* [PATCH 00/25] NXP i.MX RT595
@ 2024-09-18 19:22 Octavian Purdila
2024-09-18 19:22 ` [PATCH 01/25] fifo32: add peek function Octavian Purdila
` (24 more replies)
0 siblings, 25 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
This patch set adds support for NXP's RT500 MCU [1] and the RT595
EVK[2]. More RT500 device models will be submitted in future patch sets.
This is a minimal patch set that allows running the NXP MCU SDK hello
world example[4].
The patch set introduces a (python) tool that generates C header files
from ARM SVD files[3]. This significantly reduces the effort to write
a new device model by automatically generating: register definitions
and layout (including bit fields), register names for easier debugging
and tracing, reset register values, register write masks, etc.
The generated files are commited and not generated at compile
time. Build targets are created so that they can be easily regenerated
if needed.
Changes since RFC v3:
* rewrite the flexcomm devices to take advantage of QEMU's object
model / class inheritance and overlapped memory region and remove
the adhoc flexcomm APIs
* remove code duplication by using common fifo functions for USART
and SPI
* fix copyright in one of the headers
* remove hw/registerfields.h from generated headers as hw/register.h
is already included
* fix signed off email address for the qtests API patches
* fix description (tests/unit -> tests/qtest) for RT500 clock
controller tests
* convert devices to use the Resettable interfaces
* add support for migration
* rework the fifo32 tests on top of Mark's and Phillippe's work
Changes since RFC v2:
* convert tests from unit to qtest
* move i2c and spi testers from unit tests to hw/misc devices
* switch to using RegisterAccessInfo to generate register information
like register names, reset values, or read-only mask
* use register_write instead of adding a new reg32_write API
* remove reg32_aligned_access completly and rely on memops access
constraints and size of access for alignment checks
* add qtest APIs for checking memory access faulires
* add qtest APIs for accessing the device clock frequency
* fix bugs detected by address sanitizers
Changes since RFC v1:
* setup scripts/git.orderfile
* svd_gen_header: add support for multi line comments
* svd_gen_header: use qemu register fields instead of bitfields
* svd_gen_header: generate register write mask array
* add mcux-soc-svd as a subproject instead of commiting the rt595 SVD
file directly
* svd generated headers: don't generate them at compile time, instead
commit the generated headers and create compile targets so that it is
easy to regenerate them
* remove pysvd dependency; developers who need to (re)generate svd
headers need to have it installed on the host machine
* use DEFINE_TYPES where possible
* use g_strdup_printf where possible
* reduce iterator variables scopes
* hard code rt500 to use the cortex-m33
* use static for local arrays initializers
* remove rt500 properties as they are not yet used
* drop private/public comments
* remove unused headers
* free rt500 mem regions in rt500_unrealize() instead of
rt500_finalize
* use memops access constraints where possible instead of
reg32_aligned_access
* flexspi: use 64bit properties for mmap_size property
* rstctl: use a generic abstract type and remove the "num" property
* flexspi: don't call get_system_memory() directly and remove
mmap_base property
[1] https://www.nxp.com/docs/en/data-sheet/IMXRT500EC.pdf
[2] https://www.nxp.com/webapp/Download?colCode=MIMXRT595EVKHUG
[3] https://arm-software.github.io/CMSIS_5/SVD/html/index.html
[4] Building and running the NXP MCU SDK hello world example
Clone the following git repos:
https://github.com/nxp-mcuxpresso/cmsis.git,
https://github.com/nxp-mcuxpresso/mcux-sdk.git
https://github.com/nxp-mcuxpresso/mcux-sdk-examples.git
in the following directories: CMSIS, core, examples.
cd examples/evkmimxrt595/demo_apps/hello_world/armgcc
ARMGCC_DIR=/usr CFLAGS=-I../../../../../CMSIS/CMSIS/Core/Include \
sh build_flash_debug.sh
qemu-system-arm --machine rt595-evk -kernel flash_debug/hello_world.elf \
-global armv7m.init-nsvtor=0x08001000 -global armv7m.init-svtor=0x08001000 \
-chardev stdio,id=flexcomm0
Octavian Purdila (22):
fifo32: add peek function
tests/unit: add fifo32 tests
Add mcux-soc-svd subproject
hw/misc: add support for flexcomm
hw/misc/flexcomm.c: add common fifo functionality
hw/char: add support for flexcomm usart
hw/i2c: add support for flexcomm i2c
hw/misc: add support for RT500's clock controller
hw/ssi: add support for flexspi
hw/misc: add support for RT500's reset controller
hw/arm: add basic support for the RT500 SoC
hw/arm: add RT595-EVK board
tests/qtest: add register access macros and functions
system/qtest: add APIS to check for memory access failures
tests/qtest: add flexcomm tests
tests/qtest: add flexcomm usart tests
hw/misc: add i2c-tester
tests/qtest: add tests for flexcomm i2c
hw/ssi: allow NULL realize callbacks for peripherals
hw/misc: add spi-tester
systems/qtest: add device clock APIs
tests/qtest: add tests for RT500's clock controller
Sebastian Ene (2):
hw/ssi: add support for flexcomm spi
tests/qtest: add tests for flexcomm spi
Stefan Stanacar (1):
scripts: add script to generate C header files from SVD XML files
meson.build | 4 +
include/hw/arm/rt500.h | 44 +
include/hw/arm/svd/flexcomm.h | 112 +
include/hw/arm/svd/flexcomm_i2c.h | 1190 ++++++
include/hw/arm/svd/flexcomm_spi.h | 1036 +++++
include/hw/arm/svd/flexcomm_usart.h | 1021 +++++
include/hw/arm/svd/flexspi.h | 2656 +++++++++++++
include/hw/arm/svd/rt500.h | 63 +
include/hw/arm/svd/rt500_clkctl0.h | 2483 ++++++++++++
include/hw/arm/svd/rt500_clkctl1.h | 3396 +++++++++++++++++
include/hw/arm/svd/rt500_rstctl0.h | 858 +++++
include/hw/arm/svd/rt500_rstctl1.h | 1371 +++++++
include/hw/char/flexcomm_usart.h | 33 +
include/hw/i2c/flexcomm_i2c.h | 40 +
include/hw/misc/flexcomm.h | 57 +
include/hw/misc/flexcomm_function.h | 55 +
include/hw/misc/i2c_tester.h | 30 +
include/hw/misc/rt500_clk_freqs.h | 18 +
include/hw/misc/rt500_clkctl0.h | 35 +
include/hw/misc/rt500_clkctl1.h | 36 +
include/hw/misc/rt500_rstctl.h | 32 +
include/hw/misc/spi_tester.h | 32 +
include/hw/qdev-clock.h | 10 +
include/hw/ssi/flexcomm_spi.h | 36 +
include/hw/ssi/flexspi.h | 31 +
include/qemu/fifo32.h | 28 +
tests/qtest/libqtest-single.h | 116 +
tests/qtest/libqtest.h | 98 +
tests/qtest/reg-utils.h | 70 +
hw/arm/rt500.c | 329 ++
hw/arm/rt595-evk.c | 64 +
hw/char/flexcomm_usart.c | 288 ++
hw/core/qdev-clock.c | 2 +-
hw/i2c/flexcomm_i2c.c | 250 ++
hw/misc/flexcomm.c | 411 ++
hw/misc/i2c_tester.c | 109 +
hw/misc/rt500_clkctl0.c | 253 ++
hw/misc/rt500_clkctl1.c | 238 ++
hw/misc/rt500_rstctl.c | 258 ++
hw/misc/spi_tester.c | 67 +
hw/ssi/flexcomm_spi.c | 422 ++
hw/ssi/flexspi.c | 181 +
hw/ssi/ssi.c | 4 +-
system/qtest.c | 95 +-
tests/qtest/flexcomm-i2c-test.c | 170 +
tests/qtest/flexcomm-spi-test.c | 145 +
tests/qtest/flexcomm-test.c | 82 +
tests/qtest/flexcomm-usart-test.c | 316 ++
tests/qtest/libqtest.c | 102 +-
tests/qtest/rt500-clkctl-test.c | 195 +
tests/unit/test-fifo.c | 50 +
hw/arm/Kconfig | 12 +
hw/arm/meson.build | 4 +
hw/arm/svd/meson.build | 35 +
hw/char/meson.build | 1 +
hw/char/trace-events | 8 +
hw/i2c/meson.build | 1 +
hw/i2c/trace-events | 10 +
hw/misc/Kconfig | 21 +
hw/misc/meson.build | 7 +
hw/misc/trace-events | 18 +
hw/ssi/Kconfig | 4 +
hw/ssi/meson.build | 2 +
hw/ssi/trace-events | 9 +
meson_options.txt | 3 +
scripts/meson-buildoptions.sh | 4 +
scripts/svd-gen-header.py | 329 ++
subprojects/.gitignore | 1 +
subprojects/mcux-soc-svd.wrap | 5 +
.../packagefiles/mcux-soc-svd/meson.build | 5 +
tests/qtest/meson.build | 3 +
71 files changed, 19482 insertions(+), 22 deletions(-)
create mode 100644 include/hw/arm/rt500.h
create mode 100644 include/hw/arm/svd/flexcomm.h
create mode 100644 include/hw/arm/svd/flexcomm_i2c.h
create mode 100644 include/hw/arm/svd/flexcomm_spi.h
create mode 100644 include/hw/arm/svd/flexcomm_usart.h
create mode 100644 include/hw/arm/svd/flexspi.h
create mode 100644 include/hw/arm/svd/rt500.h
create mode 100644 include/hw/arm/svd/rt500_clkctl0.h
create mode 100644 include/hw/arm/svd/rt500_clkctl1.h
create mode 100644 include/hw/arm/svd/rt500_rstctl0.h
create mode 100644 include/hw/arm/svd/rt500_rstctl1.h
create mode 100644 include/hw/char/flexcomm_usart.h
create mode 100644 include/hw/i2c/flexcomm_i2c.h
create mode 100644 include/hw/misc/flexcomm.h
create mode 100644 include/hw/misc/flexcomm_function.h
create mode 100644 include/hw/misc/i2c_tester.h
create mode 100644 include/hw/misc/rt500_clk_freqs.h
create mode 100644 include/hw/misc/rt500_clkctl0.h
create mode 100644 include/hw/misc/rt500_clkctl1.h
create mode 100644 include/hw/misc/rt500_rstctl.h
create mode 100644 include/hw/misc/spi_tester.h
create mode 100644 include/hw/ssi/flexcomm_spi.h
create mode 100644 include/hw/ssi/flexspi.h
create mode 100644 tests/qtest/reg-utils.h
create mode 100644 hw/arm/rt500.c
create mode 100644 hw/arm/rt595-evk.c
create mode 100644 hw/char/flexcomm_usart.c
create mode 100644 hw/i2c/flexcomm_i2c.c
create mode 100644 hw/misc/flexcomm.c
create mode 100644 hw/misc/i2c_tester.c
create mode 100644 hw/misc/rt500_clkctl0.c
create mode 100644 hw/misc/rt500_clkctl1.c
create mode 100644 hw/misc/rt500_rstctl.c
create mode 100644 hw/misc/spi_tester.c
create mode 100644 hw/ssi/flexcomm_spi.c
create mode 100644 hw/ssi/flexspi.c
create mode 100644 tests/qtest/flexcomm-i2c-test.c
create mode 100644 tests/qtest/flexcomm-spi-test.c
create mode 100644 tests/qtest/flexcomm-test.c
create mode 100644 tests/qtest/flexcomm-usart-test.c
create mode 100644 tests/qtest/rt500-clkctl-test.c
create mode 100644 hw/arm/svd/meson.build
create mode 100755 scripts/svd-gen-header.py
create mode 100644 subprojects/mcux-soc-svd.wrap
create mode 100644 subprojects/packagefiles/mcux-soc-svd/meson.build
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 01/25] fifo32: add peek function
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 02/25] tests/unit: add fifo32 tests Octavian Purdila
` (23 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add fifo32_peek() that returns the first element from the queue
without popping it.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
include/qemu/fifo32.h | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/include/qemu/fifo32.h b/include/qemu/fifo32.h
index 4e9fd1b5ef..9de1807375 100644
--- a/include/qemu/fifo32.h
+++ b/include/qemu/fifo32.h
@@ -140,6 +140,34 @@ static inline uint32_t fifo32_pop(Fifo32 *fifo)
return ret;
}
+/**
+ * fifo32_peek:
+ * @fifo: fifo to peek at
+ *
+ * Returns the value from the FIFO's head without poping it. Behaviour
+ * is undefined if the FIFO is empty. Clients are responsible for
+ * checking for emptiness using fifo32_is_empty().
+ *
+ * Returns: the value from the FIFO's head
+ */
+
+static inline uint32_t fifo32_peek(Fifo32 *fifo)
+{
+ uint32_t ret = 0, num;
+ const uint8_t *buf;
+
+ buf = fifo8_peek_bufptr(&fifo->fifo, 4, &num);
+ if (num != 4) {
+ return ret;
+ }
+
+ for (int i = 0; i < sizeof(uint32_t); i++) {
+ ret |= buf[i] << (i * 8);
+ }
+
+ return ret;
+}
+
/**
* There is no fifo32_pop_buf() because the data is not stored in the buffer
* as a set of native-order words.
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 02/25] tests/unit: add fifo32 tests
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
2024-09-18 19:22 ` [PATCH 01/25] fifo32: add peek function Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 03/25] scripts: add script to generate C header files from SVD XML files Octavian Purdila
` (22 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add push/pop and peek tests for fifo32.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
tests/unit/test-fifo.c | 50 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/tests/unit/test-fifo.c b/tests/unit/test-fifo.c
index 14153c41fa..d0e05ba95c 100644
--- a/tests/unit/test-fifo.c
+++ b/tests/unit/test-fifo.c
@@ -13,6 +13,7 @@
#include "qemu/osdep.h"
#include "migration/vmstate.h"
#include "qemu/fifo8.h"
+#include "qemu/fifo32.h"
const VMStateInfo vmstate_info_uint32;
const VMStateInfo vmstate_info_buffer;
@@ -432,6 +433,53 @@ static void test_fifo8_pushpop(void)
fifo8_destroy(&fifo);
}
+static void test_fifo32_pushpop(void)
+{
+ Fifo32 fifo;
+ uint32_t e;
+
+ fifo32_create(&fifo, 2);
+ fifo32_push(&fifo, 0x11121314);
+ fifo32_push(&fifo, 0x21222324);
+ g_assert(fifo32_num_used(&fifo) == 2);
+
+ e = fifo32_pop(&fifo);
+ g_assert(e == 0x11121314);
+ g_assert(fifo32_num_used(&fifo) == 1);
+
+ e = fifo32_peek(&fifo);
+ g_assert(e == 0x21222324);
+
+ g_assert(fifo32_num_used(&fifo) == 1);
+ fifo32_destroy(&fifo);
+}
+
+static void test_fifo32_peek(void)
+{
+ Fifo32 fifo;
+ uint32_t e;
+
+ fifo32_create(&fifo, 2);
+ fifo32_push(&fifo, 0x11121314);
+ fifo32_push(&fifo, 0x21222324);
+ g_assert(fifo32_num_used(&fifo) == 2);
+
+ e = fifo32_peek(&fifo);
+ g_assert(e == 0x11121314);
+ g_assert(fifo32_num_used(&fifo) == 2);
+
+ e = fifo32_pop(&fifo);
+ g_assert(e == 0x11121314);
+ g_assert(fifo32_num_used(&fifo) == 1);
+
+ e = fifo32_peek(&fifo);
+ g_assert(e == 0x21222324);
+ g_assert(fifo32_num_used(&fifo) == 1);
+
+ fifo32_destroy(&fifo);
+}
+
+
int main(int argc, char *argv[])
{
g_test_init(&argc, &argv, NULL);
@@ -445,5 +493,7 @@ int main(int argc, char *argv[])
g_test_add_func("/fifo8/peek_bufptr_wrap", test_fifo8_peek_bufptr_wrap);
g_test_add_func("/fifo8/pop_bufptr", test_fifo8_pop_bufptr);
g_test_add_func("/fifo8/pop_bufptr_wrap", test_fifo8_pop_bufptr_wrap);
+ g_test_add_func("/fifo32/pushpop", test_fifo32_pushpop);
+ g_test_add_func("/fifo32/peek", test_fifo32_peek);
return g_test_run();
}
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 03/25] scripts: add script to generate C header files from SVD XML files
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
2024-09-18 19:22 ` [PATCH 01/25] fifo32: add peek function Octavian Purdila
2024-09-18 19:22 ` [PATCH 02/25] tests/unit: add fifo32 tests Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 04/25] Add mcux-soc-svd subproject Octavian Purdila
` (21 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
From: Stefan Stanacar <stefanst@google.com>
The CMSIS System View Description format(CMSIS-SVD) is an XML based
description of Arm Cortex-M microcontrollers provided and maintained
by sillicon vendors. It includes details such as peripherals registers
(down to bitfields), peripheral register block addresses, reset
values, etc.
This script uses this information to create header files that makes it
easier to emulate peripherals.
The script can be used to create either peripheral specific headers or
board / system specific information.
Peripheral specific headers contains information such as register
layout (using the qemu register fields infrastructure), register
names, register write masks and register reset values, the latter
using RegisterAccessInfo.
Here is an excerpt from a generated header:
#pragma once
#include "hw/registerfields.h"
/* Flexcomm */
#define FLEXCOMM_REGS_NO (1024)
/* Peripheral Select and Flexcomm module ID */
REG32(FLEXCOMM_PSELID, 4088);
/* Peripheral Select */
FIELD(FLEXCOMM_PSELID, PERSEL, 0, 3);
/* Lock the peripheral select */
FIELD(FLEXCOMM_PSELID, LOCK, 3, 1);
/* USART present indicator */
FIELD(FLEXCOMM_PSELID, USARTPRESENT, 4, 1);
...
typedef enum { /* FLEXCOMM_PSELID_LOCK */
/* Peripheral select can be changed by software. */
FLEXCOMM_PSELID_LOCK_UNLOCKED = 0,
/* Peripheral select is locked and cannot be changed until this
* Flexcomm module or the entire device is reset. */
FLEXCOMM_PSELID_LOCK_LOCKED = 1,
} FLEXCOMM_PSELID_LOCK_Enum;
...
#define FLEXCOMM_REGISTER_ACCESS_INFO_ARRAY(_name) \
struct RegisterAccessInfo _name[FLEXCOMM_REGS_NO] = { \
[0 ... FLEXCOMM_REGS_NO -1] = { \
.name = "", \
.addr = -1, \
}, \
[R_FLEXCOMM_PSELID] = { \
.name = "PSELID", \
.addr = 0xFF8, \
.ro = 0xFFFFFFF0, \
.reset = 0x101000, \
}, \
[R_FLEXCOMM_PID] = { \
.name = "PID", \
.addr = 0xFFC, \
.ro = 0xFFFFFFFF, \
.reset = 0x0, \
}, \
}
Board specific headers contains information about peripheral base
register addresses.
Signed-off-by: Stefan Stanacar <stefanst@google.com>
[tavip: pylint fixes, generate layout with qemu register fields
instead of bitfields, generate register names, romask and reset values]
Signed-off-by: Octavian Purdila <tavip@google.com>
---
meson.build | 4 +
| 329 ++++++++++++++++++++++++++++++++++++++
2 files changed, 333 insertions(+)
create mode 100755 scripts/svd-gen-header.py
diff --git a/meson.build b/meson.build
index 2d4bf71b24..57d0119733 100644
--- a/meson.build
+++ b/meson.build
@@ -3338,6 +3338,10 @@ tracetool_depends = files(
'scripts/tracetool/__init__.py',
)
+svd_gen_header = [
+ python, files('scripts/svd-gen-header.py')
+]
+
qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
meson.current_source_dir(),
get_option('pkgversion'), meson.project_version()]
--git a/scripts/svd-gen-header.py b/scripts/svd-gen-header.py
new file mode 100755
index 0000000000..2ddcc65b5a
--- /dev/null
+++ b/scripts/svd-gen-header.py
@@ -0,0 +1,329 @@
+#!/usr/bin/env python3
+
+# Copyright 2024 Google LLC
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+#
+# Use this script to generate a C header file from an SVD xml
+#
+# Two mode of operations are supported: peripheral and system.
+#
+# When running in peripheral mode a header for a specific peripheral
+# is going to be generated. It will define a type and structure with
+# all of the available registers at the bitfield level. An array that
+# contains the reigster names indexed by address is also going to be
+# generated as well as a function to initialize registers to their
+# reset values.
+#
+# Invocation example:
+#
+# svd_gen_header -i MIMXRT595S_cm33.xml -o flexcomm.h -p FLEXCOMM0 -t FLEXCOMM
+#
+# When running in system mode a header for a specific system /
+# platform will be generated. It will define register base addresses
+# and interrupt numbers for selected peripherals.
+#
+# Invocation example:
+#
+# svd_gen_header -i MIMXRT595S_cm33.xml -o rt500.h -s RT500 -p FLEXCOMM0 \
+# -p CLKCTL0 -p CLKCTL1
+#
+
+import argparse
+import re
+import os
+import sys
+import xml.etree.ElementTree
+import pysvd
+
+data_type_by_bits = {
+ 8: "uint8_t",
+ 16: "uint16_t",
+ 32: "uint32_t",
+}
+
+
+def get_register_array_name_and_size(reg):
+ """Return register name and register array size.
+
+ The SVD can define register arrays and pysvd encodes the whole set
+ as as regular register with their name prepended by [<array size>].
+
+ Returns a tuple with the register name and the size of the array or
+ zero if this is not a register set.
+
+ """
+
+ split = re.split(r"[\[\]]", reg.name)
+ return (split[0], int(split[1]) if len(split) > 1 else 0)
+
+
+def generate_comment(indent, text):
+ """Generate a comment block with for the given text with the given
+ indentation level.
+
+ If possible, use a single line /* */ comment block, otherwise use
+ a multiline comment block.
+
+ Newlines are preseved but tabs are not.
+
+ """
+
+ # preserve new lines
+ text = text.replace("\n", " \n ")
+ text = text.replace(" ", " ")
+
+ if len(text) + len("/* */") + len(" " * indent) <= 80 and "\n" not in text:
+ return f"{' '* indent}/* {text} */\n"
+
+ out = " " * indent + "/*\n"
+ line = " " * indent + " *"
+ for word in re.split(r"[ ]", text):
+ if len(line) + len(word) >= 79 or word == "\n":
+ out += line + "\n"
+ line = " " * indent + " *"
+ if word != "\n":
+ line += " " + word
+ else:
+ line += " " + word
+
+ out += line + "\n"
+
+ out += " " * indent + " */\n"
+ return out
+
+
+def generate_registers(name, periph):
+ """Generate register offsets and fields
+
+ Use registerfield macros to define register offsets and fields for
+ a given peripheral.
+
+ """
+
+ regs = sorted(periph.registers, key=lambda reg: reg.addressOffset)
+ out = generate_comment(0, periph.description)
+ out += f"#define {name}_REGS_NO ({regs[-1].addressOffset // 4 + 1})\n\n"
+ for reg in regs:
+ out += generate_comment(0, reg.description)
+ reg_name, reg_array_size = get_register_array_name_and_size(reg)
+ if reg_array_size > 1:
+ for idx in range(0, reg_array_size):
+ addr = reg.addressOffset + idx * reg.size // 8
+ out += f"REG32({name}_{reg_name}{idx}, {addr});\n"
+ else:
+ addr = reg.addressOffset
+ out += f"REG32({name}_{reg_name}, {addr});\n"
+ for field in reg.fields:
+ out += generate_comment(0, field.description)
+ if reg_array_size > 1:
+ out += f"SHARED_FIELD({name}_{reg_name}_{field.name}, "
+ out += f"{field.bitOffset}, {field.bitWidth});\n"
+ else:
+ out += f"FIELD({name}_{reg_name}, {field.name}, "
+ out += f"{field.bitOffset}, {field.bitWidth});\n"
+ out += "\n"
+
+ return out
+
+
+def generate_enum_values(name, periph):
+ """Generate enum values"""
+
+ out = "\n"
+ for reg in periph.registers:
+ reg_name, _ = get_register_array_name_and_size(reg)
+ for field in reg.fields:
+ if hasattr(field, "enumeratedValues"):
+ out += "typedef enum {\n"
+ for enum in field.enumeratedValues.enumeratedValues:
+ enum_name = f"{name}_{reg_name}_{field.name}_{enum.name}"
+ out += generate_comment(4, enum.description)
+ out += f" {enum_name} = {enum.value},\n"
+ out += f"}} {name}_{reg_name}_{field.name}_Enum;\n"
+ out += "\n"
+
+ return out
+
+
+def create_wmask(reg):
+ """Generate write mask for a register.
+
+ Generate a mask with all bits that are writable set to 1
+ """
+
+ wmask = 0
+ fields = sorted(reg.fields, key=lambda field: field.bitOffset)
+ if len(fields) > 0:
+ for field in fields:
+ if field.access != pysvd.type.access.read_only:
+ wmask |= ((1 << field.bitWidth) - 1) << field.bitOffset
+ else:
+ if reg.access != pysvd.type.access.read_only:
+ wmask = 0xFFFFFFFF
+ return wmask
+
+
+def create_romask(reg):
+ """Generate write mask for a register.
+
+ Generate a mask with all bits that are readonly set to 1
+ """
+
+ return ~create_wmask(reg) & 0xFFFFFFFF
+
+
+def generate_register_access_info(name, periph):
+ """Generate RegisterAccessInfo array macro"""
+
+ out = f"\n#define {name}_REGISTER_ACCESS_INFO_ARRAY(_name) \\\n"
+ out += f" struct RegisterAccessInfo _name[{name}_REGS_NO] = {{ \\\n"
+ out += f" [0 ... {name}_REGS_NO - 1] = {{ \\\n"
+ out += ' .name = "", \\\n'
+ out += " .addr = -1, \\\n"
+ out += " }, \\\n"
+ for reg in periph.registers:
+ reg_name, reg_array_size = get_register_array_name_and_size(reg)
+ if reg_array_size > 1:
+ for idx in range(0, reg_array_size):
+ out += f" [R_{name}_{reg_name}{idx}] = {{ \\\n"
+ addr = reg.addressOffset + idx * reg.size // 8
+ out += f' .name = "{reg_name}{idx}", \\\n'
+ out += f" .addr = 0x{addr:X}, \\\n"
+ out += f" .ro = 0x{create_romask(reg):X}, \\\n"
+ out += f" .reset = 0x{reg.resetValue:X}, \\\n"
+ out += " }, \\\n"
+ else:
+ out += f" [R_{name}_{reg_name}] = {{ \\\n"
+ out += f' .name = "{reg_name}", \\\n'
+ out += f" .addr = 0x{reg.addressOffset:X}, \\\n"
+ out += f" .ro = 0x{create_romask(reg):X}, \\\n"
+ out += f" .reset = 0x{reg.resetValue:X}, \\\n"
+ out += " }, \\\n"
+ out += " }\n"
+
+ return out
+
+
+def generate_peripheral_header(periph, name):
+ """Generate peripheral header
+
+ The following information is generated:
+
+ * typedef with all of the available registers and register fields,
+ position and mask defines for register fields.
+
+ * enum values that encode register fields options.
+
+ * a macro that defines the register names indexed by the relative
+ address of the register.
+
+ * a function that sets the registers to their reset values
+
+ """
+
+ out = generate_registers(name, periph)
+
+ out += generate_enum_values(name, periph)
+
+ out += generate_register_access_info(name, periph)
+
+ return out
+
+
+def get_same_class_peripherals(svd, periph):
+ """Get a list of peripherals that are instances of the same class."""
+
+ return [periph] + [
+ p
+ for p in svd.peripherals
+ if p.derivedFrom and p.derivedFrom.name == periph.name
+ ]
+
+
+def generate_system_header(system, svd, periph):
+ """Generate base and irq defines for given list of peripherals"""
+
+ out = ""
+
+ for p in get_same_class_peripherals(svd, periph):
+ out += f"#define {system}_{p.name}_BASE 0x{p.baseAddress:X}UL\n"
+ out += "\n"
+
+ for p in get_same_class_peripherals(svd, periph):
+ for irq in p.interrupts:
+ out += f"#define {system}_{irq.name}_IRQn 0x{irq.value}UL\n"
+ out += "\n"
+
+ return out
+
+
+def main():
+ """Script to generate C header file from an SVD file"""
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "-i", "--input", type=str, help="Input SVD file", required=True
+ )
+ parser.add_argument(
+ "-o", "--output", type=str, help="Output .h file", required=True
+ )
+ parser.add_argument(
+ "-p",
+ "--peripheral",
+ action="append",
+ help="peripheral name from the SVD file",
+ required=True,
+ )
+ parser.add_argument(
+ "-t",
+ "--type-name",
+ type=str,
+ help="name to be used for peripheral definitions",
+ required=False,
+ )
+ parser.add_argument(
+ "-s",
+ "--system",
+ type=str,
+ help="name to be used for the system definitions",
+ required=False,
+ )
+
+ args = parser.parse_args()
+
+ node = xml.etree.ElementTree.parse(args.input).getroot()
+ svd = pysvd.element.Device(node)
+
+ # Write license header
+ header = svd.licenseText.strip()
+ header += f"\n\nAutomatically generated by {os.path.basename(__file__)} "
+ header += f"from {os.path.basename(args.input)}"
+ out = generate_comment(0, header)
+
+ # Write some generic defines
+ out += "#pragma once\n\n"
+
+ for name in args.peripheral:
+ periph = svd.find(name)
+ if periph:
+ if args.system:
+ out += generate_system_header(args.system, svd, periph)
+ else:
+ out += '#include "hw/register.h"\n\n'
+ out += generate_peripheral_header(
+ periph, args.type_name if args.type_name else periph.name
+ )
+ else:
+ print(f"No such peripheral: {name}")
+ return 1
+
+ with open(args.output, "w", encoding="ascii") as output:
+ output.write(out)
+
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 04/25] Add mcux-soc-svd subproject
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (2 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 03/25] scripts: add script to generate C header files from SVD XML files Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 05/25] hw/misc: add support for flexcomm Octavian Purdila
` (20 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add mcux-soc-svd subproject that contains SVD files that are going to
be used to generate C header with register layout definitions and
other helpers to create device models.
Guard the subproject by a configuration option since it is rarely
going to be used - whenever new headers will be generated. It is
unlikely that already generated headers will be updated, with the
exception of minor hardware revisions.
Also export the rt595 SVD file which is going to be used by subsequent
patches.
TBD: switch to a qemu gitlab fork before merge
Signed-off-by: Octavian Purdila <tavip@google.com>
---
hw/arm/svd/meson.build | 4 ++++
meson_options.txt | 3 +++
scripts/meson-buildoptions.sh | 4 ++++
subprojects/.gitignore | 1 +
subprojects/mcux-soc-svd.wrap | 5 +++++
subprojects/packagefiles/mcux-soc-svd/meson.build | 5 +++++
6 files changed, 22 insertions(+)
create mode 100644 hw/arm/svd/meson.build
create mode 100644 subprojects/mcux-soc-svd.wrap
create mode 100644 subprojects/packagefiles/mcux-soc-svd/meson.build
diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build
new file mode 100644
index 0000000000..7d83d2ccbc
--- /dev/null
+++ b/hw/arm/svd/meson.build
@@ -0,0 +1,4 @@
+if get_option('mcux-soc-svd')
+ mcux_soc_svd = subproject('mcux-soc-svd')
+ rt595 = mcux_soc_svd.get_variable('rt595')
+endif
diff --git a/meson_options.txt b/meson_options.txt
index 783b56bcb9..fb64db2d2a 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -375,3 +375,6 @@ option('hexagon_idef_parser', type : 'boolean', value : true,
option('x86_version', type : 'combo', choices : ['0', '1', '2', '3', '4'], value: '1',
description: 'tweak required x86_64 architecture version beyond compiler default')
+
+option('mcux-soc-svd', type : 'boolean', value : false,
+ description: 'enable targets to generate C headers from mcux-soc-svd')
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index 107a8f69ce..0864952d80 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -41,6 +41,8 @@ meson_options_help() {
printf "%s\n" ' --enable-lto Use link time optimization'
printf "%s\n" ' --enable-malloc=CHOICE choose memory allocator to use [system] (choices:'
printf "%s\n" ' jemalloc/system/tcmalloc)'
+ printf "%s\n" ' --enable-mcux-soc-svd enable targets to generate C headers from mcux-'
+ printf "%s\n" ' soc-svd'
printf "%s\n" ' --enable-module-upgrades try to load modules from alternate paths for'
printf "%s\n" ' upgrades'
printf "%s\n" ' --enable-rng-none dummy RNG, avoid using /dev/(u)random and'
@@ -395,6 +397,8 @@ _meson_option_parse() {
--enable-malloc-trim) printf "%s" -Dmalloc_trim=enabled ;;
--disable-malloc-trim) printf "%s" -Dmalloc_trim=disabled ;;
--mandir=*) quote_sh "-Dmandir=$2" ;;
+ --enable-mcux-soc-svd) printf "%s" -Dmcux-soc-svd=true ;;
+ --disable-mcux-soc-svd) printf "%s" -Dmcux-soc-svd=false ;;
--enable-membarrier) printf "%s" -Dmembarrier=enabled ;;
--disable-membarrier) printf "%s" -Dmembarrier=disabled ;;
--enable-module-upgrades) printf "%s" -Dmodule_upgrades=true ;;
diff --git a/subprojects/.gitignore b/subprojects/.gitignore
index adca0266be..bca8693ef4 100644
--- a/subprojects/.gitignore
+++ b/subprojects/.gitignore
@@ -6,3 +6,4 @@
/keycodemapdb
/libvfio-user
/slirp
+/mcux-soc-svd
diff --git a/subprojects/mcux-soc-svd.wrap b/subprojects/mcux-soc-svd.wrap
new file mode 100644
index 0000000000..80d18e8561
--- /dev/null
+++ b/subprojects/mcux-soc-svd.wrap
@@ -0,0 +1,5 @@
+[wrap-git]
+url = https://github.com/nxp-mcuxpresso/mcux-soc-svd/
+revision = 7f6f9ef7420144fe14cd9bc4d8e0e3523232da04
+patch_directory = mcux-soc-svd
+depth = 1
diff --git a/subprojects/packagefiles/mcux-soc-svd/meson.build b/subprojects/packagefiles/mcux-soc-svd/meson.build
new file mode 100644
index 0000000000..37c537d040
--- /dev/null
+++ b/subprojects/packagefiles/mcux-soc-svd/meson.build
@@ -0,0 +1,5 @@
+project('mcux-soc-svd')
+
+fs = import('fs')
+
+rt595 = fs.copyfile('MIMXRT595S/MIMXRT595S_cm33.xml')
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 05/25] hw/misc: add support for flexcomm
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (3 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 04/25] Add mcux-soc-svd subproject Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 06/25] hw/misc/flexcomm.c: add common fifo functionality Octavian Purdila
` (19 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add support for NXP's FLEXCOMM device model.
FLEXCOMM is a generic serial communication module which support
multiple functions: UART, SPI and I2C. These are configurable at
runtime.
An abstract FlexcomFunction class is created that will be extended for
specific functions. Each function has a dedicated overlapped
MemoryRegion that it is going to be activated when that particular
function is selected.
A generic MemoryRegion is used to map generic registers (PSELID, PID)
that is always active but has a lower priority. The function memory
region is trimed to not include the generic registers.
The FlexcommFunction object also gets access to the (non-concurrently)
shared register backstore.
The patch includes an automatically generated header which contains
the register layout and helpers.
The header can be regenerated with the svd-flexcomm target when the
build is configured with --enable-mcux-soc-svd.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
include/hw/arm/svd/flexcomm.h | 112 ++++++++++
include/hw/misc/flexcomm.h | 49 +++++
include/hw/misc/flexcomm_function.h | 47 ++++
hw/misc/flexcomm.c | 319 ++++++++++++++++++++++++++++
hw/arm/meson.build | 2 +
hw/arm/svd/meson.build | 3 +
hw/misc/Kconfig | 3 +
hw/misc/meson.build | 2 +
hw/misc/trace-events | 5 +
9 files changed, 542 insertions(+)
create mode 100644 include/hw/arm/svd/flexcomm.h
create mode 100644 include/hw/misc/flexcomm.h
create mode 100644 include/hw/misc/flexcomm_function.h
create mode 100644 hw/misc/flexcomm.c
diff --git a/include/hw/arm/svd/flexcomm.h b/include/hw/arm/svd/flexcomm.h
new file mode 100644
index 0000000000..4639722bc7
--- /dev/null
+++ b/include/hw/arm/svd/flexcomm.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
+ */
+#pragma once
+
+#include "hw/register.h"
+
+/* Flexcomm */
+#define FLEXCOMM_REGS_NO (1024)
+
+/* Peripheral Select and Flexcomm module ID */
+REG32(FLEXCOMM_PSELID, 4088);
+/* Peripheral Select */
+FIELD(FLEXCOMM_PSELID, PERSEL, 0, 3);
+/* Lock the peripheral select */
+FIELD(FLEXCOMM_PSELID, LOCK, 3, 1);
+/* USART present indicator */
+FIELD(FLEXCOMM_PSELID, USARTPRESENT, 4, 1);
+/* SPI present indicator */
+FIELD(FLEXCOMM_PSELID, SPIPRESENT, 5, 1);
+/* I2C present indicator */
+FIELD(FLEXCOMM_PSELID, I2CPRESENT, 6, 1);
+/* I2S Present */
+FIELD(FLEXCOMM_PSELID, I2SPRESENT, 7, 1);
+/* Flexcomm ID */
+FIELD(FLEXCOMM_PSELID, ID, 12, 20);
+
+/* Peripheral Identification */
+REG32(FLEXCOMM_PID, 4092);
+/* Minor revision of module implementation */
+FIELD(FLEXCOMM_PID, Minor_Rev, 8, 4);
+/* Major revision of module implementation */
+FIELD(FLEXCOMM_PID, Major_Rev, 12, 4);
+/* Module identifier for the selected function */
+FIELD(FLEXCOMM_PID, ID, 16, 16);
+
+
+typedef enum {
+ /* No peripheral selected. */
+ FLEXCOMM_PSELID_PERSEL_NO_PERIPH_SELECTED = 0,
+ /* USART function selected */
+ FLEXCOMM_PSELID_PERSEL_USART = 1,
+ /* SPI function selected */
+ FLEXCOMM_PSELID_PERSEL_SPI = 2,
+ /* I2C */
+ FLEXCOMM_PSELID_PERSEL_I2C = 3,
+ /* I2S Transmit */
+ FLEXCOMM_PSELID_PERSEL_I2S_TRANSMIT = 4,
+ /* I2S Receive */
+ FLEXCOMM_PSELID_PERSEL_I2S_RECEIVE = 5,
+} FLEXCOMM_PSELID_PERSEL_Enum;
+
+typedef enum {
+ /* Peripheral select can be changed by software. */
+ FLEXCOMM_PSELID_LOCK_UNLOCKED = 0,
+ /*
+ * Peripheral select is locked and cannot be changed until this Flexcomm
+ * module or the entire device is reset.
+ */
+ FLEXCOMM_PSELID_LOCK_LOCKED = 1,
+} FLEXCOMM_PSELID_LOCK_Enum;
+
+typedef enum {
+ /* This Flexcomm module does not include the USART function. */
+ FLEXCOMM_PSELID_USARTPRESENT_NOT_PRESENT = 0,
+ /* This Flexcomm module includes the USART function. */
+ FLEXCOMM_PSELID_USARTPRESENT_PRESENT = 1,
+} FLEXCOMM_PSELID_USARTPRESENT_Enum;
+
+typedef enum {
+ /* This Flexcomm module does not include the SPI function. */
+ FLEXCOMM_PSELID_SPIPRESENT_NOT_PRESENT = 0,
+ /* This Flexcomm module includes the SPI function. */
+ FLEXCOMM_PSELID_SPIPRESENT_PRESENT = 1,
+} FLEXCOMM_PSELID_SPIPRESENT_Enum;
+
+typedef enum {
+ /* I2C Not Present */
+ FLEXCOMM_PSELID_I2CPRESENT_NOT_PRESENT = 0,
+ /* I2C Present */
+ FLEXCOMM_PSELID_I2CPRESENT_PRESENT = 1,
+} FLEXCOMM_PSELID_I2CPRESENT_Enum;
+
+typedef enum {
+ /* I2S Not Present */
+ FLEXCOMM_PSELID_I2SPRESENT_NOT_PRESENT = 0,
+ /* I2S Present */
+ FLEXCOMM_PSELID_I2SPRESENT_PRESENT = 1,
+} FLEXCOMM_PSELID_I2SPRESENT_Enum;
+
+
+#define FLEXCOMM_REGISTER_ACCESS_INFO_ARRAY(_name) \
+ struct RegisterAccessInfo _name[FLEXCOMM_REGS_NO] = { \
+ [0 ... FLEXCOMM_REGS_NO - 1] = { \
+ .name = "", \
+ .addr = -1, \
+ }, \
+ [R_FLEXCOMM_PSELID] = { \
+ .name = "PSELID", \
+ .addr = 0xFF8, \
+ .ro = 0xFFFFFFF0, \
+ .reset = 0x101000, \
+ }, \
+ [R_FLEXCOMM_PID] = { \
+ .name = "PID", \
+ .addr = 0xFFC, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ }
diff --git a/include/hw/misc/flexcomm.h b/include/hw/misc/flexcomm.h
new file mode 100644
index 0000000000..ea0fe77f26
--- /dev/null
+++ b/include/hw/misc/flexcomm.h
@@ -0,0 +1,49 @@
+/*
+ * QEMU model for NXP's FLEXCOMM
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_FLEXCOMM_H
+#define HW_FLEXCOMM_H
+
+#include "hw/sysbus.h"
+#include "hw/arm/svd/flexcomm.h"
+#include "qemu/fifo32.h"
+
+#define FLEXCOMM_FUNC_USART 0
+#define FLEXCOMM_FUNC_SPI 1
+#define FLEXCOMM_FUNC_I2C 2
+#define FLEXCOMM_FUNC_I2S 3
+#define FLEXCOMM_FUNCTIONS 4
+
+#define FLEXCOMM_FULL 0xF
+#define FLEXCOMM_HSSPI (1 << FLEXCOMM_FUNC_SPI)
+#define FLEXCOMM_PMICI2C (1 << FLEXCOMM_FUNC_I2C)
+
+#define FLEXCOMM_PERSEL_USART 1
+#define FLEXCOMM_PERSEL_SPI 2
+#define FLEXCOMM_PERSEL_I2C 3
+#define FLEXCOMM_PERSEL_I2S_TX 4
+#define FLEXCOMM_PERSEL_I2S_RX 5
+
+#define TYPE_FLEXCOMM "flexcomm"
+OBJECT_DECLARE_SIMPLE_TYPE(FlexcommState, FLEXCOMM);
+
+struct FlexcommState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion container;
+ MemoryRegion mmio;
+ uint32_t regs[FLEXCOMM_REGS_NO];
+ uint32_t functions;
+ qemu_irq irq;
+ bool irq_state;
+};
+
+#endif /* HW_FLEXCOMM_H */
diff --git a/include/hw/misc/flexcomm_function.h b/include/hw/misc/flexcomm_function.h
new file mode 100644
index 0000000000..e498976927
--- /dev/null
+++ b/include/hw/misc/flexcomm_function.h
@@ -0,0 +1,47 @@
+/*
+ * QEMU model for NXP's FLEXCOMM
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_FLEXCOMM_FUNCTION_H
+#define HW_FLEXCOMM_FUNCTION_H
+
+#include "qemu/fifo32.h"
+#include "hw/sysbus.h"
+
+#define TYPE_FLEXCOMM_FUNCTION "flexcomm-function"
+OBJECT_DECLARE_TYPE(FlexcommFunction, FlexcommFunctionClass, FLEXCOMM_FUNCTION);
+
+struct FlexcommFunction {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+ uint32_t *regs;
+};
+
+typedef void (*FlexcommFunctionSelect)(FlexcommFunction *f, bool selected);
+
+struct FlexcommFunctionClass {
+ SysBusDeviceClass parent_class;
+
+ const MemoryRegionOps *mmio_ops;
+ const char *name;
+ FlexcommFunctionSelect select;
+};
+
+static inline void flexcomm_select(FlexcommFunction *obj, bool selected)
+{
+ FlexcommFunctionClass *klass = FLEXCOMM_FUNCTION_GET_CLASS(obj);
+
+ klass->select(obj, selected);
+}
+
+void flexcomm_set_irq(FlexcommFunction *f, bool irq);
+
+#endif /* HW_FLEXCOMM_FUNCTION_H */
diff --git a/hw/misc/flexcomm.c b/hw/misc/flexcomm.c
new file mode 100644
index 0000000000..2337fb814c
--- /dev/null
+++ b/hw/misc/flexcomm.c
@@ -0,0 +1,319 @@
+/*
+ * QEMU model for NXP's FLEXCOMM
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/mmap-alloc.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
+#include "migration/vmstate.h"
+#include "exec/address-spaces.h"
+#include "qapi/error.h"
+#include "trace.h"
+#include "migration/vmstate.h"
+#include "hw/misc/flexcomm.h"
+
+#define REG(s, reg) (s->regs[R_FLEXCOMM_##reg])
+#define RF_WR(s, reg, field, val) \
+ ARRAY_FIELD_DP32(s->regs, FLEXCOMM_##reg, field, val)
+#define RF_RD(s, reg, field) \
+ ARRAY_FIELD_EX32(s->regs, FLEXCOMM_##reg, field)
+
+#define modname "FLEXCOMM"
+
+#define FLEXCOMM_FUNC_MMIO_SIZE \
+ ((FLEXCOMM_REGS_NO - 2) * sizeof(uint32_t))
+
+static const FLEXCOMM_REGISTER_ACCESS_INFO_ARRAY(reg_info);
+
+static inline bool has_function(FlexcommState *s, int function)
+{
+ return s->functions & (1 << function);
+}
+
+static inline int persel_to_function(FlexcommState *s)
+{
+ switch (RF_RD(s, PSELID, PERSEL)) {
+ case FLEXCOMM_PERSEL_USART:
+ return FLEXCOMM_FUNC_USART;
+ case FLEXCOMM_PERSEL_SPI:
+ return FLEXCOMM_FUNC_SPI;
+ case FLEXCOMM_PERSEL_I2C:
+ return FLEXCOMM_FUNC_I2C;
+ case FLEXCOMM_PERSEL_I2S_TX:
+ case FLEXCOMM_PERSEL_I2S_RX:
+ return FLEXCOMM_FUNC_I2S;
+ default:
+ return -1;
+ }
+}
+
+static void flexcomm_func_select(FlexcommState *s, bool selected)
+{
+ FlexcommFunction *obj[] = {
+ FLEXCOMM_FUNCTION(&s->usart),
+ FLEXCOMM_FUNCTION(&s->spi),
+ FLEXCOMM_FUNCTION(&s->i2c),
+ };
+ int f = persel_to_function(s);
+
+ if (f >= 0 && f < ARRAY_SIZE(obj)) {
+ flexcomm_select(obj[f], selected);
+ }
+}
+
+static void flexcomm_reset_enter(Object *o, ResetType type)
+{
+ FlexcommState *s = FLEXCOMM(o);
+
+ trace_flexcomm_reset();
+
+ flexcomm_func_select(s, false);
+
+ for (int i = 0; i < FLEXCOMM_REGS_NO; i++) {
+ hwaddr addr = reg_info[i].addr;
+
+ if (addr != -1) {
+ struct RegisterInfo ri = {
+ .data = &s->regs[addr / 4],
+ .data_size = 4,
+ .access = ®_info[i],
+ };
+
+ register_reset(&ri);
+ }
+ }
+
+ RF_WR(s, PSELID, USARTPRESENT, has_function(s, FLEXCOMM_FUNC_USART));
+ RF_WR(s, PSELID, SPIPRESENT, has_function(s, FLEXCOMM_FUNC_SPI));
+ RF_WR(s, PSELID, I2CPRESENT, has_function(s, FLEXCOMM_FUNC_I2C));
+ RF_WR(s, PSELID, I2SPRESENT, has_function(s, FLEXCOMM_FUNC_I2S));
+
+ s->irq_state = false;
+}
+
+static void flexcomm_reset_exit(Object *o, ResetType type)
+{
+ FlexcommState *s = FLEXCOMM(o);
+
+ qemu_set_irq(s->irq, s->irq_state);
+}
+
+
+static MemTxResult flexcomm_reg_read(void *opaque, hwaddr addr,
+ uint64_t *data, unsigned size,
+ MemTxAttrs attrs)
+{
+ FlexcommState *s = opaque;
+ MemTxResult ret = MEMTX_OK;
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+
+ switch (addr) {
+ case A_FLEXCOMM_PSELID:
+ case A_FLEXCOMM_PID:
+ {
+ *data = s->regs[addr / 4];
+ break;
+ }
+ default:
+ return MEMTX_ERROR;
+ }
+
+ trace_flexcomm_reg_read(DEVICE(s)->id, rai->name, addr, *data);
+ return ret;
+}
+
+static int flexcomm_check_function(FlexcommState *s)
+{
+ int f = persel_to_function(s);
+
+ if (f < 0 || !has_function(s, f)) {
+ return -1;
+ }
+
+ return f;
+}
+
+static MemTxResult flexcomm_reg_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size,
+ MemTxAttrs attrs)
+{
+ FlexcommState *s = opaque;
+ MemTxResult ret = MEMTX_OK;
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+ struct RegisterInfo ri = {
+ .data = &s->regs[addr / 4],
+ .data_size = 4,
+ .access = rai,
+ };
+
+ trace_flexcomm_reg_write(DEVICE(s)->id, rai->name, addr, value);
+
+ switch (addr) {
+ case A_FLEXCOMM_PID:
+ /* RO register, nothing do to */
+ break;
+ case A_FLEXCOMM_PSELID:
+ {
+ if (RF_RD(s, PSELID, LOCK)) {
+ break;
+ }
+
+ flexcomm_func_select(s, false);
+
+ register_write(&ri, value, ~0, modname, false);
+
+ if (flexcomm_check_function(s) < 0) {
+ RF_WR(s, PSELID, PERSEL, 0);
+ break;
+ }
+
+ flexcomm_func_select(s, true);
+ break;
+ }
+ default:
+ return MEMTX_ERROR;
+ }
+
+ return ret;
+}
+
+
+static const MemoryRegionOps flexcomm_ops = {
+ .read_with_attrs = flexcomm_reg_read,
+ .write_with_attrs = flexcomm_reg_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ .unaligned = false,
+ },
+};
+
+static Property flexcomm_properties[] = {
+ DEFINE_PROP_UINT32("functions", FlexcommState, functions,
+ FLEXCOMM_FULL),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void flexcomm_init(Object *obj)
+{
+ FlexcommState *s = FLEXCOMM(obj);
+ DeviceState *dev = DEVICE(obj);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+ memory_region_init(&s->container, obj, "container", sizeof(s->regs));
+ memory_region_init_io(&s->mmio, obj, &flexcomm_ops, s,
+ TYPE_FLEXCOMM, sizeof(s->regs));
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container);
+ sysbus_init_irq(sbd, &s->irq);
+}
+
+static void flexcomm_func_realize_and_unref(FlexcommFunction *f, Error **errp)
+{
+ FlexcommState *s = FLEXCOMM(OBJECT(f)->parent);
+ FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_GET_CLASS(f);
+
+ f->regs = s->regs;
+ memory_region_add_subregion_overlap(&s->container, 0, &f->mmio, 0);
+ DEVICE(f)->id = g_strdup_printf("%s-%s", DEVICE(s)->id, fc->name);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(f), errp);
+ memory_region_set_enabled(&f->mmio, false);
+}
+
+static void flexcomm_realize(DeviceState *dev, Error **errp)
+{
+ FlexcommState *s = FLEXCOMM(dev);
+
+ memory_region_add_subregion_overlap(&s->container, 0, &s->mmio, -1);
+}
+
+static const VMStateDescription vmstate_flexcomm = {
+ .name = "flexcomm",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(regs, FlexcommState, FLEXCOMM_REGS_NO),
+ VMSTATE_BOOL(irq_state, FlexcommState),
+ VMSTATE_FIFO32(rx_fifo, FlexcommState),
+ VMSTATE_FIFO32(tx_fifo, FlexcommState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void flexcomm_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+
+ rc->phases.enter = flexcomm_reset_enter;
+ rc->phases.exit = flexcomm_reset_exit;
+ device_class_set_props(dc, flexcomm_properties);
+ dc->realize = flexcomm_realize;
+ dc->vmsd = &vmstate_flexcomm;
+}
+
+void flexcomm_set_irq(FlexcommFunction *f, bool irq)
+{
+ FlexcommState *s = FLEXCOMM(OBJECT(f)->parent);
+
+ if (s->irq_state != irq) {
+ trace_flexcomm_irq(DEVICE(s)->id, irq);
+ qemu_set_irq(s->irq, irq);
+ s->irq_state = irq;
+ }
+}
+
+static void flexcomm_function_select(FlexcommFunction *f, bool selected)
+{
+ FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_GET_CLASS(f);
+
+ memory_region_set_enabled(&f->mmio, selected);
+}
+
+static void flexcomm_function_init(Object *obj)
+{
+ FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_GET_CLASS(obj);
+ FlexcommFunction *f = FLEXCOMM_FUNCTION(obj);
+
+ memory_region_init_io(&f->mmio, obj, fc->mmio_ops, obj, fc->name,
+ FLEXCOMM_FUNC_MMIO_SIZE);
+}
+
+static void flexcomm_function_class_init(ObjectClass *klass, void *data)
+{
+ FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_CLASS(klass);
+
+ fc->select = flexcomm_function_select;
+}
+
+static const TypeInfo flexcomm_types[] = {
+ {
+ .name = TYPE_FLEXCOMM,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(FlexcommState),
+ .instance_init = flexcomm_init,
+ .class_init = flexcomm_class_init,
+ },
+ {
+ .name = TYPE_FLEXCOMM_FUNCTION,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(FlexcommFunction),
+ .abstract = true,
+ .class_size = sizeof(FlexcommFunctionClass),
+ .instance_init = flexcomm_function_init,
+ .class_init = flexcomm_function_class_init,
+ },
+};
+
+DEFINE_TYPES(flexcomm_types);
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 4059d0be2e..fdfd083f75 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -82,3 +82,5 @@ system_ss.add(when: 'CONFIG_VEXPRESS', if_true: files('vexpress.c'))
system_ss.add(when: 'CONFIG_Z2', if_true: files('z2.c'))
hw_arch += {'arm': arm_ss}
+
+subdir('svd')
diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build
index 7d83d2ccbc..4b0bbbbbdc 100644
--- a/hw/arm/svd/meson.build
+++ b/hw/arm/svd/meson.build
@@ -1,4 +1,7 @@
if get_option('mcux-soc-svd')
mcux_soc_svd = subproject('mcux-soc-svd')
rt595 = mcux_soc_svd.get_variable('rt595')
+ run_target('svd-flexcomm', command: svd_gen_header +
+ [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm.h',
+ '-p', 'FLEXCOMM0', '-t', 'FLEXCOMM'])
endif
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 1e08785b83..14167ae9e8 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -213,4 +213,7 @@ config IOSB
config XLNX_VERSAL_TRNG
bool
+config FLEXCOMM
+ bool
+
source macio/Kconfig
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 2ca8717be2..749f688e84 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -157,3 +157,5 @@ system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c'))
# HPPA devices
system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c'))
+
+system_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm.c'))
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 1be0717c0c..419879fd65 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -362,3 +362,8 @@ aspeed_sli_read(uint64_t offset, unsigned int size, uint32_t data) "To 0x%" PRIx
aspeed_sliio_write(uint64_t offset, unsigned int size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
aspeed_sliio_read(uint64_t offset, unsigned int size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
+# flexcomm
+flexcomm_reset(void) ""
+flexcomm_irq(const char *id, uint8_t irq) "%s %d"
+flexcomm_reg_read(const char *devname, const char *regname, uint32_t addr, uint32_t val) "%s: %s[0x%04x] -> 0x%08x"
+flexcomm_reg_write(const char *dename, const char *regname, uint32_t addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x"
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 06/25] hw/misc/flexcomm.c: add common fifo functionality
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (4 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 05/25] hw/misc: add support for flexcomm Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 07/25] hw/char: add support for flexcomm usart Octavian Purdila
` (18 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
FLEXCOMM SPI and USART share FIFO functionality. Add common helper
functions to avoid code duplication.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
include/hw/misc/flexcomm.h | 2 +
include/hw/misc/flexcomm_function.h | 8 +++
hw/misc/flexcomm.c | 83 +++++++++++++++++++++++++++++
hw/misc/trace-events | 1 +
4 files changed, 94 insertions(+)
diff --git a/include/hw/misc/flexcomm.h b/include/hw/misc/flexcomm.h
index ea0fe77f26..832d4cd29d 100644
--- a/include/hw/misc/flexcomm.h
+++ b/include/hw/misc/flexcomm.h
@@ -44,6 +44,8 @@ struct FlexcommState {
uint32_t functions;
qemu_irq irq;
bool irq_state;
+ Fifo32 rx_fifo;
+ Fifo32 tx_fifo;
};
#endif /* HW_FLEXCOMM_H */
diff --git a/include/hw/misc/flexcomm_function.h b/include/hw/misc/flexcomm_function.h
index e498976927..3ff1677ff6 100644
--- a/include/hw/misc/flexcomm_function.h
+++ b/include/hw/misc/flexcomm_function.h
@@ -23,6 +23,8 @@ struct FlexcommFunction {
MemoryRegion mmio;
uint32_t *regs;
+ Fifo32 *tx_fifo;
+ Fifo32 *rx_fifo;
};
typedef void (*FlexcommFunctionSelect)(FlexcommFunction *f, bool selected);
@@ -32,6 +34,7 @@ struct FlexcommFunctionClass {
const MemoryRegionOps *mmio_ops;
const char *name;
+ bool has_fifos;
FlexcommFunctionSelect select;
};
@@ -43,5 +46,10 @@ static inline void flexcomm_select(FlexcommFunction *obj, bool selected)
}
void flexcomm_set_irq(FlexcommFunction *f, bool irq);
+void flexcomm_update_fifostat(FlexcommFunction *f);
+void flexcomm_clear_fifostat(FlexcommFunction *f, uint64_t value);
+void flexcomm_init_fifos(FlexcommFunction *f, unsigned num);
+void flexcomm_cleanup_fifos(FlexcommFunction *f);
+void flexcomm_reset_fifos(FlexcommFunction *f);
#endif /* HW_FLEXCOMM_FUNCTION_H */
diff --git a/hw/misc/flexcomm.c b/hw/misc/flexcomm.c
index 2337fb814c..a98d8845aa 100644
--- a/hw/misc/flexcomm.c
+++ b/hw/misc/flexcomm.c
@@ -22,6 +22,7 @@
#include "trace.h"
#include "migration/vmstate.h"
#include "hw/misc/flexcomm.h"
+#include "hw/arm/svd/flexcomm_usart.h"
#define REG(s, reg) (s->regs[R_FLEXCOMM_##reg])
#define RF_WR(s, reg, field, val) \
@@ -219,12 +220,22 @@ static void flexcomm_init(Object *obj)
sysbus_init_irq(sbd, &s->irq);
}
+static void flexcomm_finalize(Object *obj)
+{
+ FlexcommState *s = FLEXCOMM(obj);
+
+ /* release resources allocated by the function select (e.g. fifos) */
+ flexcomm_func_select(s, false);
+}
+
static void flexcomm_func_realize_and_unref(FlexcommFunction *f, Error **errp)
{
FlexcommState *s = FLEXCOMM(OBJECT(f)->parent);
FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_GET_CLASS(f);
f->regs = s->regs;
+ f->tx_fifo = &s->tx_fifo;
+ f->rx_fifo = &s->rx_fifo;
memory_region_add_subregion_overlap(&s->container, 0, &f->mmio, 0);
DEVICE(f)->id = g_strdup_printf("%s-%s", DEVICE(s)->id, fc->name);
sysbus_realize_and_unref(SYS_BUS_DEVICE(f), errp);
@@ -274,11 +285,82 @@ void flexcomm_set_irq(FlexcommFunction *f, bool irq)
}
}
+/* FIFO is shared between USART and SPI, provide common functions here */
+#define FIFO_REG(s, reg) (s->regs[R_FLEXCOMM_USART_FIFO##reg])
+#define FIFO_WR(s, reg, field, val) \
+ ARRAY_FIELD_DP32(s->regs, FLEXCOMM_USART_FIFO##reg, field, val)
+#define FIFO_RD(s, reg, field) \
+ ARRAY_FIELD_EX32(s->regs, FLEXCOMM_USART_FIFO##reg, field)
+
+void flexcomm_update_fifostat(FlexcommFunction *f)
+{
+ int rxlvl = fifo32_num_used(f->rx_fifo);
+ int txlvl = fifo32_num_used(f->tx_fifo);
+
+ FIFO_WR(f, STAT, RXLVL, rxlvl);
+ FIFO_WR(f, STAT, TXLVL, txlvl);
+ FIFO_WR(f, STAT, RXFULL, fifo32_is_full(f->rx_fifo) ? 1 : 0);
+ FIFO_WR(f, STAT, RXNOTEMPTY, !fifo32_is_empty(f->rx_fifo) ? 1 : 0);
+ FIFO_WR(f, STAT, TXNOTFULL, !fifo32_is_full(f->tx_fifo) ? 1 : 0);
+ FIFO_WR(f, STAT, TXEMPTY, fifo32_is_empty(f->tx_fifo) ? 1 : 0);
+
+ if (FIFO_RD(f, TRIG, RXLVLENA) && (rxlvl > FIFO_RD(f, TRIG, RXLVL))) {
+ FIFO_WR(f, INTSTAT, RXLVL, 1);
+ } else {
+ FIFO_WR(f, INTSTAT, RXLVL, 0);
+ }
+
+ if (FIFO_RD(f, TRIG, TXLVLENA) && (txlvl <= FIFO_RD(f, TRIG, TXLVL))) {
+ FIFO_WR(f, INTSTAT, TXLVL, 1);
+ } else {
+ FIFO_WR(f, INTSTAT, TXLVL, 0);
+ }
+
+ trace_flexcomm_fifostat(DEVICE(f)->id, FIFO_REG(f, STAT),
+ FIFO_REG(f, INTSTAT));
+}
+
+void flexcomm_reset_fifos(FlexcommFunction *f)
+{
+ if (FIFO_RD(f, CFG, EMPTYRX)) {
+ FIFO_WR(f, CFG, EMPTYRX, 0);
+ fifo32_reset(f->rx_fifo);
+ }
+ if (FIFO_RD(f, CFG, EMPTYTX)) {
+ FIFO_WR(f, CFG, EMPTYTX, 0);
+ fifo32_reset(f->tx_fifo);
+ }
+}
+
+void flexcomm_clear_fifostat(FlexcommFunction *f, uint64_t value)
+{
+ bool rxerr = FIELD_EX32(value, FLEXCOMM_USART_FIFOSTAT, RXERR);
+ bool txerr = FIELD_EX32(value, FLEXCOMM_USART_FIFOSTAT, TXERR);
+
+ if (rxerr) {
+ FIFO_WR(f, STAT, RXERR, 0);
+ }
+ if (txerr) {
+ FIFO_WR(f, STAT, TXERR, 0);
+ }
+}
+
static void flexcomm_function_select(FlexcommFunction *f, bool selected)
{
FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_GET_CLASS(f);
memory_region_set_enabled(&f->mmio, selected);
+ if (fc->has_fifos) {
+ if (selected) {
+ unsigned num = FIFO_RD(f, SIZE, FIFOSIZE);
+
+ fifo32_create(f->tx_fifo, num);
+ fifo32_create(f->rx_fifo, num);
+ } else {
+ fifo32_destroy(f->tx_fifo);
+ fifo32_destroy(f->rx_fifo);
+ }
+ }
}
static void flexcomm_function_init(Object *obj)
@@ -303,6 +385,7 @@ static const TypeInfo flexcomm_types[] = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(FlexcommState),
.instance_init = flexcomm_init,
+ .instance_finalize = flexcomm_finalize,
.class_init = flexcomm_class_init,
},
{
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 419879fd65..dc245905dc 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -367,3 +367,4 @@ flexcomm_reset(void) ""
flexcomm_irq(const char *id, uint8_t irq) "%s %d"
flexcomm_reg_read(const char *devname, const char *regname, uint32_t addr, uint32_t val) "%s: %s[0x%04x] -> 0x%08x"
flexcomm_reg_write(const char *dename, const char *regname, uint32_t addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x"
+flexcomm_fifostat(const char *id, uint32_t fifostat, uint32_t fifoinstat) "%s: %08x %08x"
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 07/25] hw/char: add support for flexcomm usart
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (5 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 06/25] hw/misc/flexcomm.c: add common fifo functionality Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 08/25] hw/i2c: add support for flexcomm i2c Octavian Purdila
` (17 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add support for NXP's flexcomm usart. It supports interupts and FIFO
access but no DMA.
The patch includes an automatically generated header which contains
the register layout and helpers.
The header can be regenerated with the svd-flexcomm-usart target when
the build is configured with --enable-mcux-soc-svd.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
include/hw/arm/svd/flexcomm_usart.h | 1021 +++++++++++++++++++++++++++
include/hw/char/flexcomm_usart.h | 33 +
include/hw/misc/flexcomm.h | 2 +
hw/char/flexcomm_usart.c | 288 ++++++++
hw/misc/flexcomm.c | 3 +
hw/arm/svd/meson.build | 3 +
hw/char/meson.build | 1 +
hw/char/trace-events | 8 +
8 files changed, 1359 insertions(+)
create mode 100644 include/hw/arm/svd/flexcomm_usart.h
create mode 100644 include/hw/char/flexcomm_usart.h
create mode 100644 hw/char/flexcomm_usart.c
diff --git a/include/hw/arm/svd/flexcomm_usart.h b/include/hw/arm/svd/flexcomm_usart.h
new file mode 100644
index 0000000000..fe560d5566
--- /dev/null
+++ b/include/hw/arm/svd/flexcomm_usart.h
@@ -0,0 +1,1021 @@
+/*
+ * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
+ */
+#pragma once
+
+#include "hw/register.h"
+
+/* Flexcomm USART */
+#define FLEXCOMM_USART_REGS_NO (1024)
+
+/* USART Configuration */
+REG32(FLEXCOMM_USART_CFG, 0);
+/* USART Enable */
+FIELD(FLEXCOMM_USART_CFG, ENABLE, 0, 1);
+/* Data Length. Selects the data size for the USART. */
+FIELD(FLEXCOMM_USART_CFG, DATALEN, 2, 2);
+/* Parity Select. Selects what type of parity is used by the USART. */
+FIELD(FLEXCOMM_USART_CFG, PARITYSEL, 4, 2);
+/* Stop Length */
+FIELD(FLEXCOMM_USART_CFG, STOPLEN, 6, 1);
+/* Mode 32 kHz */
+FIELD(FLEXCOMM_USART_CFG, MODE32K, 7, 1);
+/* LIN Break Mode Enable */
+FIELD(FLEXCOMM_USART_CFG, LINMODE, 8, 1);
+/* CTS Enable */
+FIELD(FLEXCOMM_USART_CFG, CTSEN, 9, 1);
+/* Synchronous Enable. Selects synchronous or asynchronous operation. */
+FIELD(FLEXCOMM_USART_CFG, SYNCEN, 11, 1);
+/* Clock Polarity */
+FIELD(FLEXCOMM_USART_CFG, CLKPOL, 12, 1);
+/* Synchronous mode Master Select */
+FIELD(FLEXCOMM_USART_CFG, SYNCMST, 14, 1);
+/* Loopback Mode */
+FIELD(FLEXCOMM_USART_CFG, LOOP, 15, 1);
+/* Output Enable Turnaround Time Enable for RS-485 Operation. */
+FIELD(FLEXCOMM_USART_CFG, OETA, 18, 1);
+/* Automatic Address Matching Enable */
+FIELD(FLEXCOMM_USART_CFG, AUTOADDR, 19, 1);
+/* Output Enable Select */
+FIELD(FLEXCOMM_USART_CFG, OESEL, 20, 1);
+/* Output Enable Polarity */
+FIELD(FLEXCOMM_USART_CFG, OEPOL, 21, 1);
+/* Receive Data Polarity */
+FIELD(FLEXCOMM_USART_CFG, RXPOL, 22, 1);
+/* Transmit data polarity */
+FIELD(FLEXCOMM_USART_CFG, TXPOL, 23, 1);
+
+/* USART Control */
+REG32(FLEXCOMM_USART_CTL, 4);
+/* Break Enable */
+FIELD(FLEXCOMM_USART_CTL, TXBRKEN, 1, 1);
+/* Enable Address Detect Mode */
+FIELD(FLEXCOMM_USART_CTL, ADDRDET, 2, 1);
+/* Transmit Disable */
+FIELD(FLEXCOMM_USART_CTL, TXDIS, 6, 1);
+/* Continuous Clock Generation */
+FIELD(FLEXCOMM_USART_CTL, CC, 8, 1);
+/* Clear Continuous Clock */
+FIELD(FLEXCOMM_USART_CTL, CLRCCONRX, 9, 1);
+/* Autobaud Enable */
+FIELD(FLEXCOMM_USART_CTL, AUTOBAUD, 16, 1);
+
+/* USART Status */
+REG32(FLEXCOMM_USART_STAT, 8);
+/* Receiver Idle */
+FIELD(FLEXCOMM_USART_STAT, RXIDLE, 1, 1);
+/* Transmitter Idle */
+FIELD(FLEXCOMM_USART_STAT, TXIDLE, 3, 1);
+/* CTS value */
+FIELD(FLEXCOMM_USART_STAT, CTS, 4, 1);
+/* Delta CTS */
+FIELD(FLEXCOMM_USART_STAT, DELTACTS, 5, 1);
+/* Transmitter Disabled Status Flag */
+FIELD(FLEXCOMM_USART_STAT, TXDISSTAT, 6, 1);
+/* Received Break */
+FIELD(FLEXCOMM_USART_STAT, RXBRK, 10, 1);
+/* Delta Received Break */
+FIELD(FLEXCOMM_USART_STAT, DELTARXBRK, 11, 1);
+/* Start */
+FIELD(FLEXCOMM_USART_STAT, START, 12, 1);
+/* Framing Error Interrupt Flag */
+FIELD(FLEXCOMM_USART_STAT, FRAMERRINT, 13, 1);
+/* Parity Error Interrupt Flag */
+FIELD(FLEXCOMM_USART_STAT, PARITYERRINT, 14, 1);
+/* Received Noise Interrupt Flag */
+FIELD(FLEXCOMM_USART_STAT, RXNOISEINT, 15, 1);
+/* Auto Baud Error */
+FIELD(FLEXCOMM_USART_STAT, ABERR, 16, 1);
+
+/* Interrupt Enable Read and Set for USART (not FIFO) Status */
+REG32(FLEXCOMM_USART_INTENSET, 12);
+/* Transmit Idle Flag */
+FIELD(FLEXCOMM_USART_INTENSET, TXIDLEEN, 3, 1);
+/* Delta CTS Input Flag */
+FIELD(FLEXCOMM_USART_INTENSET, DELTACTSEN, 5, 1);
+/* Transmit Disabled Flag */
+FIELD(FLEXCOMM_USART_INTENSET, TXDISEN, 6, 1);
+/* Delta Receive Break Enable */
+FIELD(FLEXCOMM_USART_INTENSET, DELTARXBRKEN, 11, 1);
+/* Start Enable */
+FIELD(FLEXCOMM_USART_INTENSET, STARTEN, 12, 1);
+/* Frame Error Enable */
+FIELD(FLEXCOMM_USART_INTENSET, FRAMERREN, 13, 1);
+/* Parity Error Enble */
+FIELD(FLEXCOMM_USART_INTENSET, PARITYERREN, 14, 1);
+/* Receive Noise Enable */
+FIELD(FLEXCOMM_USART_INTENSET, RXNOISEEN, 15, 1);
+/* Auto Baud Error Enable */
+FIELD(FLEXCOMM_USART_INTENSET, ABERREN, 16, 1);
+
+/* Interrupt Enable Clear */
+REG32(FLEXCOMM_USART_INTENCLR, 16);
+/* Transmit Idle Clear */
+FIELD(FLEXCOMM_USART_INTENCLR, TXIDLECLR, 3, 1);
+/* Delta CTS Clear */
+FIELD(FLEXCOMM_USART_INTENCLR, DELTACTSCLR, 5, 1);
+/* Transmit Disable Clear */
+FIELD(FLEXCOMM_USART_INTENCLR, TXDISCLR, 6, 1);
+/* Delta Receive Break Clear */
+FIELD(FLEXCOMM_USART_INTENCLR, DELTARXBRKCLR, 11, 1);
+/* Start Clear */
+FIELD(FLEXCOMM_USART_INTENCLR, STARTCLR, 12, 1);
+/* Frame Error Clear */
+FIELD(FLEXCOMM_USART_INTENCLR, FRAMERRCLR, 13, 1);
+/* Parity Error Clear */
+FIELD(FLEXCOMM_USART_INTENCLR, PARITYERRCLR, 14, 1);
+/* Receive Noise Clear */
+FIELD(FLEXCOMM_USART_INTENCLR, RXNOISECLR, 15, 1);
+/* Auto Baud Error Clear */
+FIELD(FLEXCOMM_USART_INTENCLR, ABERRCLR, 16, 1);
+
+/* Baud Rate Generator */
+REG32(FLEXCOMM_USART_BRG, 32);
+/* Baud Rate Generator Value */
+FIELD(FLEXCOMM_USART_BRG, BRGVAL, 0, 16);
+
+/* Interrupt Status */
+REG32(FLEXCOMM_USART_INTSTAT, 36);
+/* Transmitter Idle Flag */
+FIELD(FLEXCOMM_USART_INTSTAT, TXIDLE, 3, 1);
+/* Delta CTS Change Flag */
+FIELD(FLEXCOMM_USART_INTSTAT, DELTACTS, 5, 1);
+/* Transmitter Disabled Interrupt Flag */
+FIELD(FLEXCOMM_USART_INTSTAT, TXDISINT, 6, 1);
+/* Delta Receiver Break Change Flag */
+FIELD(FLEXCOMM_USART_INTSTAT, DELTARXBRK, 11, 1);
+/* Start Detected on Receiver Flag */
+FIELD(FLEXCOMM_USART_INTSTAT, START, 12, 1);
+/* Framing Error Interrupt Flag */
+FIELD(FLEXCOMM_USART_INTSTAT, FRAMERRINT, 13, 1);
+/* Parity Error Interrupt Flag */
+FIELD(FLEXCOMM_USART_INTSTAT, PARITYERRINT, 14, 1);
+/* Received Noise Interrupt Flag */
+FIELD(FLEXCOMM_USART_INTSTAT, RXNOISEINT, 15, 1);
+/* Auto Baud Error Interrupt Flag */
+FIELD(FLEXCOMM_USART_INTSTAT, ABERRINT, 16, 1);
+
+/* Oversample Selection Register for Asynchronous Communication */
+REG32(FLEXCOMM_USART_OSR, 40);
+/* Oversample Selection Value */
+FIELD(FLEXCOMM_USART_OSR, OSRVAL, 0, 4);
+
+/* Address Register for Automatic Address Matching */
+REG32(FLEXCOMM_USART_ADDR, 44);
+/* Address */
+FIELD(FLEXCOMM_USART_ADDR, ADDRESS, 0, 8);
+
+/* FIFO Configuration */
+REG32(FLEXCOMM_USART_FIFOCFG, 3584);
+/* Enable the Transmit FIFO. */
+FIELD(FLEXCOMM_USART_FIFOCFG, ENABLETX, 0, 1);
+/* Enable the Receive FIFO */
+FIELD(FLEXCOMM_USART_FIFOCFG, ENABLERX, 1, 1);
+/* FIFO Size Configuration */
+FIELD(FLEXCOMM_USART_FIFOCFG, SIZE, 4, 2);
+/* DMA Configuration for Transmit */
+FIELD(FLEXCOMM_USART_FIFOCFG, DMATX, 12, 1);
+/* DMA Configuration for Receive */
+FIELD(FLEXCOMM_USART_FIFOCFG, DMARX, 13, 1);
+/* Wake-up for Transmit FIFO Level */
+FIELD(FLEXCOMM_USART_FIFOCFG, WAKETX, 14, 1);
+/* Wake-up for Receive FIFO Level */
+FIELD(FLEXCOMM_USART_FIFOCFG, WAKERX, 15, 1);
+/* Empty Command for the Transmit FIFO */
+FIELD(FLEXCOMM_USART_FIFOCFG, EMPTYTX, 16, 1);
+/* Empty Command for the Receive FIFO */
+FIELD(FLEXCOMM_USART_FIFOCFG, EMPTYRX, 17, 1);
+/* Pop FIFO for Debug Reads */
+FIELD(FLEXCOMM_USART_FIFOCFG, POPDBG, 18, 1);
+
+/* FIFO Status */
+REG32(FLEXCOMM_USART_FIFOSTAT, 3588);
+/* TX FIFO Error */
+FIELD(FLEXCOMM_USART_FIFOSTAT, TXERR, 0, 1);
+/* RX FIFO Error */
+FIELD(FLEXCOMM_USART_FIFOSTAT, RXERR, 1, 1);
+/* Peripheral Interrupt */
+FIELD(FLEXCOMM_USART_FIFOSTAT, PERINT, 3, 1);
+/* Transmit FIFO Empty */
+FIELD(FLEXCOMM_USART_FIFOSTAT, TXEMPTY, 4, 1);
+/* Transmit FIFO is Not Full */
+FIELD(FLEXCOMM_USART_FIFOSTAT, TXNOTFULL, 5, 1);
+/* Receive FIFO is Not Empty */
+FIELD(FLEXCOMM_USART_FIFOSTAT, RXNOTEMPTY, 6, 1);
+/* Receive FIFO is Full */
+FIELD(FLEXCOMM_USART_FIFOSTAT, RXFULL, 7, 1);
+/* Transmit FIFO Current Level */
+FIELD(FLEXCOMM_USART_FIFOSTAT, TXLVL, 8, 5);
+/* Receive FIFO Current Level */
+FIELD(FLEXCOMM_USART_FIFOSTAT, RXLVL, 16, 5);
+
+/* FIFO Trigger Settings for Interrupt and DMA Request */
+REG32(FLEXCOMM_USART_FIFOTRIG, 3592);
+/* Transmit FIFO Level Trigger Enable. */
+FIELD(FLEXCOMM_USART_FIFOTRIG, TXLVLENA, 0, 1);
+/* Receive FIFO Level Trigger Enable */
+FIELD(FLEXCOMM_USART_FIFOTRIG, RXLVLENA, 1, 1);
+/* Transmit FIFO Level Trigger Point */
+FIELD(FLEXCOMM_USART_FIFOTRIG, TXLVL, 8, 4);
+/* Receive FIFO Level Trigger Point */
+FIELD(FLEXCOMM_USART_FIFOTRIG, RXLVL, 16, 4);
+
+/* FIFO Interrupt Enable */
+REG32(FLEXCOMM_USART_FIFOINTENSET, 3600);
+/* Transmit Error Interrupt Enable */
+FIELD(FLEXCOMM_USART_FIFOINTENSET, TXERR, 0, 1);
+/* Receive Error Interrupt Enable */
+FIELD(FLEXCOMM_USART_FIFOINTENSET, RXERR, 1, 1);
+/* Transmit FIFO Level Interrupt Enable */
+FIELD(FLEXCOMM_USART_FIFOINTENSET, TXLVL, 2, 1);
+/* Receive FIFO Level Interrupt Enable */
+FIELD(FLEXCOMM_USART_FIFOINTENSET, RXLVL, 3, 1);
+
+/* FIFO Interrupt Enable Clear */
+REG32(FLEXCOMM_USART_FIFOINTENCLR, 3604);
+/* Transmit Error Interrupt Enable */
+FIELD(FLEXCOMM_USART_FIFOINTENCLR, TXERR, 0, 1);
+/* Receive Error Interrupt Enable */
+FIELD(FLEXCOMM_USART_FIFOINTENCLR, RXERR, 1, 1);
+/* Transmit FIFO Level Interrupt Enable */
+FIELD(FLEXCOMM_USART_FIFOINTENCLR, TXLVL, 2, 1);
+/* Receive FIFO Level Interrupt Enable */
+FIELD(FLEXCOMM_USART_FIFOINTENCLR, RXLVL, 3, 1);
+
+/* FIFO Interrupt Status */
+REG32(FLEXCOMM_USART_FIFOINTSTAT, 3608);
+/* TX FIFO Error Interrupt Status */
+FIELD(FLEXCOMM_USART_FIFOINTSTAT, TXERR, 0, 1);
+/* RX FIFO Error Interrupt Status */
+FIELD(FLEXCOMM_USART_FIFOINTSTAT, RXERR, 1, 1);
+/* Transmit FIFO Level Interrupt Status */
+FIELD(FLEXCOMM_USART_FIFOINTSTAT, TXLVL, 2, 1);
+/* Receive FIFO Level Interrupt Status */
+FIELD(FLEXCOMM_USART_FIFOINTSTAT, RXLVL, 3, 1);
+/* Peripheral Interrupt Status */
+FIELD(FLEXCOMM_USART_FIFOINTSTAT, PERINT, 4, 1);
+
+/* FIFO Write Data */
+REG32(FLEXCOMM_USART_FIFOWR, 3616);
+/* Transmit data to the FIFO */
+FIELD(FLEXCOMM_USART_FIFOWR, TXDATA, 0, 9);
+
+/* FIFO Read Data */
+REG32(FLEXCOMM_USART_FIFORD, 3632);
+/* Received Data from the FIFO */
+FIELD(FLEXCOMM_USART_FIFORD, RXDATA, 0, 9);
+/* Framing Error Status Flag */
+FIELD(FLEXCOMM_USART_FIFORD, FRAMERR, 13, 1);
+/* Parity Error Status Flag */
+FIELD(FLEXCOMM_USART_FIFORD, PARITYERR, 14, 1);
+/* Received Noise Flag */
+FIELD(FLEXCOMM_USART_FIFORD, RXNOISE, 15, 1);
+
+/* FIFO Data Read with No FIFO Pop */
+REG32(FLEXCOMM_USART_FIFORDNOPOP, 3648);
+/* Received Data from the FIFO */
+FIELD(FLEXCOMM_USART_FIFORDNOPOP, RXDATA, 0, 9);
+/* Framing Error Status Flag */
+FIELD(FLEXCOMM_USART_FIFORDNOPOP, FRAMERR, 13, 1);
+/* Parity Error Status Flag */
+FIELD(FLEXCOMM_USART_FIFORDNOPOP, PARITYERR, 14, 1);
+/* Received Noise Flag */
+FIELD(FLEXCOMM_USART_FIFORDNOPOP, RXNOISE, 15, 1);
+
+/* FIFO Size */
+REG32(FLEXCOMM_USART_FIFOSIZE, 3656);
+/* FIFO Size */
+FIELD(FLEXCOMM_USART_FIFOSIZE, FIFOSIZE, 0, 5);
+
+/* Peripheral Identification */
+REG32(FLEXCOMM_USART_ID, 4092);
+/* Aperture */
+FIELD(FLEXCOMM_USART_ID, APERTURE, 0, 8);
+/* Minor revision of module implementation */
+FIELD(FLEXCOMM_USART_ID, MINOR_REV, 8, 4);
+/* Major revision of module implementation */
+FIELD(FLEXCOMM_USART_ID, MAJOR_REV, 12, 4);
+/* Module identifier for the selected function */
+FIELD(FLEXCOMM_USART_ID, ID, 16, 16);
+
+
+typedef enum {
+ /* Disabled */
+ FLEXCOMM_USART_CFG_ENABLE_DISABLED = 0,
+ /* Enabled. The USART is enabled for operation. */
+ FLEXCOMM_USART_CFG_ENABLE_ENABLED = 1,
+} FLEXCOMM_USART_CFG_ENABLE_Enum;
+
+typedef enum {
+ /* 7 bit data length */
+ FLEXCOMM_USART_CFG_DATALEN_BIT_7 = 0,
+ /* 8 bit data length */
+ FLEXCOMM_USART_CFG_DATALEN_BIT_8 = 1,
+ /*
+ * 9 bit data length. The 9th bit is commonly used for addressing in
+ * multidrop mode. See the ADDRDET[CTL].
+ */
+ FLEXCOMM_USART_CFG_DATALEN_BIT_9 = 2,
+} FLEXCOMM_USART_CFG_DATALEN_Enum;
+
+typedef enum {
+ /* No parity */
+ FLEXCOMM_USART_CFG_PARITYSEL_NO_PARITY = 0,
+ /* Even parity */
+ FLEXCOMM_USART_CFG_PARITYSEL_EVEN_PARITY = 2,
+ /* Odd parity */
+ FLEXCOMM_USART_CFG_PARITYSEL_ODD_PARITY = 3,
+} FLEXCOMM_USART_CFG_PARITYSEL_Enum;
+
+typedef enum {
+ /* 1 stop bit */
+ FLEXCOMM_USART_CFG_STOPLEN_BIT_1 = 0,
+ /*
+ * 2 stop bits. This setting should be used only for asynchronous
+ * communication.
+ */
+ FLEXCOMM_USART_CFG_STOPLEN_BITS_2 = 1,
+} FLEXCOMM_USART_CFG_STOPLEN_Enum;
+
+typedef enum {
+ /* Disabled. USART uses standard clocking. */
+ FLEXCOMM_USART_CFG_MODE32K_DISABLED = 0,
+ /* Enabled */
+ FLEXCOMM_USART_CFG_MODE32K_ENABLED = 1,
+} FLEXCOMM_USART_CFG_MODE32K_Enum;
+
+typedef enum {
+ /*
+ * Disabled. Break detect and generate is configured for normal operation.
+ */
+ FLEXCOMM_USART_CFG_LINMODE_DISABLED = 0,
+ /*
+ * Enabled. Break detect and generate is configured for LIN bus operation.
+ */
+ FLEXCOMM_USART_CFG_LINMODE_ENABLED = 1,
+} FLEXCOMM_USART_CFG_LINMODE_Enum;
+
+typedef enum {
+ /*
+ * No flow control. The transmitter does not receive any automatic flow
+ * control signal.
+ */
+ FLEXCOMM_USART_CFG_CTSEN_DISABLED = 0,
+ /*
+ * Flow control enabled. The transmitter uses the CTS input (or RTS output
+ * in loopback mode) for flow control purposes.
+ */
+ FLEXCOMM_USART_CFG_CTSEN_ENABLED = 1,
+} FLEXCOMM_USART_CFG_CTSEN_Enum;
+
+typedef enum {
+ /* Asynchronous mode */
+ FLEXCOMM_USART_CFG_SYNCEN_ASYNCHRONOUS_MODE = 0,
+ /* Synchronous mode */
+ FLEXCOMM_USART_CFG_SYNCEN_SYNCHRONOUS_MODE = 1,
+} FLEXCOMM_USART_CFG_SYNCEN_Enum;
+
+typedef enum {
+ /* Falling edge. RXD is sampled on the falling edge of SCLK. */
+ FLEXCOMM_USART_CFG_CLKPOL_FALLING_EDGE = 0,
+ /* Rising edge. RXD is sampled on the rising edge of SCLK. */
+ FLEXCOMM_USART_CFG_CLKPOL_RISING_EDGE = 1,
+} FLEXCOMM_USART_CFG_CLKPOL_Enum;
+
+typedef enum {
+ /* Slave. When synchronous mode is enabled, the USART is a slave. */
+ FLEXCOMM_USART_CFG_SYNCMST_SLAVE = 0,
+ /* Master. When synchronous mode is enabled, the USART is a master. */
+ FLEXCOMM_USART_CFG_SYNCMST_MASTER = 1,
+} FLEXCOMM_USART_CFG_SYNCMST_Enum;
+
+typedef enum {
+ /* Normal operation */
+ FLEXCOMM_USART_CFG_LOOP_NORMAL = 0,
+ /* Loopback mode */
+ FLEXCOMM_USART_CFG_LOOP_LOOPBACK = 1,
+} FLEXCOMM_USART_CFG_LOOP_Enum;
+
+typedef enum {
+ /* Disabled */
+ FLEXCOMM_USART_CFG_OETA_DISABLED = 0,
+ /* Enabled */
+ FLEXCOMM_USART_CFG_OETA_ENABLED = 1,
+} FLEXCOMM_USART_CFG_OETA_Enum;
+
+typedef enum {
+ /* Disabled */
+ FLEXCOMM_USART_CFG_AUTOADDR_DISABLED = 0,
+ /* Enabled */
+ FLEXCOMM_USART_CFG_AUTOADDR_ENABLED = 1,
+} FLEXCOMM_USART_CFG_AUTOADDR_Enum;
+
+typedef enum {
+ /*
+ * Standard. The RTS signal is used as the standard flow control function.
+ */
+ FLEXCOMM_USART_CFG_OESEL_STANDARD = 0,
+ /*
+ * RS-485. The RTS signal is configured to provide an output enable signal
+ * to control an RS-485 transceiver.
+ */
+ FLEXCOMM_USART_CFG_OESEL_RS_485 = 1,
+} FLEXCOMM_USART_CFG_OESEL_Enum;
+
+typedef enum {
+ /* Low. If selected by OESEL, the output enable is active low. */
+ FLEXCOMM_USART_CFG_OEPOL_LOW = 0,
+ /* High. If selected by OESEL, the output enable is active high. */
+ FLEXCOMM_USART_CFG_OEPOL_HIGH = 1,
+} FLEXCOMM_USART_CFG_OEPOL_Enum;
+
+typedef enum {
+ /* Standard */
+ FLEXCOMM_USART_CFG_RXPOL_STANDARD = 0,
+ /* Inverted */
+ FLEXCOMM_USART_CFG_RXPOL_INVERTED = 1,
+} FLEXCOMM_USART_CFG_RXPOL_Enum;
+
+typedef enum {
+ /* Standard */
+ FLEXCOMM_USART_CFG_TXPOL_STANDARD = 0,
+ /* Inverted */
+ FLEXCOMM_USART_CFG_TXPOL_INVERTED = 1,
+} FLEXCOMM_USART_CFG_TXPOL_Enum;
+
+typedef enum {
+ /* Normal operation */
+ FLEXCOMM_USART_CTL_TXBRKEN_NORMAL = 0,
+ /* Continuous break */
+ FLEXCOMM_USART_CTL_TXBRKEN_CONTINUOUS = 1,
+} FLEXCOMM_USART_CTL_TXBRKEN_Enum;
+
+typedef enum {
+ /* Disabled. The USART presents all incoming data. */
+ FLEXCOMM_USART_CTL_ADDRDET_DISABLED = 0,
+ /* Enabled */
+ FLEXCOMM_USART_CTL_ADDRDET_ENABLED = 1,
+} FLEXCOMM_USART_CTL_ADDRDET_Enum;
+
+typedef enum {
+ /* Not disabled. USART transmitter is not disabled. */
+ FLEXCOMM_USART_CTL_TXDIS_ENABLED = 0,
+ /*
+ * Disabled. USART transmitter is disabled after any character currently
+ * being transmitted is complete. This feature can be used to facilitate
+ * software flow control.
+ */
+ FLEXCOMM_USART_CTL_TXDIS_DISABLED = 1,
+} FLEXCOMM_USART_CTL_TXDIS_Enum;
+
+typedef enum {
+ /* Clock on character */
+ FLEXCOMM_USART_CTL_CC_CLOCK_ON_CHARACTER = 0,
+ /* Continuous clock */
+ FLEXCOMM_USART_CTL_CC_CONTINOUS_CLOCK = 1,
+} FLEXCOMM_USART_CTL_CC_Enum;
+
+typedef enum {
+ /* No effect. No effect on the CC bit. */
+ FLEXCOMM_USART_CTL_CLRCCONRX_NO_EFFECT = 0,
+ /* Auto-clear */
+ FLEXCOMM_USART_CTL_CLRCCONRX_AUTO_CLEAR = 1,
+} FLEXCOMM_USART_CTL_CLRCCONRX_Enum;
+
+typedef enum {
+ /* Disabled */
+ FLEXCOMM_USART_CTL_AUTOBAUD_DISABLED = 0,
+ /* Enabled */
+ FLEXCOMM_USART_CTL_AUTOBAUD_ENABLED = 1,
+} FLEXCOMM_USART_CTL_AUTOBAUD_Enum;
+
+typedef enum {
+ /* The receiver is currently receiving data. */
+ FLEXCOMM_USART_STAT_RXIDLE_RX_ACTIVE = 0,
+ /* The receiver is not currently receiving data. */
+ FLEXCOMM_USART_STAT_RXIDLE_RX_IDLE = 1,
+} FLEXCOMM_USART_STAT_RXIDLE_Enum;
+
+typedef enum {
+ /* The transmitter is currently sending data. */
+ FLEXCOMM_USART_STAT_TXIDLE_TX_ACTIVE = 0,
+ /* The transmitter is not currently sending data. */
+ FLEXCOMM_USART_STAT_TXIDLE_TX_IDLE = 1,
+} FLEXCOMM_USART_STAT_TXIDLE_Enum;
+
+typedef enum {
+ /*
+ * Not Idle. Indicates that the USART transmitter is NOT fully idle after
+ * being disabled.
+ */
+ FLEXCOMM_USART_STAT_TXDISSTAT_TX_NOT_IDLE = 0,
+ /*
+ * Idle. Indicates that the USART transmitter is fully idle after being
+ * disabled (CTL[TXDIS] = 1).
+ */
+ FLEXCOMM_USART_STAT_TXDISSTAT_TX_IDLE = 1,
+} FLEXCOMM_USART_STAT_TXDISSTAT_Enum;
+
+typedef enum {
+ /*
+ * Enables an interrupt when the transmitter becomes idle (STAT[TXIDLE] =
+ * 1).
+ */
+ FLEXCOMM_USART_INTENSET_TXIDLEEN_ENABLE = 1,
+} FLEXCOMM_USART_INTENSET_TXIDLEEN_Enum;
+
+typedef enum {
+ /*
+ * Enables an interrupt when there is a change in the state of the CTS
+ * input.
+ */
+ FLEXCOMM_USART_INTENSET_DELTACTSEN_ENABLE = 1,
+} FLEXCOMM_USART_INTENSET_DELTACTSEN_Enum;
+
+typedef enum {
+ /*
+ * Enables an interrupt when the transmitter is fully disabled as indicated
+ * by the STAT[TXDISINT] flag. See the description of the STAT[TXDISINT]
+ * flag.
+ */
+ FLEXCOMM_USART_INTENSET_TXDISEN_ENABLE = 1,
+} FLEXCOMM_USART_INTENSET_TXDISEN_Enum;
+
+typedef enum {
+ /* Enable */
+ FLEXCOMM_USART_INTENSET_DELTARXBRKEN_ENABLE = 1,
+} FLEXCOMM_USART_INTENSET_DELTARXBRKEN_Enum;
+
+typedef enum {
+ /* Enables an interrupt when a received start bit has been detected. */
+ FLEXCOMM_USART_INTENSET_STARTEN_ENABLE = 1,
+} FLEXCOMM_USART_INTENSET_STARTEN_Enum;
+
+typedef enum {
+ /* Enables an interrupt when a framing error has been detected. */
+ FLEXCOMM_USART_INTENSET_FRAMERREN_ENABLE = 1,
+} FLEXCOMM_USART_INTENSET_FRAMERREN_Enum;
+
+typedef enum {
+ /* Enables an interrupt when a parity error has been detected. */
+ FLEXCOMM_USART_INTENSET_PARITYERREN_ENABLE = 1,
+} FLEXCOMM_USART_INTENSET_PARITYERREN_Enum;
+
+typedef enum {
+ /*
+ * Enables an interrupt when noise is detected. See the description of the
+ * CTL[RXNOISEINT] bit.
+ */
+ FLEXCOMM_USART_INTENSET_RXNOISEEN_ENABLE = 1,
+} FLEXCOMM_USART_INTENSET_RXNOISEEN_Enum;
+
+typedef enum {
+ /* Enables an interrupt when an auto baud error occurs. */
+ FLEXCOMM_USART_INTENSET_ABERREN_ENABLE = 1,
+} FLEXCOMM_USART_INTENSET_ABERREN_Enum;
+
+typedef enum {
+ /* FCLK is used directly by the USART function. */
+ FLEXCOMM_USART_BRG_BRGVAL_Zero = 0,
+ /* FCLK is divided by 2 before use by the USART function. */
+ FLEXCOMM_USART_BRG_BRGVAL_One = 1,
+ /* FCLK is divided by 3 before use by the USART function. */
+ FLEXCOMM_USART_BRG_BRGVAL_Two = 2,
+ /* FCLK is divided by 65,536 before use by the USART function. */
+ FLEXCOMM_USART_BRG_BRGVAL_FFFF = 65535,
+} FLEXCOMM_USART_BRG_BRGVAL_Enum;
+
+typedef enum {
+ /* Not supported */
+ FLEXCOMM_USART_OSR_OSRVAL_zero = 0,
+ /* Not supported */
+ FLEXCOMM_USART_OSR_OSRVAL_one = 1,
+ /* Not supported */
+ FLEXCOMM_USART_OSR_OSRVAL_two = 2,
+ /* Not supported */
+ FLEXCOMM_USART_OSR_OSRVAL_three = 3,
+ /* 5 function clocks are used to transmit and receive each data bit. */
+ FLEXCOMM_USART_OSR_OSRVAL_four = 4,
+ /* 6 function clocks are used to transmit and receive each data bit. */
+ FLEXCOMM_USART_OSR_OSRVAL_five = 5,
+ /* 16 function clocks are used to transmit and receive each data bit. */
+ FLEXCOMM_USART_OSR_OSRVAL_sixteen = 15,
+} FLEXCOMM_USART_OSR_OSRVAL_Enum;
+
+typedef enum {
+ /* The transmit FIFO is not enabled. */
+ FLEXCOMM_USART_FIFOCFG_ENABLETX_DISABLED = 0,
+ /* The transmit FIFO is enabled. */
+ FLEXCOMM_USART_FIFOCFG_ENABLETX_ENABLED = 1,
+} FLEXCOMM_USART_FIFOCFG_ENABLETX_Enum;
+
+typedef enum {
+ /* The receive FIFO is not enabled. */
+ FLEXCOMM_USART_FIFOCFG_ENABLERX_DISABLED = 0,
+ /* The receive FIFO is enabled. */
+ FLEXCOMM_USART_FIFOCFG_ENABLERX_ENABLED = 1,
+} FLEXCOMM_USART_FIFOCFG_ENABLERX_Enum;
+
+typedef enum {
+ /* FIFO is configured as 16 entries of 8 bits. */
+ FLEXCOMM_USART_FIFOCFG_SIZE_SIZE16 = 0,
+ /* Not used */
+ FLEXCOMM_USART_FIFOCFG_SIZE_SIZEINVALID1 = 1,
+ /* Not used */
+ FLEXCOMM_USART_FIFOCFG_SIZE_SIZEINVALID2 = 2,
+ /* Not used */
+ FLEXCOMM_USART_FIFOCFG_SIZE_SIZEINVALID3 = 3,
+} FLEXCOMM_USART_FIFOCFG_SIZE_Enum;
+
+typedef enum {
+ /* DMA is not used for the transmit function. */
+ FLEXCOMM_USART_FIFOCFG_DMATX_DISABLED = 0,
+ /*
+ * Triggers DMA for the transmit function if the FIFO is not full.
+ * Generally, data interrupts would be disabled if DMA is enabled.
+ */
+ FLEXCOMM_USART_FIFOCFG_DMATX_ENABLED = 1,
+} FLEXCOMM_USART_FIFOCFG_DMATX_Enum;
+
+typedef enum {
+ /* DMA is not used for the receive function. */
+ FLEXCOMM_USART_FIFOCFG_DMARX_DISABLED = 0,
+ /*
+ * Triggers DMA for the receive function if the FIFO is not empty.
+ * Generally, data interrupts would be disabled if DMA is enabled.
+ */
+ FLEXCOMM_USART_FIFOCFG_DMARX_ENABLED = 1,
+} FLEXCOMM_USART_FIFOCFG_DMARX_Enum;
+
+typedef enum {
+ /* Only enabled interrupts will wake up the device from low power modes. */
+ FLEXCOMM_USART_FIFOCFG_WAKETX_DISABLED = 0,
+ /*
+ * A device wake-up for DMA will occur if the transmit FIFO level reaches
+ * the value specified by FIFOTRIG[TXLVL], even when the TXLVL interrupt is
+ * not enabled.
+ */
+ FLEXCOMM_USART_FIFOCFG_WAKETX_ENABLED = 1,
+} FLEXCOMM_USART_FIFOCFG_WAKETX_Enum;
+
+typedef enum {
+ /* Only enabled interrupts will wake up the device from low power modes. */
+ FLEXCOMM_USART_FIFOCFG_WAKERX_DISABLED = 0,
+ /*
+ * A device wake-up for DMA will occur if the receive FIFO level reaches
+ * the value specified by FIFOTRIG[RXLVL], even when the RXLVL interrupt is
+ * not enabled.
+ */
+ FLEXCOMM_USART_FIFOCFG_WAKERX_ENABLED = 1,
+} FLEXCOMM_USART_FIFOCFG_WAKERX_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_USART_FIFOCFG_EMPTYTX_NO_EFFECT = 0,
+ /* The TX FIFO is emptied. */
+ FLEXCOMM_USART_FIFOCFG_EMPTYTX_EMPTY_THE_TX_FIFO = 1,
+} FLEXCOMM_USART_FIFOCFG_EMPTYTX_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_USART_FIFOCFG_EMPTYRX_NO_EFFECT = 0,
+ /* The RX FIFO is emptied. */
+ FLEXCOMM_USART_FIFOCFG_EMPTYRX_EMPTY_THE_RX_FIFO = 1,
+} FLEXCOMM_USART_FIFOCFG_EMPTYRX_Enum;
+
+typedef enum {
+ /* Debug reads of the FIFO do not pop the FIFO. */
+ FLEXCOMM_USART_FIFOCFG_POPDBG_DO_NOT_POP = 0,
+ /* A debug read will cause the FIFO to pop. */
+ FLEXCOMM_USART_FIFOCFG_POPDBG_POP = 1,
+} FLEXCOMM_USART_FIFOCFG_POPDBG_Enum;
+
+typedef enum {
+ /* A transmit FIFO error has not occurred. */
+ FLEXCOMM_USART_FIFOSTAT_TXERR_NO_TXERR = 0,
+ /*
+ * A transmit FIFO error has occurred. This error could be an overflow
+ * caused by pushing data into a full FIFO, or by an underflow if the FIFO
+ * is empty when data is needed.
+ */
+ FLEXCOMM_USART_FIFOSTAT_TXERR_TXERR = 1,
+} FLEXCOMM_USART_FIFOSTAT_TXERR_Enum;
+
+typedef enum {
+ /* A receive FIFO overflow has not occurred */
+ FLEXCOMM_USART_FIFOSTAT_RXERR_NO_RXERR = 0,
+ /*
+ * A receive FIFO overflow has occurred, caused by software or DMA not
+ * emptying the FIFO fast enough
+ */
+ FLEXCOMM_USART_FIFOSTAT_RXERR_RXERR = 1,
+} FLEXCOMM_USART_FIFOSTAT_RXERR_Enum;
+
+typedef enum {
+ /* No Peripheral Interrupt */
+ FLEXCOMM_USART_FIFOSTAT_PERINT_NO_PERINT = 0,
+ /* Peripheral Interrupt */
+ FLEXCOMM_USART_FIFOSTAT_PERINT_PERINT = 1,
+} FLEXCOMM_USART_FIFOSTAT_PERINT_Enum;
+
+typedef enum {
+ /* The transmit FIFO is not empty. */
+ FLEXCOMM_USART_FIFOSTAT_TXEMPTY_TXFIFO_ISNOTEMPTY = 0,
+ /*
+ * The transmit FIFO is empty, although the peripheral may still be
+ * processing the last piece of data.
+ */
+ FLEXCOMM_USART_FIFOSTAT_TXEMPTY_TXFIFO_ISEMPTY = 1,
+} FLEXCOMM_USART_FIFOSTAT_TXEMPTY_Enum;
+
+typedef enum {
+ /*
+ * The transmit FIFO is full and another write would cause it to overflow.
+ */
+ FLEXCOMM_USART_FIFOSTAT_TXNOTFULL_TXFIFO_ISFULL = 0,
+ /* The transmit FIFO is not full, so more data can be written. */
+ FLEXCOMM_USART_FIFOSTAT_TXNOTFULL_TXFIFO_ISNOTFULL = 1,
+} FLEXCOMM_USART_FIFOSTAT_TXNOTFULL_Enum;
+
+typedef enum {
+ /* The receive FIFO is empty. */
+ FLEXCOMM_USART_FIFOSTAT_RXNOTEMPTY_RXFIFO_ISEMPTY = 0,
+ /* The receive FIFO is not empty, so data can be read. */
+ FLEXCOMM_USART_FIFOSTAT_RXNOTEMPTY_RXFIFO_ISNOTEMPTY = 1,
+} FLEXCOMM_USART_FIFOSTAT_RXNOTEMPTY_Enum;
+
+typedef enum {
+ /* The receive FIFO is not full. */
+ FLEXCOMM_USART_FIFOSTAT_RXFULL_RXFIFO_ISNOTFULL = 0,
+ /* The receive FIFO is full. */
+ FLEXCOMM_USART_FIFOSTAT_RXFULL_RXFIFO_ISFULL = 1,
+} FLEXCOMM_USART_FIFOSTAT_RXFULL_Enum;
+
+typedef enum {
+ /* Transmit FIFO level does not generate a FIFO level trigger. */
+ FLEXCOMM_USART_FIFOTRIG_TXLVLENA_DISABLED = 0,
+ /*
+ * A trigger will be generated if the transmit FIFO level reaches the value
+ * specified by the TXLVL field.
+ */
+ FLEXCOMM_USART_FIFOTRIG_TXLVLENA_ENABLED = 1,
+} FLEXCOMM_USART_FIFOTRIG_TXLVLENA_Enum;
+
+typedef enum {
+ /* Receive FIFO level does not generate a FIFO level trigger. */
+ FLEXCOMM_USART_FIFOTRIG_RXLVLENA_DISABLED = 0,
+ /*
+ * An trigger will be generated if the receive FIFO level reaches the value
+ * specified by the RXLVL field.
+ */
+ FLEXCOMM_USART_FIFOTRIG_RXLVLENA_ENABLED = 1,
+} FLEXCOMM_USART_FIFOTRIG_RXLVLENA_Enum;
+
+typedef enum {
+ /* Trigger when the TX FIFO becomes empty */
+ FLEXCOMM_USART_FIFOTRIG_TXLVL_TXLVL0 = 0,
+ /* Trigger when the TX FIFO level decreases to 1 entry */
+ FLEXCOMM_USART_FIFOTRIG_TXLVL_TXLVL1 = 1,
+ /*
+ * Trigger when the TX FIFO level decreases to 15 entries (is no longer
+ * full)
+ */
+ FLEXCOMM_USART_FIFOTRIG_TXLVL_TXLVL15 = 15,
+} FLEXCOMM_USART_FIFOTRIG_TXLVL_Enum;
+
+typedef enum {
+ /* Trigger when the RX FIFO has received 1 entry (is no longer empty) */
+ FLEXCOMM_USART_FIFOTRIG_RXLVL_RXLVL1 = 0,
+ /* Trigger when the RX FIFO has received 2 entries */
+ FLEXCOMM_USART_FIFOTRIG_RXLVL_RXLVL2 = 1,
+ /* Trigger when the RX FIFO has received 16 entries (has become full) */
+ FLEXCOMM_USART_FIFOTRIG_RXLVL_RXLVL15 = 15,
+} FLEXCOMM_USART_FIFOTRIG_RXLVL_Enum;
+
+typedef enum {
+ /* No interrupt will be generated for a transmit error. */
+ FLEXCOMM_USART_FIFOINTENSET_TXERR_DISABLED = 0,
+ /* An interrupt will be generated when a transmit error occurs. */
+ FLEXCOMM_USART_FIFOINTENSET_TXERR_ENABLED = 1,
+} FLEXCOMM_USART_FIFOINTENSET_TXERR_Enum;
+
+typedef enum {
+ /* No interrupt will be generated for a receive error. */
+ FLEXCOMM_USART_FIFOINTENSET_RXERR_DISABLED = 0,
+ /* An interrupt will be generated when a receive error occurs. */
+ FLEXCOMM_USART_FIFOINTENSET_RXERR_ENABLED = 1,
+} FLEXCOMM_USART_FIFOINTENSET_RXERR_Enum;
+
+typedef enum {
+ /* No interrupt will be generated based on the TX FIFO level. */
+ FLEXCOMM_USART_FIFOINTENSET_TXLVL_DISABLED = 0,
+ /*
+ * If FIFOTRIG[TXLVLENA] = 1, then an interrupt will be generated when the
+ * TX FIFO level decreases to the level specified by FIFOTRIG[TXLVL]
+ */
+ FLEXCOMM_USART_FIFOINTENSET_TXLVL_ENABLED = 1,
+} FLEXCOMM_USART_FIFOINTENSET_TXLVL_Enum;
+
+typedef enum {
+ /* No interrupt will be generated based on the RX FIFO level. */
+ FLEXCOMM_USART_FIFOINTENSET_RXLVL_DISABLED = 0,
+ /*
+ * If FIFOTRIG[RXLVLENA] = 1, an interrupt will be generated when the when
+ * the RX FIFO level increases to the level specified by FIFOTRIG[RXLVL].
+ */
+ FLEXCOMM_USART_FIFOINTENSET_RXLVL_ENABLED = 1,
+} FLEXCOMM_USART_FIFOINTENSET_RXLVL_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_USART_FIFOINTENCLR_TXERR_NO_EFFECT = 0,
+ /* Clear the interrupt */
+ FLEXCOMM_USART_FIFOINTENCLR_TXERR_CLEAR_THE_TXERR = 1,
+} FLEXCOMM_USART_FIFOINTENCLR_TXERR_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_USART_FIFOINTENCLR_RXERR_NO_EFFECT = 0,
+ /* Clear the interrupt */
+ FLEXCOMM_USART_FIFOINTENCLR_RXERR_CLEAR_THE_RXERR = 1,
+} FLEXCOMM_USART_FIFOINTENCLR_RXERR_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_USART_FIFOINTENCLR_TXLVL_NO_EFFECT = 0,
+ /* Clear the interrupt */
+ FLEXCOMM_USART_FIFOINTENCLR_TXLVL_CLEAR_THE_TXLVL = 1,
+} FLEXCOMM_USART_FIFOINTENCLR_TXLVL_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_USART_FIFOINTENCLR_RXLVL_NO_EFFECT = 0,
+ /* Clear the interrupt */
+ FLEXCOMM_USART_FIFOINTENCLR_RXLVL_CLEAR_THE_RXLVL = 1,
+} FLEXCOMM_USART_FIFOINTENCLR_RXLVL_Enum;
+
+typedef enum {
+ /* Not pending */
+ FLEXCOMM_USART_FIFOINTSTAT_TXERR_TXERR_ISNOTPENDING = 0,
+ /* Pending */
+ FLEXCOMM_USART_FIFOINTSTAT_TXERR_TXERR_ISPENDING = 1,
+} FLEXCOMM_USART_FIFOINTSTAT_TXERR_Enum;
+
+typedef enum {
+ /* Not pending */
+ FLEXCOMM_USART_FIFOINTSTAT_RXERR_RXERR_ISNOTPENDING = 0,
+ /* Pending */
+ FLEXCOMM_USART_FIFOINTSTAT_RXERR_RXERR_ISPENDING = 1,
+} FLEXCOMM_USART_FIFOINTSTAT_RXERR_Enum;
+
+typedef enum {
+ /* Not pending */
+ FLEXCOMM_USART_FIFOINTSTAT_TXLVL_TXLVL_ISNOTPENDING = 0,
+ /* Pending */
+ FLEXCOMM_USART_FIFOINTSTAT_TXLVL_TXLVL_ISPENDING = 1,
+} FLEXCOMM_USART_FIFOINTSTAT_TXLVL_Enum;
+
+typedef enum {
+ /* Not pending */
+ FLEXCOMM_USART_FIFOINTSTAT_RXLVL_RXLVL_ISNOTPENDING = 0,
+ /* Pending */
+ FLEXCOMM_USART_FIFOINTSTAT_RXLVL_RXLVL_ISPENDING = 1,
+} FLEXCOMM_USART_FIFOINTSTAT_RXLVL_Enum;
+
+typedef enum {
+ /* Not pending */
+ FLEXCOMM_USART_FIFOINTSTAT_PERINT_PERINT_ISNOTPENDING = 0,
+ /* Pending */
+ FLEXCOMM_USART_FIFOINTSTAT_PERINT_PERINT_ISPENDING = 1,
+} FLEXCOMM_USART_FIFOINTSTAT_PERINT_Enum;
+
+
+#define FLEXCOMM_USART_REGISTER_ACCESS_INFO_ARRAY(_name) \
+ struct RegisterAccessInfo _name[FLEXCOMM_USART_REGS_NO] = { \
+ [0 ... FLEXCOMM_USART_REGS_NO - 1] = { \
+ .name = "", \
+ .addr = -1, \
+ }, \
+ [R_FLEXCOMM_USART_CFG] = { \
+ .name = "CFG", \
+ .addr = 0x0, \
+ .ro = 0xFF032402, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_CTL] = { \
+ .name = "CTL", \
+ .addr = 0x4, \
+ .ro = 0xFFFEFCB9, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_STAT] = { \
+ .name = "STAT", \
+ .addr = 0x8, \
+ .ro = 0xFFFE07DF, \
+ .reset = 0xA, \
+ }, \
+ [R_FLEXCOMM_USART_INTENSET] = { \
+ .name = "INTENSET", \
+ .addr = 0xC, \
+ .ro = 0xFFFE0797, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_INTENCLR] = { \
+ .name = "INTENCLR", \
+ .addr = 0x10, \
+ .ro = 0xFFFE0797, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_BRG] = { \
+ .name = "BRG", \
+ .addr = 0x20, \
+ .ro = 0xFFFF0000, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_INTSTAT] = { \
+ .name = "INTSTAT", \
+ .addr = 0x24, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_OSR] = { \
+ .name = "OSR", \
+ .addr = 0x28, \
+ .ro = 0xFFFFFFF0, \
+ .reset = 0xF, \
+ }, \
+ [R_FLEXCOMM_USART_ADDR] = { \
+ .name = "ADDR", \
+ .addr = 0x2C, \
+ .ro = 0xFFFFFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_FIFOCFG] = { \
+ .name = "FIFOCFG", \
+ .addr = 0xE00, \
+ .ro = 0xFFF80FFC, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_FIFOSTAT] = { \
+ .name = "FIFOSTAT", \
+ .addr = 0xE04, \
+ .ro = 0xFFFFFFFC, \
+ .reset = 0x30, \
+ }, \
+ [R_FLEXCOMM_USART_FIFOTRIG] = { \
+ .name = "FIFOTRIG", \
+ .addr = 0xE08, \
+ .ro = 0xFFF0F0FC, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_FIFOINTENSET] = { \
+ .name = "FIFOINTENSET", \
+ .addr = 0xE10, \
+ .ro = 0xFFFFFFF0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_FIFOINTENCLR] = { \
+ .name = "FIFOINTENCLR", \
+ .addr = 0xE14, \
+ .ro = 0xFFFFFFF0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_FIFOINTSTAT] = { \
+ .name = "FIFOINTSTAT", \
+ .addr = 0xE18, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_FIFOWR] = { \
+ .name = "FIFOWR", \
+ .addr = 0xE20, \
+ .ro = 0xFFFFFE00, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_FIFORD] = { \
+ .name = "FIFORD", \
+ .addr = 0xE30, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_FIFORDNOPOP] = { \
+ .name = "FIFORDNOPOP", \
+ .addr = 0xE40, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_USART_FIFOSIZE] = { \
+ .name = "FIFOSIZE", \
+ .addr = 0xE48, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x10, \
+ }, \
+ [R_FLEXCOMM_USART_ID] = { \
+ .name = "ID", \
+ .addr = 0xFFC, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0xE0102100, \
+ }, \
+ }
diff --git a/include/hw/char/flexcomm_usart.h b/include/hw/char/flexcomm_usart.h
new file mode 100644
index 0000000000..e67b15208f
--- /dev/null
+++ b/include/hw/char/flexcomm_usart.h
@@ -0,0 +1,33 @@
+/*
+ * QEMU model for NXP's FLEXCOMM USART
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_FLEXCOMM_USART_H
+#define HW_FLEXCOMM_USART_H
+
+#include "hw/misc/flexcomm_function.h"
+#include "chardev/char-fe.h"
+
+#define TYPE_FLEXCOMM_USART "flexcomm-usart"
+OBJECT_DECLARE_TYPE(FlexcommUsartState, FlexcommUsartClass, FLEXCOMM_USART);
+
+struct FlexcommUsartState {
+ FlexcommFunction parent_obj;
+
+ CharBackend chr;
+};
+
+struct FlexcommUsartClass {
+ FlexcommFunctionClass parent_obj;
+
+ FlexcommFunctionSelect select;
+};
+
+#endif /* HW_FLEXCOMM_USART_H */
diff --git a/include/hw/misc/flexcomm.h b/include/hw/misc/flexcomm.h
index 832d4cd29d..679b7ea64d 100644
--- a/include/hw/misc/flexcomm.h
+++ b/include/hw/misc/flexcomm.h
@@ -15,6 +15,7 @@
#include "hw/sysbus.h"
#include "hw/arm/svd/flexcomm.h"
#include "qemu/fifo32.h"
+#include "hw/char/flexcomm_usart.h"
#define FLEXCOMM_FUNC_USART 0
#define FLEXCOMM_FUNC_SPI 1
@@ -46,6 +47,7 @@ struct FlexcommState {
bool irq_state;
Fifo32 rx_fifo;
Fifo32 tx_fifo;
+ FlexcommUsartState usart;
};
#endif /* HW_FLEXCOMM_H */
diff --git a/hw/char/flexcomm_usart.c b/hw/char/flexcomm_usart.c
new file mode 100644
index 0000000000..53ab5d8379
--- /dev/null
+++ b/hw/char/flexcomm_usart.c
@@ -0,0 +1,288 @@
+/*
+ * QEMU model for NXP's FLEXCOMM USART
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "exec/address-spaces.h"
+#include "qapi/error.h"
+#include "trace.h"
+#include "hw/misc/flexcomm.h"
+#include "hw/char/flexcomm_usart.h"
+#include "hw/arm/svd/flexcomm_usart.h"
+
+#define REG(s, reg) (s->regs[R_FLEXCOMM_USART_##reg])
+/* register field write helper macro */
+#define RF_RD(s, reg, field, val) \
+ ARRAY_FIELD_DP32(s->regs, FLEXCOMM_USART_##reg, field, val)
+/* register field read helper macro */
+#define RF_WR(s, reg, field) \
+ ARRAY_FIELD_EX32(s->regs, FLEXCOMM_USART_##reg, field)
+
+static FLEXCOMM_USART_REGISTER_ACCESS_INFO_ARRAY(reg_info);
+
+static void flexcomm_usart_reset(FlexcommFunction *f)
+{
+ for (int i = 0; i < FLEXCOMM_USART_REGS_NO; i++) {
+ hwaddr addr = reg_info[i].addr;
+
+ if (addr != -1) {
+ struct RegisterInfo ri = {
+ .data = &f->regs[addr / 4],
+ .data_size = 4,
+ .access = ®_info[i],
+ };
+
+ register_reset(&ri);
+ }
+ }
+}
+
+static void flexcomm_usart_irq_update(FlexcommFunction *f)
+{
+ bool irq, per_irqs, fifo_irqs, enabled = RF_WR(f, CFG, ENABLE);
+
+ flexcomm_update_fifostat(f);
+ fifo_irqs = REG(f, FIFOINTSTAT) & REG(f, FIFOINTENSET);
+
+ REG(f, INTSTAT) = REG(f, STAT) & REG(f, INTENSET);
+ per_irqs = REG(f, INTSTAT) != 0;
+
+ irq = enabled && (fifo_irqs || per_irqs);
+
+ trace_flexcomm_usart_irq(DEVICE(f)->id, irq, fifo_irqs, per_irqs, enabled);
+ flexcomm_set_irq(f, irq);
+}
+
+static int flexcomm_usart_rx_space(void *opaque)
+{
+ FlexcommUsartState *s = FLEXCOMM_USART(opaque);
+ FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
+
+ uint32_t ret = fifo32_num_free(f->rx_fifo);
+
+ if (!RF_WR(f, CFG, ENABLE) || !RF_WR(f, FIFOCFG, ENABLERX)) {
+ ret = 0;
+ }
+
+ trace_flexcomm_usart_rx_space(DEVICE(s)->id, ret);
+
+ return ret;
+}
+
+static void flexcomm_usart_rx(void *opaque, const uint8_t *buf, int size)
+{
+ FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
+
+ if (!RF_WR(f, CFG, ENABLE) || !RF_WR(f, FIFOCFG, ENABLERX)) {
+ return;
+ }
+
+ trace_flexcomm_usart_rx(DEVICE(f)->id);
+
+ while (!fifo32_is_full(f->rx_fifo) && size) {
+ fifo32_push(f->rx_fifo, *buf++);
+ size--;
+ }
+
+ flexcomm_usart_irq_update(f);
+}
+
+static MemTxResult flexcomm_usart_reg_read(void *opaque, hwaddr addr,
+ uint64_t *data, unsigned size,
+ MemTxAttrs attrs)
+{
+ FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
+ FlexcommUsartState *s = FLEXCOMM_USART(opaque);
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+ MemTxResult ret = MEMTX_OK;
+
+ if (size != 4) {
+ ret = MEMTX_ERROR;
+ goto out;
+ }
+
+ switch (addr) {
+ case A_FLEXCOMM_USART_FIFORD:
+ {
+ if (!fifo32_is_empty(f->rx_fifo)) {
+ *data = fifo32_pop(f->rx_fifo);
+ qemu_chr_fe_accept_input(&s->chr);
+ }
+ break;
+ }
+ case A_FLEXCOMM_USART_FIFORDNOPOP:
+ {
+ if (!fifo32_is_empty(f->rx_fifo)) {
+ *data = fifo32_peek(f->rx_fifo);
+ }
+ break;
+ }
+ default:
+ *data = f->regs[addr / 4];
+ break;
+ }
+
+ flexcomm_usart_irq_update(f);
+
+out:
+ trace_flexcomm_usart_reg_read(DEVICE(f)->id, rai->name, addr, *data);
+ return ret;
+}
+
+static MemTxResult flexcomm_usart_reg_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size,
+ MemTxAttrs attrs)
+{
+ FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
+ FlexcommUsartState *s = FLEXCOMM_USART(opaque);
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+ struct RegisterInfo ri = {
+ .data = &f->regs[addr / 4],
+ .data_size = 4,
+ .access = rai,
+ };
+
+ trace_flexcomm_usart_reg_write(DEVICE(f)->id, rai->name, addr, value);
+
+ switch (addr) {
+ case A_FLEXCOMM_USART_INTENCLR:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+ REG(f, INTENSET) &= ~REG(f, INTENCLR);
+ break;
+ }
+ case A_FLEXCOMM_USART_FIFOCFG:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+ flexcomm_reset_fifos(f);
+ break;
+ }
+ case A_FLEXCOMM_USART_FIFOSTAT:
+ {
+ flexcomm_clear_fifostat(f, value);
+ break;
+ }
+ case A_FLEXCOMM_USART_FIFOINTENSET:
+ {
+ REG(f, FIFOINTENSET) |= value;
+ break;
+ }
+ case A_FLEXCOMM_USART_FIFOINTENCLR:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+ REG(f, FIFOINTENSET) &= ~value;
+ break;
+ }
+ case A_FLEXCOMM_USART_FIFOWR:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+
+ if (!fifo32_is_full(f->tx_fifo)) {
+ fifo32_push(f->tx_fifo, REG(f, FIFOWR));
+ }
+
+ if (!RF_WR(f, CFG, ENABLE) || !RF_WR(f, FIFOCFG, ENABLETX)) {
+ break;
+ }
+
+ while (!fifo32_is_empty(f->tx_fifo)) {
+ uint32_t val32 = fifo32_pop(f->tx_fifo);
+ uint8_t val8 = val32 & 0xff;
+
+ trace_flexcomm_usart_tx(DEVICE(f)->id);
+ qemu_chr_fe_write_all(&s->chr, &val8, sizeof(val8));
+ }
+ break;
+ }
+ case A_FLEXCOMM_USART_CFG:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+ break;
+ }
+ default:
+ register_write(&ri, value, ~0, NULL, false);
+ break;
+ }
+
+ flexcomm_usart_irq_update(f);
+
+ return MEMTX_OK;
+}
+
+static void flexcomm_usart_select(FlexcommFunction *f, bool selected)
+{
+ FlexcommUsartState *s = FLEXCOMM_USART(f);
+ FlexcommUsartClass *uc = FLEXCOMM_USART_GET_CLASS(f);
+
+ if (selected) {
+ qemu_chr_fe_set_handlers(&s->chr, flexcomm_usart_rx_space,
+ flexcomm_usart_rx, NULL, NULL,
+ s, NULL, true);
+ flexcomm_usart_reset(f);
+ } else {
+ qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL, NULL, NULL,
+ false);
+ }
+ uc->select(f, selected);
+}
+
+static const MemoryRegionOps flexcomm_usart_ops = {
+ .read_with_attrs = flexcomm_usart_reg_read,
+ .write_with_attrs = flexcomm_usart_reg_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ .unaligned = false,
+ },
+};
+
+static Property flexcomm_usart_properties[] = {
+ DEFINE_PROP_CHR("chardev", FlexcommUsartState, chr),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void flexcomm_usart_realize(DeviceState *dev, Error **errp)
+{
+ qdev_prop_set_chr(dev, "chardev", qemu_chr_find(dev->id));
+}
+
+static void flexcomm_usart_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_CLASS(klass);
+ FlexcommUsartClass *uc = FLEXCOMM_USART_CLASS(klass);
+
+ device_class_set_props(dc, flexcomm_usart_properties);
+ dc->realize = flexcomm_usart_realize;
+ uc->select = fc->select;
+ fc->select = flexcomm_usart_select;
+ fc->name = "usart";
+ fc->has_fifos = true;
+ fc->mmio_ops = &flexcomm_usart_ops;
+}
+
+static const TypeInfo flexcomm_usart_types[] = {
+ {
+ .name = TYPE_FLEXCOMM_USART,
+ .parent = TYPE_FLEXCOMM_FUNCTION,
+ .instance_size = sizeof(FlexcommUsartState),
+ .class_init = flexcomm_usart_class_init,
+ .class_size = sizeof(FlexcommUsartClass),
+ },
+};
+
+DEFINE_TYPES(flexcomm_usart_types);
diff --git a/hw/misc/flexcomm.c b/hw/misc/flexcomm.c
index a98d8845aa..a291148f27 100644
--- a/hw/misc/flexcomm.c
+++ b/hw/misc/flexcomm.c
@@ -23,6 +23,7 @@
#include "migration/vmstate.h"
#include "hw/misc/flexcomm.h"
#include "hw/arm/svd/flexcomm_usart.h"
+#include "hw/char/flexcomm_usart.h"
#define REG(s, reg) (s->regs[R_FLEXCOMM_##reg])
#define RF_WR(s, reg, field, val) \
@@ -218,6 +219,7 @@ static void flexcomm_init(Object *obj)
TYPE_FLEXCOMM, sizeof(s->regs));
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container);
sysbus_init_irq(sbd, &s->irq);
+ object_initialize_child(obj, "usart", &s->usart, TYPE_FLEXCOMM_USART);
}
static void flexcomm_finalize(Object *obj)
@@ -247,6 +249,7 @@ static void flexcomm_realize(DeviceState *dev, Error **errp)
FlexcommState *s = FLEXCOMM(dev);
memory_region_add_subregion_overlap(&s->container, 0, &s->mmio, -1);
+ flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->usart), errp);
}
static const VMStateDescription vmstate_flexcomm = {
diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build
index 4b0bbbbbdc..2bde34d15b 100644
--- a/hw/arm/svd/meson.build
+++ b/hw/arm/svd/meson.build
@@ -4,4 +4,7 @@ if get_option('mcux-soc-svd')
run_target('svd-flexcomm', command: svd_gen_header +
[ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm.h',
'-p', 'FLEXCOMM0', '-t', 'FLEXCOMM'])
+ run_target('svd-flexcomm-usart', command: svd_gen_header +
+ [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_usart.h',
+ '-p', 'USART0', '-t', 'FLEXCOMM_USART'])
endif
diff --git a/hw/char/meson.build b/hw/char/meson.build
index a4c4c5ff0f..761e4b817c 100644
--- a/hw/char/meson.build
+++ b/hw/char/meson.build
@@ -38,3 +38,4 @@ system_ss.add(when: 'CONFIG_GOLDFISH_TTY', if_true: files('goldfish_tty.c'))
specific_ss.add(when: 'CONFIG_TERMINAL3270', if_true: files('terminal3270.c'))
specific_ss.add(when: 'CONFIG_VIRTIO', if_true: files('virtio-serial-bus.c'))
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_vty.c'))
+system_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm_usart.c'))
diff --git a/hw/char/trace-events b/hw/char/trace-events
index 59e1f734a7..578551b388 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -125,3 +125,11 @@ xen_console_unrealize(unsigned int idx) "idx %u"
xen_console_realize(unsigned int idx, const char *chrdev) "idx %u chrdev %s"
xen_console_device_create(unsigned int idx) "idx %u"
xen_console_device_destroy(unsigned int idx) "idx %u"
+
+# flexcomm_usart.c
+flexcomm_usart_reg_read(const char *id, const char *reg_name, uint32_t addr, uint32_t val) " %s: %s[0x%04x] -> 0x%08x"
+flexcomm_usart_reg_write(const char *id, const char *reg_name, uint32_t addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x"
+flexcomm_usart_rx_space(const char *id, uint32_t rx) "%s: %d"
+flexcomm_usart_rx(const char *id) "%s"
+flexcomm_usart_tx(const char *id) "%s"
+flexcomm_usart_irq(const char *id, bool irq, bool fifoirqs, bool perirqs, bool enabled) "%s: %d %d %d %d"
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 08/25] hw/i2c: add support for flexcomm i2c
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (6 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 07/25] hw/char: add support for flexcomm usart Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 20:17 ` Corey Minyard
2024-09-18 19:22 ` [PATCH 09/25] hw/ssi: add support for flexcomm spi Octavian Purdila
` (16 subsequent siblings)
24 siblings, 1 reply; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add support for NXP's flexcomm i2c. It does not support slave mode or
DMA.
The patch includes an automatically generated header which contains
the register layout and helpers.
The header can be regenerated with the svd-flexcomm-i2c target when
the build is configured with --enable-mcux-soc-svd.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
include/hw/arm/svd/flexcomm_i2c.h | 1190 +++++++++++++++++++++++++++++
include/hw/i2c/flexcomm_i2c.h | 40 +
include/hw/misc/flexcomm.h | 2 +
hw/i2c/flexcomm_i2c.c | 250 ++++++
hw/misc/flexcomm.c | 3 +
hw/arm/svd/meson.build | 3 +
hw/i2c/meson.build | 1 +
hw/i2c/trace-events | 10 +
hw/misc/Kconfig | 1 +
9 files changed, 1500 insertions(+)
create mode 100644 include/hw/arm/svd/flexcomm_i2c.h
create mode 100644 include/hw/i2c/flexcomm_i2c.h
create mode 100644 hw/i2c/flexcomm_i2c.c
diff --git a/include/hw/arm/svd/flexcomm_i2c.h b/include/hw/arm/svd/flexcomm_i2c.h
new file mode 100644
index 0000000000..9017d48446
--- /dev/null
+++ b/include/hw/arm/svd/flexcomm_i2c.h
@@ -0,0 +1,1190 @@
+/*
+ * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
+ */
+#pragma once
+
+#include "hw/register.h"
+
+/* I2C Bus Interface */
+#define FLEXCOMM_I2C_REGS_NO (1024)
+
+/* Configuration Register */
+REG32(FLEXCOMM_I2C_CFG, 2048);
+/* Master Enable */
+FIELD(FLEXCOMM_I2C_CFG, MSTEN, 0, 1);
+/* Slave Enable */
+FIELD(FLEXCOMM_I2C_CFG, SLVEN, 1, 1);
+/* Monitor Enable */
+FIELD(FLEXCOMM_I2C_CFG, MONEN, 2, 1);
+/* I2C bus Time-out Enable */
+FIELD(FLEXCOMM_I2C_CFG, TIMEOUTEN, 3, 1);
+/* Monitor function Clock Stretching */
+FIELD(FLEXCOMM_I2C_CFG, MONCLKSTR, 4, 1);
+/* High Speed mode Capable enable */
+FIELD(FLEXCOMM_I2C_CFG, HSCAPABLE, 5, 1);
+
+/* Status Register */
+REG32(FLEXCOMM_I2C_STAT, 2052);
+/* Master Pending */
+FIELD(FLEXCOMM_I2C_STAT, MSTPENDING, 0, 1);
+/* Master State code */
+FIELD(FLEXCOMM_I2C_STAT, MSTSTATE, 1, 3);
+/* Master Arbitration Loss flag */
+FIELD(FLEXCOMM_I2C_STAT, MSTARBLOSS, 4, 1);
+/* Master Start/Stop Error flag */
+FIELD(FLEXCOMM_I2C_STAT, MSTSTSTPERR, 6, 1);
+/* Slave Pending */
+FIELD(FLEXCOMM_I2C_STAT, SLVPENDING, 8, 1);
+/* Slave State */
+FIELD(FLEXCOMM_I2C_STAT, SLVSTATE, 9, 2);
+/* Slave Not Stretching */
+FIELD(FLEXCOMM_I2C_STAT, SLVNOTSTR, 11, 1);
+/* Slave address match Index T */
+FIELD(FLEXCOMM_I2C_STAT, SLVIDX, 12, 2);
+/* Slave selected flag */
+FIELD(FLEXCOMM_I2C_STAT, SLVSEL, 14, 1);
+/* Slave Deselected flag */
+FIELD(FLEXCOMM_I2C_STAT, SLVDESEL, 15, 1);
+/* Monitor Ready */
+FIELD(FLEXCOMM_I2C_STAT, MONRDY, 16, 1);
+/* Monitor Overflow flag */
+FIELD(FLEXCOMM_I2C_STAT, MONOV, 17, 1);
+/* Monitor Active flag */
+FIELD(FLEXCOMM_I2C_STAT, MONACTIVE, 18, 1);
+/* Monitor Idle flag */
+FIELD(FLEXCOMM_I2C_STAT, MONIDLE, 19, 1);
+/* Event Time-out Interrupt flag */
+FIELD(FLEXCOMM_I2C_STAT, EVENTTIMEOUT, 24, 1);
+/* SCL Time-out Interrupt flag */
+FIELD(FLEXCOMM_I2C_STAT, SCLTIMEOUT, 25, 1);
+
+/* Interrupt Enable Set Register */
+REG32(FLEXCOMM_I2C_INTENSET, 2056);
+/* Master Pending interrupt Enable */
+FIELD(FLEXCOMM_I2C_INTENSET, MSTPENDINGEN, 0, 1);
+/* Master Arbitration Loss interrupt Enable */
+FIELD(FLEXCOMM_I2C_INTENSET, MSTARBLOSSEN, 4, 1);
+/* Master Start/Stop Error interrupt Enable */
+FIELD(FLEXCOMM_I2C_INTENSET, MSTSTSTPERREN, 6, 1);
+/* Slave Pending interrupt Enable */
+FIELD(FLEXCOMM_I2C_INTENSET, SLVPENDINGEN, 8, 1);
+/* Slave Not Stretching interrupt Enable */
+FIELD(FLEXCOMM_I2C_INTENSET, SLVNOTSTREN, 11, 1);
+/* Slave Deselect interrupt Enable */
+FIELD(FLEXCOMM_I2C_INTENSET, SLVDESELEN, 15, 1);
+/* Monitor data Ready interrupt Enable */
+FIELD(FLEXCOMM_I2C_INTENSET, MONRDYEN, 16, 1);
+/* Monitor Overrun interrupt Enable */
+FIELD(FLEXCOMM_I2C_INTENSET, MONOVEN, 17, 1);
+/* Monitor Idle interrupt Enable */
+FIELD(FLEXCOMM_I2C_INTENSET, MONIDLEEN, 19, 1);
+/* Event Time-out interrupt Enable */
+FIELD(FLEXCOMM_I2C_INTENSET, EVENTTIMEOUTEN, 24, 1);
+/* SCL Time-out interrupt Enable */
+FIELD(FLEXCOMM_I2C_INTENSET, SCLTIMEOUTEN, 25, 1);
+
+/* Interrupt Enable Clear Register */
+REG32(FLEXCOMM_I2C_INTENCLR, 2060);
+/* Master Pending interrupt clear */
+FIELD(FLEXCOMM_I2C_INTENCLR, MSTPENDINGCLR, 0, 1);
+/* Master Arbitration Loss interrupt clear */
+FIELD(FLEXCOMM_I2C_INTENCLR, MSTARBLOSSCLR, 4, 1);
+/* Master Start/Stop Error interrupt clear */
+FIELD(FLEXCOMM_I2C_INTENCLR, MSTSTSTPERRCLR, 6, 1);
+/* Slave Pending interrupt clear */
+FIELD(FLEXCOMM_I2C_INTENCLR, SLVPENDINGCLR, 8, 1);
+/* Slave Not Stretching interrupt clear */
+FIELD(FLEXCOMM_I2C_INTENCLR, SLVNOTSTRCLR, 11, 1);
+/* Slave Deselect interrupt clear */
+FIELD(FLEXCOMM_I2C_INTENCLR, SLVDESELCLR, 15, 1);
+/* Monitor data Ready interrupt clear */
+FIELD(FLEXCOMM_I2C_INTENCLR, MONRDYCLR, 16, 1);
+/* Monitor Overrun interrupt clear */
+FIELD(FLEXCOMM_I2C_INTENCLR, MONOVCLR, 17, 1);
+/* Monitor Idle interrupt clear */
+FIELD(FLEXCOMM_I2C_INTENCLR, MONIDLECLR, 19, 1);
+/* Event time-out interrupt clear */
+FIELD(FLEXCOMM_I2C_INTENCLR, EVENTTIMEOUTCLR, 24, 1);
+/* SCL time-out interrupt clear */
+FIELD(FLEXCOMM_I2C_INTENCLR, SCLTIMEOUTCLR, 25, 1);
+
+/* Time-out Register */
+REG32(FLEXCOMM_I2C_TIMEOUT, 2064);
+/* Time-out time value, the bottom 4 bits */
+FIELD(FLEXCOMM_I2C_TIMEOUT, TOMIN, 0, 4);
+/* Time-out time value */
+FIELD(FLEXCOMM_I2C_TIMEOUT, TO, 4, 12);
+
+/* Clock Divider Register */
+REG32(FLEXCOMM_I2C_CLKDIV, 2068);
+/* Divider Value */
+FIELD(FLEXCOMM_I2C_CLKDIV, DIVVAL, 0, 16);
+
+/* Interrupt Status Register */
+REG32(FLEXCOMM_I2C_INTSTAT, 2072);
+/* Master Pending */
+FIELD(FLEXCOMM_I2C_INTSTAT, MSTPENDING, 0, 1);
+/* Master Arbitration Loss flag */
+FIELD(FLEXCOMM_I2C_INTSTAT, MSTARBLOSS, 4, 1);
+/* Master Start/Stop Error flag */
+FIELD(FLEXCOMM_I2C_INTSTAT, MSTSTSTPERR, 6, 1);
+/* Slave Pending */
+FIELD(FLEXCOMM_I2C_INTSTAT, SLVPENDING, 8, 1);
+/* Slave Not Stretching status */
+FIELD(FLEXCOMM_I2C_INTSTAT, SLVNOTSTR, 11, 1);
+/* Slave Deselected flag */
+FIELD(FLEXCOMM_I2C_INTSTAT, SLVDESEL, 15, 1);
+/* Monitor Ready */
+FIELD(FLEXCOMM_I2C_INTSTAT, MONRDY, 16, 1);
+/* Monitor Overflow flag */
+FIELD(FLEXCOMM_I2C_INTSTAT, MONOV, 17, 1);
+/* Monitor Idle flag */
+FIELD(FLEXCOMM_I2C_INTSTAT, MONIDLE, 19, 1);
+/* Event Time-out Interrupt flag */
+FIELD(FLEXCOMM_I2C_INTSTAT, EVENTTIMEOUT, 24, 1);
+/* SCL Time-out Interrupt flag */
+FIELD(FLEXCOMM_I2C_INTSTAT, SCLTIMEOUT, 25, 1);
+
+/* Master Control Register */
+REG32(FLEXCOMM_I2C_MSTCTL, 2080);
+/* Master Continue(write-only) */
+FIELD(FLEXCOMM_I2C_MSTCTL, MSTCONTINUE, 0, 1);
+/* Master Start control(write-only) */
+FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTART, 1, 1);
+/* Master Stop control(write-only) */
+FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTOP, 2, 1);
+/* Master DMA enable */
+FIELD(FLEXCOMM_I2C_MSTCTL, MSTDMA, 3, 1);
+
+/* Master Timing Register */
+REG32(FLEXCOMM_I2C_MSTTIME, 2084);
+/* Master SCL Low time */
+FIELD(FLEXCOMM_I2C_MSTTIME, MSTSCLLOW, 0, 3);
+/* Master SCL High time */
+FIELD(FLEXCOMM_I2C_MSTTIME, MSTSCLHIGH, 4, 3);
+
+/* Master Data Register */
+REG32(FLEXCOMM_I2C_MSTDAT, 2088);
+/* Master function data register */
+FIELD(FLEXCOMM_I2C_MSTDAT, DATA, 0, 8);
+
+/* Slave Control Register */
+REG32(FLEXCOMM_I2C_SLVCTL, 2112);
+/* Slave Continue */
+FIELD(FLEXCOMM_I2C_SLVCTL, SLVCONTINUE, 0, 1);
+/* Slave NACK */
+FIELD(FLEXCOMM_I2C_SLVCTL, SLVNACK, 1, 1);
+/* Slave DMA enable */
+FIELD(FLEXCOMM_I2C_SLVCTL, SLVDMA, 3, 1);
+/* Automatic Acknowledge */
+FIELD(FLEXCOMM_I2C_SLVCTL, AUTOACK, 8, 1);
+/* Automatic Match Read */
+FIELD(FLEXCOMM_I2C_SLVCTL, AUTOMATCHREAD, 9, 1);
+
+/* Slave Data Register */
+REG32(FLEXCOMM_I2C_SLVDAT, 2116);
+/* Slave function data register */
+FIELD(FLEXCOMM_I2C_SLVDAT, DATA, 0, 8);
+
+/* Slave Address Register */
+REG32(FLEXCOMM_I2C_SLVADR0, 2120);
+/* Slave Address n Disable */
+FIELD(FLEXCOMM_I2C_SLVADR0, SADISABLE, 0, 1);
+/* Slave Address. */
+FIELD(FLEXCOMM_I2C_SLVADR0, SLVADR, 1, 7);
+/* Automatic NACK operation */
+FIELD(FLEXCOMM_I2C_SLVADR0, AUTONACK, 15, 1);
+
+/* Slave Address Register */
+REG32(FLEXCOMM_I2C_SLVADR1, 2124);
+/* Slave Address n Disable */
+FIELD(FLEXCOMM_I2C_SLVADR1, SADISABLE, 0, 1);
+/* Slave Address. */
+FIELD(FLEXCOMM_I2C_SLVADR1, SLVADR, 1, 7);
+/* Automatic NACK operation */
+FIELD(FLEXCOMM_I2C_SLVADR1, AUTONACK, 15, 1);
+
+/* Slave Address Register */
+REG32(FLEXCOMM_I2C_SLVADR2, 2128);
+/* Slave Address n Disable */
+FIELD(FLEXCOMM_I2C_SLVADR2, SADISABLE, 0, 1);
+/* Slave Address. */
+FIELD(FLEXCOMM_I2C_SLVADR2, SLVADR, 1, 7);
+/* Automatic NACK operation */
+FIELD(FLEXCOMM_I2C_SLVADR2, AUTONACK, 15, 1);
+
+/* Slave Address Register */
+REG32(FLEXCOMM_I2C_SLVADR3, 2132);
+/* Slave Address n Disable */
+FIELD(FLEXCOMM_I2C_SLVADR3, SADISABLE, 0, 1);
+/* Slave Address. */
+FIELD(FLEXCOMM_I2C_SLVADR3, SLVADR, 1, 7);
+/* Automatic NACK operation */
+FIELD(FLEXCOMM_I2C_SLVADR3, AUTONACK, 15, 1);
+
+/* Slave Qualification for Address 0 Register */
+REG32(FLEXCOMM_I2C_SLVQUAL0, 2136);
+/* Qualify mode for slave address 0 */
+FIELD(FLEXCOMM_I2C_SLVQUAL0, QUALMODE0, 0, 1);
+/* Slave address Qualifier for address 0 */
+FIELD(FLEXCOMM_I2C_SLVQUAL0, SLVQUAL0, 1, 7);
+
+/* Monitor Receiver Data Register */
+REG32(FLEXCOMM_I2C_MONRXDAT, 2176);
+/* Monitor function Receiver Data */
+FIELD(FLEXCOMM_I2C_MONRXDAT, MONRXDAT, 0, 8);
+/* Monitor Received Start */
+FIELD(FLEXCOMM_I2C_MONRXDAT, MONSTART, 8, 1);
+/* Monitor Received Repeated Start */
+FIELD(FLEXCOMM_I2C_MONRXDAT, MONRESTART, 9, 1);
+/* Monitor Received NACK */
+FIELD(FLEXCOMM_I2C_MONRXDAT, MONNACK, 10, 1);
+
+/* Peripheral Identification Register */
+REG32(FLEXCOMM_I2C_ID, 4092);
+/* Aperture */
+FIELD(FLEXCOMM_I2C_ID, APERTURE, 0, 8);
+/* Minor revision of module implementation */
+FIELD(FLEXCOMM_I2C_ID, MINOR_REV, 8, 4);
+/* Major revision of module implementation */
+FIELD(FLEXCOMM_I2C_ID, MAJOR_REV, 12, 4);
+/* Module identifier for the selected function */
+FIELD(FLEXCOMM_I2C_ID, ID, 16, 16);
+
+
+typedef enum {
+ /*
+ * Disabled. The I2C Master function is disabled. When disabled, the Master
+ * configuration settings are not changed, but the Master function is
+ * internally reset.
+ */
+ FLEXCOMM_I2C_CFG_MSTEN_DISABLED = 0,
+ /* Enabled. The I2C Master function is enabled. */
+ FLEXCOMM_I2C_CFG_MSTEN_ENABLED = 1,
+} FLEXCOMM_I2C_CFG_MSTEN_Enum;
+
+typedef enum {
+ /*
+ * Disabled. The I2C slave function is disabled. When disabled, the Slave
+ * configuration settings are not changed, but the Slave function is
+ * internally reset.
+ */
+ FLEXCOMM_I2C_CFG_SLVEN_DISABLED = 0,
+ /* Enabled. The I2C slave function is enabled. */
+ FLEXCOMM_I2C_CFG_SLVEN_ENABLED = 1,
+} FLEXCOMM_I2C_CFG_SLVEN_Enum;
+
+typedef enum {
+ /*
+ * Disabled. The I2C Monitor function is disabled. When disabled, the
+ * Monitor function configuration settings are not changed, but the Monitor
+ * function is internally reset.
+ */
+ FLEXCOMM_I2C_CFG_MONEN_DISABLED = 0,
+ /* Enabled. The I2C Monitor function is enabled. */
+ FLEXCOMM_I2C_CFG_MONEN_ENABLED = 1,
+} FLEXCOMM_I2C_CFG_MONEN_Enum;
+
+typedef enum {
+ /*
+ * Disabled. The time-out function is disabled. When disabled, the time-out
+ * function is internally reset.
+ */
+ FLEXCOMM_I2C_CFG_TIMEOUTEN_DISABLED = 0,
+ /*
+ * Enabled. The time-out function is enabled. Both types of time-out flags
+ * will be generated and will cause interrupts if those flags are enabled.
+ * Typically, only one time-out flag will be used in a system.
+ */
+ FLEXCOMM_I2C_CFG_TIMEOUTEN_ENABLED = 1,
+} FLEXCOMM_I2C_CFG_TIMEOUTEN_Enum;
+
+typedef enum {
+ /*
+ * Disabled. The Monitor function will not perform clock stretching.
+ * Software or DMA may not always be able to read data provided by the
+ * Monitor function before it (the data) is overwritten. This mode can be
+ * used when non-invasive monitoring is critical.
+ */
+ FLEXCOMM_I2C_CFG_MONCLKSTR_DISABLED = 0,
+ /*
+ * Enabled. The Monitor function will perform clock stretching, to ensure
+ * that the software or DMA can read all incoming data supplied by the
+ * Monitor function.
+ */
+ FLEXCOMM_I2C_CFG_MONCLKSTR_ENABLED = 1,
+} FLEXCOMM_I2C_CFG_MONCLKSTR_Enum;
+
+typedef enum {
+ /* Fast mode Plus enable */
+ FLEXCOMM_I2C_CFG_HSCAPABLE_FAST_MODE_PLUS = 0,
+ /* High Speed mode enable */
+ FLEXCOMM_I2C_CFG_HSCAPABLE_HIGH_SPEED = 1,
+} FLEXCOMM_I2C_CFG_HSCAPABLE_Enum;
+
+typedef enum {
+ /*
+ * In progress. Communication is in progress and the Master function is
+ * busy and cannot currently accept a command.
+ */
+ FLEXCOMM_I2C_STAT_MSTPENDING_IN_PROGRESS = 0,
+ /*
+ * Pending. The Master function needs software service or is in the idle
+ * state. If the master is not in the idle state, then the master is
+ * waiting to receive or transmit data, or is waiting for the NACK bit.
+ */
+ FLEXCOMM_I2C_STAT_MSTPENDING_PENDING = 1,
+} FLEXCOMM_I2C_STAT_MSTPENDING_Enum;
+
+typedef enum {
+ /*
+ * Idle. The Master function is available to be used for a new transaction.
+ */
+ FLEXCOMM_I2C_STAT_MSTSTATE_IDLE = 0,
+ /*
+ * Receive ready. Received data is available (in Master Receiver mode).
+ * Address plus Read was previously sent and Acknowledged by a slave.
+ */
+ FLEXCOMM_I2C_STAT_MSTSTATE_RECEIVE_READY = 1,
+ /*
+ * Transmit ready. Data can be transmitted (in Master Transmitter mode).
+ * Address plus Write was previously sent and Acknowledged by a slave.
+ */
+ FLEXCOMM_I2C_STAT_MSTSTATE_TRANSMIT_READY = 2,
+ /* NACK Address. Slave NACKed address. */
+ FLEXCOMM_I2C_STAT_MSTSTATE_NACK_ADDRESS = 3,
+ /* NACK Data. Slave NACKed transmitted data. */
+ FLEXCOMM_I2C_STAT_MSTSTATE_NACK_DATA = 4,
+} FLEXCOMM_I2C_STAT_MSTSTATE_Enum;
+
+typedef enum {
+ /* No Arbitration Loss has occurred */
+ FLEXCOMM_I2C_STAT_MSTARBLOSS_NO_LOSS = 0,
+ /*
+ * Arbitration loss. The Master function has experienced an Arbitration
+ * Loss. At this point, the Master function has already stopped driving the
+ * bus and has gone into an idle state. Software can respond by doing
+ * nothing, or by sending a Start (to attempt to gain control of the bus
+ * when the bus next becomes idle).
+ */
+ FLEXCOMM_I2C_STAT_MSTARBLOSS_ARBITRATION_LOSS = 1,
+} FLEXCOMM_I2C_STAT_MSTARBLOSS_Enum;
+
+typedef enum {
+ /* No Start/Stop Error has occurred. */
+ FLEXCOMM_I2C_STAT_MSTSTSTPERR_NO_ERROR = 0,
+ /*
+ * The Master function has experienced a Start/Stop Error. A Start or Stop
+ * was detected at a time when Start or Stop is not allowed by the I2C
+ * specification. The Master interface has stopped driving the bus and gone
+ * into an idle state; no action is required. A request for a Start could
+ * be made, or software could attempt to make sure that the bus has not
+ * stalled.
+ */
+ FLEXCOMM_I2C_STAT_MSTSTSTPERR_ERROR = 1,
+} FLEXCOMM_I2C_STAT_MSTSTSTPERR_Enum;
+
+typedef enum {
+ /*
+ * In progress. The Slave function does not currently need software
+ * service.
+ */
+ FLEXCOMM_I2C_STAT_SLVPENDING_IN_PROGRESS = 0,
+ /*
+ * Pending. The Slave function needs software service. Information about
+ * what is needed is in the Slave state field (SLVSTATE).
+ */
+ FLEXCOMM_I2C_STAT_SLVPENDING_PENDING = 1,
+} FLEXCOMM_I2C_STAT_SLVPENDING_Enum;
+
+typedef enum {
+ /*
+ * Slave address. Address plus R/W received. At least one of the 4 slave
+ * addresses has been matched by hardware.
+ */
+ FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_ADDRESS = 0,
+ /* Slave receive. Received data is available (in Slave Receiver mode). */
+ FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_RECEIVE = 1,
+ /* Slave transmit. Data can be transmitted (in Slave Transmitter mode). */
+ FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_TRANSMIT = 2,
+} FLEXCOMM_I2C_STAT_SLVSTATE_Enum;
+
+typedef enum {
+ /*
+ * Stretching. The slave function is currently stretching the I2C bus
+ * clock. Deep-Sleepmode cannot be entered at this time.
+ */
+ FLEXCOMM_I2C_STAT_SLVNOTSTR_STRETCHING = 0,
+ /*
+ * Not stretching. The slave function is not currently stretching the I2C
+ * bus clock. Deep-sleep mode can be entered at this time.
+ */
+ FLEXCOMM_I2C_STAT_SLVNOTSTR_NOT_STRETCHING = 1,
+} FLEXCOMM_I2C_STAT_SLVNOTSTR_Enum;
+
+typedef enum {
+ /* Address 0. Slave address 0 was matched. */
+ FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS0 = 0,
+ /* Address 1. Slave address 1 was matched. */
+ FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS1 = 1,
+ /* Address 2. Slave address 2 was matched. */
+ FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS2 = 2,
+ /* Address 3. Slave address 3 was matched. */
+ FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS3 = 3,
+} FLEXCOMM_I2C_STAT_SLVIDX_Enum;
+
+typedef enum {
+ /* Not selected. The Slave function is not currently selected. */
+ FLEXCOMM_I2C_STAT_SLVSEL_NOT_SELECTED = 0,
+ /* Selected. The Slave function is currently selected. */
+ FLEXCOMM_I2C_STAT_SLVSEL_SELECTED = 1,
+} FLEXCOMM_I2C_STAT_SLVSEL_Enum;
+
+typedef enum {
+ /*
+ * Not deselected. The Slave function has not become deselected. This does
+ * not mean that the Slave is currently selected. That information is in
+ * the SLVSEL flag.
+ */
+ FLEXCOMM_I2C_STAT_SLVDESEL_NOT_DESELECTED = 0,
+ /*
+ * Deselected. The Slave function has become deselected. This is
+ * specifically caused by the SLVSEL flag changing from 1 to 0. See SLVSEL
+ * for details about when that event occurs.
+ */
+ FLEXCOMM_I2C_STAT_SLVDESEL_DESELECTED = 1,
+} FLEXCOMM_I2C_STAT_SLVDESEL_Enum;
+
+typedef enum {
+ /* No data. The Monitor function does not currently have data available. */
+ FLEXCOMM_I2C_STAT_MONRDY_NO_DATA = 0,
+ /* Data waiting. The Monitor function has data waiting to be read. */
+ FLEXCOMM_I2C_STAT_MONRDY_DATA_WAITING = 1,
+} FLEXCOMM_I2C_STAT_MONRDY_Enum;
+
+typedef enum {
+ /* No overrun. Monitor data has not overrun. */
+ FLEXCOMM_I2C_STAT_MONOV_NO_OVERRUN = 0,
+ /*
+ * Overrun. A Monitor data overrun has occurred. An overrun can only happen
+ * when Monitor clock stretching not enabled via the CFG[MONCLKSTR] bit.
+ * Writing 1 to MONOV bit clears the MONOV flag.
+ */
+ FLEXCOMM_I2C_STAT_MONOV_OVERRUN = 1,
+} FLEXCOMM_I2C_STAT_MONOV_Enum;
+
+typedef enum {
+ /* Inactive. The Monitor function considers the I2C bus to be inactive. */
+ FLEXCOMM_I2C_STAT_MONACTIVE_INACTIVE = 0,
+ /* Active. The Monitor function considers the I2C bus to be active. */
+ FLEXCOMM_I2C_STAT_MONACTIVE_ACTIVE = 1,
+} FLEXCOMM_I2C_STAT_MONACTIVE_Enum;
+
+typedef enum {
+ /*
+ * Not idle. The I2C bus is not idle, or MONIDLE flag has been cleared by
+ * software.
+ */
+ FLEXCOMM_I2C_STAT_MONIDLE_NOT_IDLE = 0,
+ /*
+ * Idle. The I2C bus has gone idle at least once, since the last time
+ * MONIDLE flag was cleared by software.
+ */
+ FLEXCOMM_I2C_STAT_MONIDLE_IDLE = 1,
+} FLEXCOMM_I2C_STAT_MONIDLE_Enum;
+
+typedef enum {
+ /* No time-out. I2C bus events have not caused a time-out. */
+ FLEXCOMM_I2C_STAT_EVENTTIMEOUT_NO_TIMEOUT = 0,
+ /*
+ * Event time-out. The time between I2C bus events has been longer than the
+ * time specified by the TIMEOUT register.
+ */
+ FLEXCOMM_I2C_STAT_EVENTTIMEOUT_EVEN_TIMEOUT = 1,
+} FLEXCOMM_I2C_STAT_EVENTTIMEOUT_Enum;
+
+typedef enum {
+ /* No time-out. SCL low time has not caused a time-out. */
+ FLEXCOMM_I2C_STAT_SCLTIMEOUT_NO_TIMEOUT = 0,
+ /* Time-out. SCL low time has caused a time-out. */
+ FLEXCOMM_I2C_STAT_SCLTIMEOUT_TIMEOUT = 1,
+} FLEXCOMM_I2C_STAT_SCLTIMEOUT_Enum;
+
+typedef enum {
+ /* Disabled. The MstPending interrupt is disabled. */
+ FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_DISABLED = 0,
+ /* Enabled. The MstPending interrupt is enabled. */
+ FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_ENABLED = 1,
+} FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_Enum;
+
+typedef enum {
+ /* Disabled. The MstArbLoss interrupt is disabled. */
+ FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_DISABLED = 0,
+ /* Enabled. The MstArbLoss interrupt is enabled. */
+ FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_ENABLED = 1,
+} FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_Enum;
+
+typedef enum {
+ /* Disabled. The MstStStpErr interrupt is disabled. */
+ FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_DISABLED = 0,
+ /* Enabled. The MstStStpErr interrupt is enabled. */
+ FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_ENABLED = 1,
+} FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_Enum;
+
+typedef enum {
+ /* Disabled. The SlvPending interrupt is disabled. */
+ FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_DISABLED = 0,
+ /* Enabled. The SlvPending interrupt is enabled. */
+ FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_ENABLED = 1,
+} FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_Enum;
+
+typedef enum {
+ /* Disabled. The SlvNotStr interrupt is disabled. */
+ FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_DISABLED = 0,
+ /* Enabled. The SlvNotStr interrupt is enabled. */
+ FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_ENABLED = 1,
+} FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_Enum;
+
+typedef enum {
+ /* Disabled. The SlvDeSel interrupt is disabled. */
+ FLEXCOMM_I2C_INTENSET_SLVDESELEN_DISABLED = 0,
+ /* Enabled. The SlvDeSel interrupt is enabled. */
+ FLEXCOMM_I2C_INTENSET_SLVDESELEN_ENABLED = 1,
+} FLEXCOMM_I2C_INTENSET_SLVDESELEN_Enum;
+
+typedef enum {
+ /* Disabled. The MonRdy interrupt is disabled. */
+ FLEXCOMM_I2C_INTENSET_MONRDYEN_DISABLED = 0,
+ /* Enabled. The MonRdy interrupt is enabled. */
+ FLEXCOMM_I2C_INTENSET_MONRDYEN_ENABLED = 1,
+} FLEXCOMM_I2C_INTENSET_MONRDYEN_Enum;
+
+typedef enum {
+ /* Disabled. The MonOv interrupt is disabled. */
+ FLEXCOMM_I2C_INTENSET_MONOVEN_DISABLED = 0,
+ /* Enabled. The MonOv interrupt is enabled. */
+ FLEXCOMM_I2C_INTENSET_MONOVEN_ENABLED = 1,
+} FLEXCOMM_I2C_INTENSET_MONOVEN_Enum;
+
+typedef enum {
+ /* Disabled. The MonIdle interrupt is disabled. */
+ FLEXCOMM_I2C_INTENSET_MONIDLEEN_DISABLED = 0,
+ /* Enabled. The MonIdle interrupt is enabled. */
+ FLEXCOMM_I2C_INTENSET_MONIDLEEN_ENABLED = 1,
+} FLEXCOMM_I2C_INTENSET_MONIDLEEN_Enum;
+
+typedef enum {
+ /* Disabled. The Event time-out interrupt is disabled. */
+ FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_DISABLED = 0,
+ /* Enabled. The Event time-out interrupt is enabled. */
+ FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_ENABLED = 1,
+} FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_Enum;
+
+typedef enum {
+ /* Disabled. The SCL time-out interrupt is disabled. */
+ FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_DISABLED = 0,
+ /* Enabled. The SCL time-out interrupt is enabled. */
+ FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_ENABLED = 1,
+} FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_Enum;
+
+typedef enum {
+ /* No effect on interrupt */
+ FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_NO_EFFECT = 0,
+ /* Clears the interrupt bit in INTENSET register */
+ FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_CLEAR_MSTPENDING = 1,
+} FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_Enum;
+
+typedef enum {
+ /* No effect on interrupt */
+ FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_NO_EFFECT = 0,
+ /* Clears the interrupt bit in INTENSET register */
+ FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_CLEAR_MSTARBLOSS = 1,
+} FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_Enum;
+
+typedef enum {
+ /* No effect on interrupt */
+ FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_NO_EFFECT = 0,
+ /* Clears the interrupt bit in INTENSET register */
+ FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_CLEAR_MSTSTSTPERR = 1,
+} FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_Enum;
+
+typedef enum {
+ /* No effect on interrupt */
+ FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_NO_EFFECT = 0,
+ /* Clears the interrupt bit in INTENSET register */
+ FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_CLEAR_SLVPENDING = 1,
+} FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_Enum;
+
+typedef enum {
+ /* No effect on interrupt */
+ FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_NO_EFFECT = 0,
+ /* Clears the interrupt bit in INTENSET register */
+ FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_CLEAR_SLVNOTSTR = 1,
+} FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_Enum;
+
+typedef enum {
+ /* No effect on interrupt */
+ FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_NO_EFFECT = 0,
+ /* Clears the interrupt bit in INTENSET register */
+ FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_CLEAR_SLVDESEL = 1,
+} FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_Enum;
+
+typedef enum {
+ /* No effect on interrupt */
+ FLEXCOMM_I2C_INTENCLR_MONRDYCLR_NO_EFFECT = 0,
+ /* Clears the interrupt bit in INTENSET register */
+ FLEXCOMM_I2C_INTENCLR_MONRDYCLR_CLEAR_MONRDY = 1,
+} FLEXCOMM_I2C_INTENCLR_MONRDYCLR_Enum;
+
+typedef enum {
+ /* No effect on interrupt */
+ FLEXCOMM_I2C_INTENCLR_MONOVCLR_NO_EFFECT = 0,
+ /* Clears the interrupt bit in INTENSET register */
+ FLEXCOMM_I2C_INTENCLR_MONOVCLR_CLEAR_MONOV = 1,
+} FLEXCOMM_I2C_INTENCLR_MONOVCLR_Enum;
+
+typedef enum {
+ /* No effect on interrupt */
+ FLEXCOMM_I2C_INTENCLR_MONIDLECLR_NO_EFFECT = 0,
+ /* Clears the interrupt bit in INTENSET register */
+ FLEXCOMM_I2C_INTENCLR_MONIDLECLR_CLEAR_MONIDLE = 1,
+} FLEXCOMM_I2C_INTENCLR_MONIDLECLR_Enum;
+
+typedef enum {
+ /* No effect on interrupt */
+ FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_NO_EFFECT = 0,
+ /* Clears the interrupt bit in INTENSET register */
+ FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_CLEAR_EVENTTIMEOUT = 1,
+} FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_Enum;
+
+typedef enum {
+ /* No effect on interrupt */
+ FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_NO_EFFECT = 0,
+ /* Clears the interrupt bit in INTENSET register */
+ FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_CLEAR_SCLTIMEOUT = 1,
+} FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_Enum;
+
+typedef enum {
+ /* A time-out will occur after 16 counts of the I2C function clock. */
+ FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT16 = 0,
+ /* A time-out will occur after 32 counts of the I2C function clock. */
+ FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT32 = 1,
+ /* A time-out will occur after 65,536 counts of the I2C function clock. */
+ FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT65K = 4095,
+} FLEXCOMM_I2C_TIMEOUT_TO_Enum;
+
+typedef enum {
+ /* FCLK is used directly by the I2C. */
+ FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKUNDIVIDED = 0,
+ /* FCLK is divided by 2 before being used by the I2C. */
+ FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV2 = 1,
+ /* FCLK is divided by 3 before being used by the I2C. */
+ FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV3 = 2,
+ /* FCLK is divided by 65,536 before being used by the I2C. */
+ FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV65K = 65535,
+} FLEXCOMM_I2C_CLKDIV_DIVVAL_Enum;
+
+typedef enum {
+ /* Not active */
+ FLEXCOMM_I2C_INTSTAT_MSTPENDING_MSTPENDING_ISNOTACTIVE = 0,
+ /* Active */
+ FLEXCOMM_I2C_INTSTAT_MSTPENDING_MSTPENDING_ISACTIVE = 1,
+} FLEXCOMM_I2C_INTSTAT_MSTPENDING_Enum;
+
+typedef enum {
+ /* Not active */
+ FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_MSTARBLOSS_ISNOTACTIVE = 0,
+ /* Active */
+ FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_MSTARBLOSS_ISACTIVE = 1,
+} FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_Enum;
+
+typedef enum {
+ /* Not active */
+ FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_MSTSTSTPERR_ISNOTACTIVE = 0,
+ /* Active */
+ FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_MSTSTSTPERR_ISACTIVE = 1,
+} FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_Enum;
+
+typedef enum {
+ /* Not active */
+ FLEXCOMM_I2C_INTSTAT_SLVPENDING_SLVPENDING_ISNOTACTIVE = 0,
+ /* Active */
+ FLEXCOMM_I2C_INTSTAT_SLVPENDING_SLVPENDING_ISACTIVE = 1,
+} FLEXCOMM_I2C_INTSTAT_SLVPENDING_Enum;
+
+typedef enum {
+ /* Not active */
+ FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_SLVNOTSTR_ISNOTACTIVE = 0,
+ /* Active */
+ FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_SLVNOTSTR_ISACTIVE = 1,
+} FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_Enum;
+
+typedef enum {
+ /* Not active */
+ FLEXCOMM_I2C_INTSTAT_SLVDESEL_SLVDESEL_ISNOTACTIVE = 0,
+ /* Active */
+ FLEXCOMM_I2C_INTSTAT_SLVDESEL_SLVDESEL_ISACTIVE = 1,
+} FLEXCOMM_I2C_INTSTAT_SLVDESEL_Enum;
+
+typedef enum {
+ /* Not active */
+ FLEXCOMM_I2C_INTSTAT_MONRDY_MONRDY_ISNOTACTIVE = 0,
+ /* Active */
+ FLEXCOMM_I2C_INTSTAT_MONRDY_MONRDY_ISACTIVE = 1,
+} FLEXCOMM_I2C_INTSTAT_MONRDY_Enum;
+
+typedef enum {
+ /* Not active */
+ FLEXCOMM_I2C_INTSTAT_MONOV_MONOV_ISNOTACTIVE = 0,
+ /* Active */
+ FLEXCOMM_I2C_INTSTAT_MONOV_MONOV_ISACTIVE = 1,
+} FLEXCOMM_I2C_INTSTAT_MONOV_Enum;
+
+typedef enum {
+ /* Not active */
+ FLEXCOMM_I2C_INTSTAT_MONIDLE_MONIDLE_ISNOTACTIVE = 0,
+ /* Active */
+ FLEXCOMM_I2C_INTSTAT_MONIDLE_MONIDLE_ISACTIVE = 1,
+} FLEXCOMM_I2C_INTSTAT_MONIDLE_Enum;
+
+typedef enum {
+ /* Not active */
+ FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_EVENTTIMEOUT_ISNOTACTIVE = 0,
+ /* Active */
+ FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_EVENTTIMEOUT_ISACTIVE = 1,
+} FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_Enum;
+
+typedef enum {
+ /* Not active */
+ FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_SCLTIMEOUT_ISNOTACTIVE = 0,
+ /* Active */
+ FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_SCLTIMEOUT_ISACTIVE = 1,
+} FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_NO_EFFECT = 0,
+ /*
+ * Continue. Informs the Master function to continue to the next operation.
+ * This action must done after writing transmit data, reading received
+ * data, or any other housekeeping related to the next bus operation.
+ */
+ FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_CONTINUE = 1,
+} FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_I2C_MSTCTL_MSTSTART_NO_EFFECT = 0,
+ /*
+ * Start. A Start will be generated on the I2C bus at the next allowed
+ * time.
+ */
+ FLEXCOMM_I2C_MSTCTL_MSTSTART_START = 1,
+} FLEXCOMM_I2C_MSTCTL_MSTSTART_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_I2C_MSTCTL_MSTSTOP_NO_EFFECT = 0,
+ /*
+ * Stop. A Stop will be generated on the I2C bus at the next allowed time,
+ * preceded by a NACK to the slave if the master is receiving data from the
+ * slave (in Master Receiver mode).
+ */
+ FLEXCOMM_I2C_MSTCTL_MSTSTOP_STOP = 1,
+} FLEXCOMM_I2C_MSTCTL_MSTSTOP_Enum;
+
+typedef enum {
+ /* Disable. No DMA requests are generated for master operation. */
+ FLEXCOMM_I2C_MSTCTL_MSTDMA_DISABLED = 0,
+ /*
+ * Enable. A DMA request is generated for I2C master data operations. When
+ * this I2C master is generating Acknowledge bits in Master Receiver mode,
+ * the acknowledge is generated automatically.
+ */
+ FLEXCOMM_I2C_MSTCTL_MSTDMA_ENABLED = 1,
+} FLEXCOMM_I2C_MSTCTL_MSTDMA_Enum;
+
+typedef enum {
+ /*
+ * 2 clocks. Minimum SCL low time is 2 clocks of the I2C clock pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_2CLOCKS = 0,
+ /*
+ * 3 clocks. Minimum SCL low time is 3 clocks of the I2C clock pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_3CLOCKS = 1,
+ /*
+ * 4 clocks. Minimum SCL low time is 4 clocks of the I2C clock pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_4CLOCKS = 2,
+ /*
+ * 5 clocks. Minimum SCL low time is 5 clocks of the I2C clock pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_5CLOCKS = 3,
+ /*
+ * 6 clocks. Minimum SCL low time is 6 clocks of the I2C clock pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_6CLOCKS = 4,
+ /*
+ * 7 clocks. Minimum SCL low time is 7 clocks of the I2C clock pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_7CLOCKS = 5,
+ /*
+ * 8 clocks. Minimum SCL low time is 8 clocks of the I2C clock pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_8CLOCKS = 6,
+ /*
+ * 9 clocks. Minimum SCL low time is 9 clocks of the I2C clock pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_9CLOCKS = 7,
+} FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_Enum;
+
+typedef enum {
+ /*
+ * 2 clocks. Minimum SCL high time is 2 clocks of the I2C clock
+ * pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_2CLOCKS = 0,
+ /*
+ * 3 clocks. Minimum SCL high time is 3 clocks of the I2C clock pre-divider
+ * .
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_3CLOCKS = 1,
+ /*
+ * 4 clocks. Minimum SCL high time is 4 clocks of the I2C clock
+ * pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_4CLOCKS = 2,
+ /*
+ * 5 clocks. Minimum SCL high time is 5 clocks of the I2C clock
+ * pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_5CLOCKS = 3,
+ /*
+ * 6 clocks. Minimum SCL high time is 6 clocks of the I2C clock
+ * pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_6CLOCKS = 4,
+ /*
+ * 7 clocks. Minimum SCL high time is 7 clocks of the I2C clock
+ * pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_7CLOCKS = 5,
+ /*
+ * 8 clocks. Minimum SCL high time is 8 clocks of the I2C clock
+ * pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_8CLOCKS = 6,
+ /*
+ * 9 clocks. Minimum SCL high time is 9 clocks of the I2C clock
+ * pre-divider.
+ */
+ FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_9CLOCKS = 7,
+} FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_NO_EFFECT = 0,
+ /*
+ * Continue. Informs the Slave function to continue to the next operation,
+ * by clearing the STAT[SLVPENDING] flag. This must be done after writing
+ * transmit data, reading received data, or any other housekeeping related
+ * to the next bus operation. Automatic Operation has different
+ * requirements. SLVCONTINUE should not be set unless SLVPENDING = 1.
+ */
+ FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_CONTINUE = 1,
+} FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_I2C_SLVCTL_SLVNACK_NO_EFFECT = 0,
+ /*
+ * NACK. Causes the Slave function to NACK the master when the slave is
+ * receiving data from the master (in Slave Receiver mode).
+ */
+ FLEXCOMM_I2C_SLVCTL_SLVNACK_NACK = 1,
+} FLEXCOMM_I2C_SLVCTL_SLVNACK_Enum;
+
+typedef enum {
+ /* Disabled. No DMA requests are issued for Slave mode operation. */
+ FLEXCOMM_I2C_SLVCTL_SLVDMA_DISABLED = 0,
+ /*
+ * Enabled. DMA requests are issued for I2C slave data transmission and
+ * reception.
+ */
+ FLEXCOMM_I2C_SLVCTL_SLVDMA_ENABLED = 1,
+} FLEXCOMM_I2C_SLVCTL_SLVDMA_Enum;
+
+typedef enum {
+ /*
+ * Normal, non-automatic operation. If AUTONACK = 0, then a SlvPending
+ * interrupt is generated when a matching address is received. If AUTONACK
+ * = 1, then received addresses are NACKed (ignored).
+ */
+ FLEXCOMM_I2C_SLVCTL_AUTOACK_NORMAL = 0,
+ /*
+ * A header with matching SLVADR0 and matching direction as set by
+ * AUTOMATCHREAD will be ACKed immediately, allowing the master to move on
+ * to the data bytes. If the address matches SLVADR0, but the direction
+ * does not match AUTOMATCHREAD, then the behavior will depend on the
+ * SLVADR0[AUTONACK] bit: if AUTONACK is set, then it will be Nacked; if
+ * AUTONACK is clear, then a SlvPending interrupt is generated.
+ */
+ FLEXCOMM_I2C_SLVCTL_AUTOACK_AUTOMATIC_ACK = 1,
+} FLEXCOMM_I2C_SLVCTL_AUTOACK_Enum;
+
+typedef enum {
+ /* In Automatic Mode, the expected next operation is an I2C write. */
+ FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_I2C_WRITE = 0,
+ /* In Automatic Mode, the expected next operation is an I2C read. */
+ FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_I2C_READ = 1,
+} FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_Enum;
+
+typedef enum {
+ /* Enabled. Slave Address n is enabled. */
+ FLEXCOMM_I2C_SLVADR0_SADISABLE_ENABLED = 0,
+ /* Ignored. Slave Address n is ignored. */
+ FLEXCOMM_I2C_SLVADR0_SADISABLE_DISABLED = 1,
+} FLEXCOMM_I2C_SLVADR0_SADISABLE_Enum;
+
+typedef enum {
+ /* Normal operation, matching I2C addresses are not ignored. */
+ FLEXCOMM_I2C_SLVADR0_AUTONACK_NORMAL = 0,
+ /*
+ * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
+ * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
+ * matches the direction.
+ */
+ FLEXCOMM_I2C_SLVADR0_AUTONACK_AUTOMATIC = 1,
+} FLEXCOMM_I2C_SLVADR0_AUTONACK_Enum;
+
+typedef enum {
+ /* Enabled. Slave Address n is enabled. */
+ FLEXCOMM_I2C_SLVADR1_SADISABLE_ENABLED = 0,
+ /* Ignored. Slave Address n is ignored. */
+ FLEXCOMM_I2C_SLVADR1_SADISABLE_DISABLED = 1,
+} FLEXCOMM_I2C_SLVADR1_SADISABLE_Enum;
+
+typedef enum {
+ /* Normal operation, matching I2C addresses are not ignored. */
+ FLEXCOMM_I2C_SLVADR1_AUTONACK_NORMAL = 0,
+ /*
+ * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
+ * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
+ * matches the direction.
+ */
+ FLEXCOMM_I2C_SLVADR1_AUTONACK_AUTOMATIC = 1,
+} FLEXCOMM_I2C_SLVADR1_AUTONACK_Enum;
+
+typedef enum {
+ /* Enabled. Slave Address n is enabled. */
+ FLEXCOMM_I2C_SLVADR2_SADISABLE_ENABLED = 0,
+ /* Ignored. Slave Address n is ignored. */
+ FLEXCOMM_I2C_SLVADR2_SADISABLE_DISABLED = 1,
+} FLEXCOMM_I2C_SLVADR2_SADISABLE_Enum;
+
+typedef enum {
+ /* Normal operation, matching I2C addresses are not ignored. */
+ FLEXCOMM_I2C_SLVADR2_AUTONACK_NORMAL = 0,
+ /*
+ * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
+ * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
+ * matches the direction.
+ */
+ FLEXCOMM_I2C_SLVADR2_AUTONACK_AUTOMATIC = 1,
+} FLEXCOMM_I2C_SLVADR2_AUTONACK_Enum;
+
+typedef enum {
+ /* Enabled. Slave Address n is enabled. */
+ FLEXCOMM_I2C_SLVADR3_SADISABLE_ENABLED = 0,
+ /* Ignored. Slave Address n is ignored. */
+ FLEXCOMM_I2C_SLVADR3_SADISABLE_DISABLED = 1,
+} FLEXCOMM_I2C_SLVADR3_SADISABLE_Enum;
+
+typedef enum {
+ /* Normal operation, matching I2C addresses are not ignored. */
+ FLEXCOMM_I2C_SLVADR3_AUTONACK_NORMAL = 0,
+ /*
+ * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
+ * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
+ * matches the direction.
+ */
+ FLEXCOMM_I2C_SLVADR3_AUTONACK_AUTOMATIC = 1,
+} FLEXCOMM_I2C_SLVADR3_AUTONACK_Enum;
+
+typedef enum {
+ /*
+ * Mask. The SLVQUAL0 field is used as a logical mask for matching address
+ * 0.
+ */
+ FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_MASK = 0,
+ /*
+ * Extend. The SLVQUAL0 field is used to extend address 0 matching in a
+ * range of addresses.
+ */
+ FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_EXTEND = 1,
+} FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_Enum;
+
+typedef enum {
+ /*
+ * No start detected. The Monitor function has not detected a Start event
+ * on the I2C bus.
+ */
+ FLEXCOMM_I2C_MONRXDAT_MONSTART_NO_START_DETECTED = 0,
+ /*
+ * Start detected. The Monitor function has detected a Start event on the
+ * I2C bus.
+ */
+ FLEXCOMM_I2C_MONRXDAT_MONSTART_START_DETECTED = 1,
+} FLEXCOMM_I2C_MONRXDAT_MONSTART_Enum;
+
+typedef enum {
+ /*
+ * No repeated start detected. The Monitor function has not detected a
+ * Repeated Start event on the I2C bus.
+ */
+ FLEXCOMM_I2C_MONRXDAT_MONRESTART_NOT_DETECTED = 0,
+ /*
+ * Repeated start detected. The Monitor function has detected a Repeated
+ * Start event on the I2C bus.
+ */
+ FLEXCOMM_I2C_MONRXDAT_MONRESTART_DETECTED = 1,
+} FLEXCOMM_I2C_MONRXDAT_MONRESTART_Enum;
+
+typedef enum {
+ /*
+ * Acknowledged. The data currently being provided by the Monitor function
+ * was acknowledged by at least one master or slave receiver.
+ */
+ FLEXCOMM_I2C_MONRXDAT_MONNACK_ACKNOWLEDGED = 0,
+ /*
+ * Not acknowledged. The data currently being provided by the Monitor
+ * function was not acknowledged by any receiver.
+ */
+ FLEXCOMM_I2C_MONRXDAT_MONNACK_NOT_ACKNOWLEDGED = 1,
+} FLEXCOMM_I2C_MONRXDAT_MONNACK_Enum;
+
+
+#define FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(_name) \
+ struct RegisterAccessInfo _name[FLEXCOMM_I2C_REGS_NO] = { \
+ [0 ... FLEXCOMM_I2C_REGS_NO - 1] = { \
+ .name = "", \
+ .addr = -1, \
+ }, \
+ [R_FLEXCOMM_I2C_CFG] = { \
+ .name = "CFG", \
+ .addr = 0x800, \
+ .ro = 0xFFFFFFC0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_I2C_STAT] = { \
+ .name = "STAT", \
+ .addr = 0x804, \
+ .ro = 0xFCF57FAF, \
+ .reset = 0x801, \
+ }, \
+ [R_FLEXCOMM_I2C_INTENSET] = { \
+ .name = "INTENSET", \
+ .addr = 0x808, \
+ .ro = 0xFCF476AE, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_I2C_INTENCLR] = { \
+ .name = "INTENCLR", \
+ .addr = 0x80C, \
+ .ro = 0xFCF476AE, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_I2C_TIMEOUT] = { \
+ .name = "TIMEOUT", \
+ .addr = 0x810, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFFFF, \
+ }, \
+ [R_FLEXCOMM_I2C_CLKDIV] = { \
+ .name = "CLKDIV", \
+ .addr = 0x814, \
+ .ro = 0xFFFF0000, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_I2C_INTSTAT] = { \
+ .name = "INTSTAT", \
+ .addr = 0x818, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x801, \
+ }, \
+ [R_FLEXCOMM_I2C_MSTCTL] = { \
+ .name = "MSTCTL", \
+ .addr = 0x820, \
+ .ro = 0xFFFFFFF0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_I2C_MSTTIME] = { \
+ .name = "MSTTIME", \
+ .addr = 0x824, \
+ .ro = 0xFFFFFF88, \
+ .reset = 0x77, \
+ }, \
+ [R_FLEXCOMM_I2C_MSTDAT] = { \
+ .name = "MSTDAT", \
+ .addr = 0x828, \
+ .ro = 0xFFFFFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_I2C_SLVCTL] = { \
+ .name = "SLVCTL", \
+ .addr = 0x840, \
+ .ro = 0xFFFFFCF4, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_I2C_SLVDAT] = { \
+ .name = "SLVDAT", \
+ .addr = 0x844, \
+ .ro = 0xFFFFFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_I2C_SLVADR0] = { \
+ .name = "SLVADR0", \
+ .addr = 0x848, \
+ .ro = 0xFFFF7F00, \
+ .reset = 0x1, \
+ }, \
+ [R_FLEXCOMM_I2C_SLVADR1] = { \
+ .name = "SLVADR1", \
+ .addr = 0x84C, \
+ .ro = 0xFFFF7F00, \
+ .reset = 0x1, \
+ }, \
+ [R_FLEXCOMM_I2C_SLVADR2] = { \
+ .name = "SLVADR2", \
+ .addr = 0x850, \
+ .ro = 0xFFFF7F00, \
+ .reset = 0x1, \
+ }, \
+ [R_FLEXCOMM_I2C_SLVADR3] = { \
+ .name = "SLVADR3", \
+ .addr = 0x854, \
+ .ro = 0xFFFF7F00, \
+ .reset = 0x1, \
+ }, \
+ [R_FLEXCOMM_I2C_SLVQUAL0] = { \
+ .name = "SLVQUAL0", \
+ .addr = 0x858, \
+ .ro = 0xFFFFFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_I2C_MONRXDAT] = { \
+ .name = "MONRXDAT", \
+ .addr = 0x880, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_I2C_ID] = { \
+ .name = "ID", \
+ .addr = 0xFFC, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0xE0301300, \
+ }, \
+ }
diff --git a/include/hw/i2c/flexcomm_i2c.h b/include/hw/i2c/flexcomm_i2c.h
new file mode 100644
index 0000000000..7b27e333d7
--- /dev/null
+++ b/include/hw/i2c/flexcomm_i2c.h
@@ -0,0 +1,40 @@
+/*
+ * QEMU model for NXP's FLEXCOMM I2C
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_FLEXCOMM_I2C_H
+#define HW_FLEXCOMM_I2C_H
+
+#include "hw/i2c/i2c.h"
+#include "hw/misc/flexcomm_function.h"
+
+#define TYPE_FLEXCOMM_I2C "flexcomm-i2c"
+OBJECT_DECLARE_TYPE(FlexcommI2cState, FlexcommI2cClass, FLEXCOMM_I2C);
+
+struct FlexcommI2cState {
+ FlexcommFunction parent_obj;
+
+ I2CBus *bus;
+};
+
+struct FlexcommI2cClass {
+ FlexcommFunctionClass parent_obj;
+
+ FlexcommFunctionSelect select;
+};
+
+#define MSTSTATE_IDLE 0
+#define MSTSTATE_RXRDY 1
+#define MSTSTATE_TXRDY 2
+#define MSTSTATE_NAKADR 3
+#define MSTSTATE_NAKDAT 4
+
+
+#endif /* HW_FLEXCOMM_I2C_H */
diff --git a/include/hw/misc/flexcomm.h b/include/hw/misc/flexcomm.h
index 679b7ea64d..c9f1cd3890 100644
--- a/include/hw/misc/flexcomm.h
+++ b/include/hw/misc/flexcomm.h
@@ -16,6 +16,7 @@
#include "hw/arm/svd/flexcomm.h"
#include "qemu/fifo32.h"
#include "hw/char/flexcomm_usart.h"
+#include "hw/i2c/flexcomm_i2c.h"
#define FLEXCOMM_FUNC_USART 0
#define FLEXCOMM_FUNC_SPI 1
@@ -48,6 +49,7 @@ struct FlexcommState {
Fifo32 rx_fifo;
Fifo32 tx_fifo;
FlexcommUsartState usart;
+ FlexcommI2cState i2c;
};
#endif /* HW_FLEXCOMM_H */
diff --git a/hw/i2c/flexcomm_i2c.c b/hw/i2c/flexcomm_i2c.c
new file mode 100644
index 0000000000..e5341ec241
--- /dev/null
+++ b/hw/i2c/flexcomm_i2c.c
@@ -0,0 +1,250 @@
+/*
+ * QEMU model for NXP's FLEXCOMM I2C
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "exec/address-spaces.h"
+#include "qapi/error.h"
+#include "trace.h"
+#include "hw/i2c/flexcomm_i2c.h"
+#include "hw/arm/svd/flexcomm_i2c.h"
+
+#define REG(s, reg) (s->regs[R_FLEXCOMM_I2C_##reg])
+#define RF_WR(s, reg, field, val) \
+ ARRAY_FIELD_DP32(s->regs, FLEXCOMM_I2C_##reg, field, val)
+#define RF_RD(s, reg, field) \
+ ARRAY_FIELD_EX32(s->regs, FLEXCOMM_I2C_##reg, field)
+
+static FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(reg_info);
+
+static void flexcomm_i2c_reset(FlexcommFunction *f)
+{
+ for (int i = 0; i < FLEXCOMM_I2C_REGS_NO; i++) {
+ hwaddr addr = reg_info[i].addr;
+
+ if (addr != -1) {
+ struct RegisterInfo ri = {
+ .data = &f->regs[addr / 4],
+ .data_size = 4,
+ .access = ®_info[i],
+ };
+
+ register_reset(&ri);
+ }
+ }
+}
+
+static void flexcomm_i2c_irq_update(FlexcommFunction *f)
+{
+ bool enabled = RF_RD(f, CFG, MSTEN);
+ bool irq, per_irqs;
+
+ REG(f, INTSTAT) = REG(f, STAT) & REG(f, INTENSET);
+ per_irqs = REG(f, INTSTAT) != 0;
+
+ irq = enabled && per_irqs;
+
+ trace_flexcomm_i2c_irq(DEVICE(f)->id, irq, per_irqs, enabled);
+ flexcomm_set_irq(f, irq);
+}
+
+static MemTxResult flexcomm_i2c_reg_read(void *opaque, hwaddr addr,
+ uint64_t *data, unsigned size,
+ MemTxAttrs attrs)
+{
+ FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
+ MemTxResult ret = MEMTX_OK;
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+
+ if (size != 4) {
+ ret = MEMTX_ERROR;
+ goto out;
+ }
+
+ *data = f->regs[addr / 4];
+
+ flexcomm_i2c_irq_update(f);
+
+out:
+ trace_flexcomm_i2c_reg_read(DEVICE(f)->id, rai->name, addr, *data);
+ return ret;
+}
+
+static MemTxResult flexcomm_i2c_reg_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size,
+ MemTxAttrs attrs)
+{
+ FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
+ FlexcommI2cState *s = FLEXCOMM_I2C(opaque);
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+ struct RegisterInfo ri = {
+ .data = &f->regs[addr / 4],
+ .data_size = 4,
+ .access = rai,
+ };
+
+ trace_flexcomm_i2c_reg_write(DEVICE(f)->id, rai->name, addr, value);
+
+ if (size != 4) {
+ return MEMTX_ERROR;
+ }
+
+ switch (addr) {
+ case A_FLEXCOMM_I2C_CFG:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+ if (RF_RD(f, CFG, SLVEN)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "I2C slave not supported");
+ }
+ if (RF_RD(f, CFG, MONEN)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "I2C monitoring not supported");
+ }
+ break;
+ }
+ case A_FLEXCOMM_I2C_INTENCLR:
+ {
+ REG(f, INTENSET) &= ~value;
+ break;
+ }
+ case A_FLEXCOMM_I2C_TIMEOUT:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+ /* The bottom 4 bits are hard-wired to 0xF */
+ RF_WR(f, TIMEOUT, TOMIN, 0xf);
+ break;
+ }
+ case A_FLEXCOMM_I2C_MSTCTL:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+ if (RF_RD(f, MSTCTL, MSTSTART)) {
+ uint8_t i2c_addr = RF_RD(f, MSTDAT, DATA);
+ bool recv = i2c_addr & 1;
+
+ trace_flexcomm_i2c_start(DEVICE(s)->id, i2c_addr, recv);
+ if (i2c_start_transfer(s->bus, i2c_addr, recv)) {
+ RF_WR(f, STAT, MSTSTATE, MSTSTATE_NAKADR);
+ trace_flexcomm_i2c_nak(DEVICE(s)->id);
+ } else {
+ if (recv) {
+ uint8_t data = i2c_recv(s->bus);
+
+ RF_WR(f, MSTDAT, DATA, data);
+ trace_flexcomm_i2c_rx(DEVICE(s)->id, data);
+ RF_WR(f, STAT, MSTSTATE, MSTSTATE_RXRDY);
+ } else {
+ RF_WR(f, STAT, MSTSTATE, MSTSTATE_TXRDY);
+ }
+ }
+ }
+ if (RF_RD(f, MSTCTL, MSTSTOP)) {
+ RF_WR(f, STAT, MSTSTATE, MSTSTATE_IDLE);
+ i2c_end_transfer(s->bus);
+ }
+ if (RF_RD(f, MSTCTL, MSTCONTINUE)) {
+ if (RF_RD(f, STAT, MSTSTATE) == MSTSTATE_TXRDY) {
+ uint8_t data = RF_RD(f, MSTDAT, DATA);
+
+ trace_flexcomm_i2c_tx(DEVICE(s)->id, data);
+ if (i2c_send(s->bus, data)) {
+ RF_WR(f, STAT, MSTSTATE, MSTSTATE_NAKDAT);
+ }
+ } else if (RF_RD(f, STAT, MSTSTATE) == MSTSTATE_RXRDY) {
+ uint8_t data = i2c_recv(s->bus);
+
+ RF_WR(f, MSTDAT, DATA, data);
+ trace_flexcomm_i2c_rx(DEVICE(s)->id, data);
+ }
+ }
+ break;
+ }
+ case A_FLEXCOMM_I2C_STAT:
+ {
+ /* write 1 to clear bits */
+ REG(f, STAT) &= ~value;
+ break;
+ }
+ case A_FLEXCOMM_I2C_SLVCTL:
+ case A_FLEXCOMM_I2C_SLVDAT:
+ case A_FLEXCOMM_I2C_SLVADR0:
+ case A_FLEXCOMM_I2C_SLVADR1:
+ case A_FLEXCOMM_I2C_SLVADR2:
+ case A_FLEXCOMM_I2C_SLVADR3:
+ case A_FLEXCOMM_I2C_SLVQUAL0:
+ {
+ qemu_log_mask(LOG_GUEST_ERROR, "I2C slave not supported\n");
+ break;
+ }
+ default:
+ register_write(&ri, value, ~0, NULL, false);
+ break;
+ }
+
+ flexcomm_i2c_irq_update(f);
+
+ return MEMTX_OK;
+}
+
+static void flexcomm_i2c_select(FlexcommFunction *f, bool selected)
+{
+ FlexcommI2cClass *ic = FLEXCOMM_I2C_GET_CLASS(f);
+
+ if (selected) {
+ flexcomm_i2c_reset(f);
+ }
+ ic->select(f, selected);
+}
+
+static const MemoryRegionOps flexcomm_i2c_ops = {
+ .read_with_attrs = flexcomm_i2c_reg_read,
+ .write_with_attrs = flexcomm_i2c_reg_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ .unaligned = false,
+ },
+};
+
+static void flexcomm_i2c_realize(DeviceState *dev, Error **errp)
+{
+ FlexcommI2cState *s = FLEXCOMM_I2C(dev);
+
+ s->bus = i2c_init_bus(DEVICE(s), "bus");
+}
+
+static void flexcomm_i2c_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_CLASS(klass);
+ FlexcommI2cClass *ic = FLEXCOMM_I2C_CLASS(klass);
+
+ dc->realize = flexcomm_i2c_realize;
+ ic->select = fc->select;
+ fc->select = flexcomm_i2c_select;
+ fc->name = "i2c";
+ fc->mmio_ops = &flexcomm_i2c_ops;
+}
+
+static const TypeInfo flexcomm_i2c_types[] = {
+ {
+ .name = TYPE_FLEXCOMM_I2C,
+ .parent = TYPE_FLEXCOMM_FUNCTION,
+ .instance_size = sizeof(FlexcommI2cState),
+ .class_init = flexcomm_i2c_class_init,
+ .class_size = sizeof(FlexcommI2cClass),
+ },
+};
+
+DEFINE_TYPES(flexcomm_i2c_types);
diff --git a/hw/misc/flexcomm.c b/hw/misc/flexcomm.c
index a291148f27..b1a2f01acf 100644
--- a/hw/misc/flexcomm.c
+++ b/hw/misc/flexcomm.c
@@ -24,6 +24,7 @@
#include "hw/misc/flexcomm.h"
#include "hw/arm/svd/flexcomm_usart.h"
#include "hw/char/flexcomm_usart.h"
+#include "hw/i2c/flexcomm_i2c.h"
#define REG(s, reg) (s->regs[R_FLEXCOMM_##reg])
#define RF_WR(s, reg, field, val) \
@@ -220,6 +221,7 @@ static void flexcomm_init(Object *obj)
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container);
sysbus_init_irq(sbd, &s->irq);
object_initialize_child(obj, "usart", &s->usart, TYPE_FLEXCOMM_USART);
+ object_initialize_child(obj, "i2c", &s->i2c, TYPE_FLEXCOMM_I2C);
}
static void flexcomm_finalize(Object *obj)
@@ -250,6 +252,7 @@ static void flexcomm_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion_overlap(&s->container, 0, &s->mmio, -1);
flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->usart), errp);
+ flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->i2c), errp);
}
static const VMStateDescription vmstate_flexcomm = {
diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build
index 2bde34d15b..417491cd5c 100644
--- a/hw/arm/svd/meson.build
+++ b/hw/arm/svd/meson.build
@@ -7,4 +7,7 @@ if get_option('mcux-soc-svd')
run_target('svd-flexcomm-usart', command: svd_gen_header +
[ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_usart.h',
'-p', 'USART0', '-t', 'FLEXCOMM_USART'])
+ run_target('svd-flexcomm-i2c', command: svd_gen_header +
+ [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_i2c.h',
+ '-p', 'I2C0', '-t', 'FLEXCOMM_I2C'])
endif
diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build
index c459adcb59..e7d79e6938 100644
--- a/hw/i2c/meson.build
+++ b/hw/i2c/meson.build
@@ -18,4 +18,5 @@ i2c_ss.add(when: 'CONFIG_PPC4XX', if_true: files('ppc4xx_i2c.c'))
i2c_ss.add(when: 'CONFIG_PCA954X', if_true: files('i2c_mux_pca954x.c'))
i2c_ss.add(when: 'CONFIG_PMBUS', if_true: files('pmbus_device.c'))
i2c_ss.add(when: 'CONFIG_BCM2835_I2C', if_true: files('bcm2835_i2c.c'))
+i2c_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm_i2c.c'))
system_ss.add_all(when: 'CONFIG_I2C', if_true: i2c_ss)
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
index 6900e06eda..9f0175fab7 100644
--- a/hw/i2c/trace-events
+++ b/hw/i2c/trace-events
@@ -51,3 +51,13 @@ npcm7xx_smbus_recv_fifo(const char *id, uint8_t received, uint8_t expected) "%s
pca954x_write_bytes(uint8_t value) "PCA954X write data: 0x%02x"
pca954x_read_data(uint8_t value) "PCA954X read data: 0x%02x"
+
+# flexcomm_i2c.c
+
+flexcomm_i2c_reg_read(const char *id, const char *reg_name, uint32_t addr, uint32_t val) " %s: %s[0x%04x] -> 0x%08x"
+flexcomm_i2c_reg_write(const char *id, const char *reg_name, uint32_t addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x"
+flexcomm_i2c_start(const char *id, uint8_t addr, uint8_t recv) "%s: 0x%02x %d"
+flexcomm_i2c_rx(const char *id, uint8_t data) "%s: <- 0x%02x"
+flexcomm_i2c_tx(const char *id, uint8_t data) "%s: -> 0x%02x"
+flexcomm_i2c_nak(const char *id) "%s: <- nak"
+flexcomm_i2c_irq(const char *id, bool irq, bool perirqs, bool enabled) "%s: %d %d %d"
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 14167ae9e8..9a244fa01d 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -215,5 +215,6 @@ config XLNX_VERSAL_TRNG
config FLEXCOMM
bool
+ select I2C
source macio/Kconfig
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 09/25] hw/ssi: add support for flexcomm spi
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (7 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 08/25] hw/i2c: add support for flexcomm i2c Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 10/25] hw/misc: add support for RT500's clock controller Octavian Purdila
` (15 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
From: Sebastian Ene <sebastianene@google.com>
Add support for NXP's flexcomm spi. It supports FIFO access,
interrupts and master mode only. It does not support DMA.
The patch includes an automatically generated header which contains
the register layout and helpers.
The header can be regenerated with the svd-flexcomm-spi target when
the build is configured with --enable-mcux-soc-svd.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
[tavip: add suport for CFG.SPOL, CFG.LSBF, TX control flags per FIFO
entry and 8/16 bit access to FIFORD and FIFOWR, convert to Resettable
interface, add support for migration]
Signed-off-by: Octavian Purdila <tavip@google.com>
---
include/hw/arm/svd/flexcomm_spi.h | 1036 +++++++++++++++++++++++++++++
include/hw/misc/flexcomm.h | 2 +
include/hw/ssi/flexcomm_spi.h | 36 +
hw/misc/flexcomm.c | 3 +
hw/ssi/flexcomm_spi.c | 422 ++++++++++++
hw/arm/svd/meson.build | 3 +
hw/misc/Kconfig | 1 +
hw/ssi/meson.build | 1 +
hw/ssi/trace-events | 5 +
9 files changed, 1509 insertions(+)
create mode 100644 include/hw/arm/svd/flexcomm_spi.h
create mode 100644 include/hw/ssi/flexcomm_spi.h
create mode 100644 hw/ssi/flexcomm_spi.c
diff --git a/include/hw/arm/svd/flexcomm_spi.h b/include/hw/arm/svd/flexcomm_spi.h
new file mode 100644
index 0000000000..638efd3f07
--- /dev/null
+++ b/include/hw/arm/svd/flexcomm_spi.h
@@ -0,0 +1,1036 @@
+/*
+ * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
+ */
+#pragma once
+
+#include "hw/register.h"
+
+/* Serial Peripheral Interfaces (SPI) */
+#define FLEXCOMM_SPI_REGS_NO (1024)
+
+/* Configuration Register */
+REG32(FLEXCOMM_SPI_CFG, 1024);
+/* SPI Enable */
+FIELD(FLEXCOMM_SPI_CFG, ENABLE, 0, 1);
+/* Master Mode Select */
+FIELD(FLEXCOMM_SPI_CFG, MASTER, 2, 1);
+/* LSB First Mode Enable */
+FIELD(FLEXCOMM_SPI_CFG, LSBF, 3, 1);
+/* Clock Phase Select */
+FIELD(FLEXCOMM_SPI_CFG, CPHA, 4, 1);
+/* Clock Polarity Select */
+FIELD(FLEXCOMM_SPI_CFG, CPOL, 5, 1);
+/* Loopback Mode Enable */
+FIELD(FLEXCOMM_SPI_CFG, LOOP, 7, 1);
+/* SSEL0 Polarity Select */
+FIELD(FLEXCOMM_SPI_CFG, SPOL0, 8, 1);
+/* SSEL1 Polarity Select */
+FIELD(FLEXCOMM_SPI_CFG, SPOL1, 9, 1);
+/* SSEL2 Polarity Select */
+FIELD(FLEXCOMM_SPI_CFG, SPOL2, 10, 1);
+/* SSEL3 Polarity Select */
+FIELD(FLEXCOMM_SPI_CFG, SPOL3, 11, 1);
+
+/* Delay Register */
+REG32(FLEXCOMM_SPI_DLY, 1028);
+/* Pre-Delay */
+FIELD(FLEXCOMM_SPI_DLY, PRE_DELAY, 0, 4);
+/* Post-Delay */
+FIELD(FLEXCOMM_SPI_DLY, POST_DELAY, 4, 4);
+/* Frame Delay */
+FIELD(FLEXCOMM_SPI_DLY, FRAME_DELAY, 8, 4);
+/* Transfer Delay */
+FIELD(FLEXCOMM_SPI_DLY, TRANSFER_DELAY, 12, 4);
+
+/* Status Register */
+REG32(FLEXCOMM_SPI_STAT, 1032);
+/* Slave Select Assert */
+FIELD(FLEXCOMM_SPI_STAT, SSA, 4, 1);
+/* Slave Select Deassert */
+FIELD(FLEXCOMM_SPI_STAT, SSD, 5, 1);
+/* Stalled Status Flag */
+FIELD(FLEXCOMM_SPI_STAT, STALLED, 6, 1);
+/* End Transfer Control */
+FIELD(FLEXCOMM_SPI_STAT, ENDTRANSFER, 7, 1);
+/* Master Idle Status Flag */
+FIELD(FLEXCOMM_SPI_STAT, MSTIDLE, 8, 1);
+
+/* Interrupt Enable Register */
+REG32(FLEXCOMM_SPI_INTENSET, 1036);
+/* Slave Select Assert Interrupt Enable */
+FIELD(FLEXCOMM_SPI_INTENSET, SSAEN, 4, 1);
+/* Slave Select Deassert Interrupt Enable */
+FIELD(FLEXCOMM_SPI_INTENSET, SSDEN, 5, 1);
+/* Master Idle Interrupt Enable */
+FIELD(FLEXCOMM_SPI_INTENSET, MSTIDLEEN, 8, 1);
+
+/* Interrupt Enable Clear Register */
+REG32(FLEXCOMM_SPI_INTENCLR, 1040);
+/* Slave Select Assert Interrupt Enable */
+FIELD(FLEXCOMM_SPI_INTENCLR, SSAEN, 4, 1);
+/* Slave Select Deassert Interrupt Enable */
+FIELD(FLEXCOMM_SPI_INTENCLR, SSDEN, 5, 1);
+/* Master Idle Interrupt Enable */
+FIELD(FLEXCOMM_SPI_INTENCLR, MSTIDLE, 8, 1);
+
+/* Clock Divider Register */
+REG32(FLEXCOMM_SPI_DIV, 1060);
+/* Rate Divider Value */
+FIELD(FLEXCOMM_SPI_DIV, DIVVAL, 0, 16);
+
+/* Interrupt Status Register */
+REG32(FLEXCOMM_SPI_INTSTAT, 1064);
+/* Slave Select Assert Interrupt */
+FIELD(FLEXCOMM_SPI_INTSTAT, SSA, 4, 1);
+/* Slave Select Deassert Interrupt */
+FIELD(FLEXCOMM_SPI_INTSTAT, SSD, 5, 1);
+/* Master Idle Status Flag Interrupt */
+FIELD(FLEXCOMM_SPI_INTSTAT, MSTIDLE, 8, 1);
+
+/* FIFO Configuration Register */
+REG32(FLEXCOMM_SPI_FIFOCFG, 3584);
+/* Enable the Transmit FIFO */
+FIELD(FLEXCOMM_SPI_FIFOCFG, ENABLETX, 0, 1);
+/* Enable the Receive FIFO */
+FIELD(FLEXCOMM_SPI_FIFOCFG, ENABLERX, 1, 1);
+/* FIFO Size Configuration */
+FIELD(FLEXCOMM_SPI_FIFOCFG, SIZE, 4, 2);
+/* DMA Configuration for Transmit */
+FIELD(FLEXCOMM_SPI_FIFOCFG, DMATX, 12, 1);
+/* DMA Configuration for Receive */
+FIELD(FLEXCOMM_SPI_FIFOCFG, DMARX, 13, 1);
+/* Wake-up for Transmit FIFO Level */
+FIELD(FLEXCOMM_SPI_FIFOCFG, WAKETX, 14, 1);
+/* Wake-up for Receive FIFO Level */
+FIELD(FLEXCOMM_SPI_FIFOCFG, WAKERX, 15, 1);
+/* Empty Command for the Transmit FIFO */
+FIELD(FLEXCOMM_SPI_FIFOCFG, EMPTYTX, 16, 1);
+/* Empty Command for the Receive FIFO */
+FIELD(FLEXCOMM_SPI_FIFOCFG, EMPTYRX, 17, 1);
+/* Pop FIFO for Debug Reads */
+FIELD(FLEXCOMM_SPI_FIFOCFG, POPDBG, 18, 1);
+
+/* FIFO Status Register */
+REG32(FLEXCOMM_SPI_FIFOSTAT, 3588);
+/* TX FIFO Error */
+FIELD(FLEXCOMM_SPI_FIFOSTAT, TXERR, 0, 1);
+/* RX FIFO Error */
+FIELD(FLEXCOMM_SPI_FIFOSTAT, RXERR, 1, 1);
+/* Peripheral Interrupt */
+FIELD(FLEXCOMM_SPI_FIFOSTAT, PERINT, 3, 1);
+/* Transmit FIFO Empty */
+FIELD(FLEXCOMM_SPI_FIFOSTAT, TXEMPTY, 4, 1);
+/* Transmit FIFO is Not Full */
+FIELD(FLEXCOMM_SPI_FIFOSTAT, TXNOTFULL, 5, 1);
+/* Receive FIFO is Not Empty */
+FIELD(FLEXCOMM_SPI_FIFOSTAT, RXNOTEMPTY, 6, 1);
+/* Receive FIFO is Full */
+FIELD(FLEXCOMM_SPI_FIFOSTAT, RXFULL, 7, 1);
+/* Transmit FIFO Current Level */
+FIELD(FLEXCOMM_SPI_FIFOSTAT, TXLVL, 8, 5);
+/* Receive FIFO Current Level */
+FIELD(FLEXCOMM_SPI_FIFOSTAT, RXLVL, 16, 5);
+
+/* FIFO Trigger Register */
+REG32(FLEXCOMM_SPI_FIFOTRIG, 3592);
+/* Transmit FIFO Level Trigger Enable */
+FIELD(FLEXCOMM_SPI_FIFOTRIG, TXLVLENA, 0, 1);
+/* Receive FIFO Level Trigger Enable */
+FIELD(FLEXCOMM_SPI_FIFOTRIG, RXLVLENA, 1, 1);
+/* Transmit FIFO Level Trigger Point */
+FIELD(FLEXCOMM_SPI_FIFOTRIG, TXLVL, 8, 4);
+/* Receive FIFO Level Trigger Point */
+FIELD(FLEXCOMM_SPI_FIFOTRIG, RXLVL, 16, 4);
+
+/* FIFO Interrupt Enable Register */
+REG32(FLEXCOMM_SPI_FIFOINTENSET, 3600);
+/* TX Error Interrupt Enable */
+FIELD(FLEXCOMM_SPI_FIFOINTENSET, TXERR, 0, 1);
+/* Receive Error Interrupt Enable */
+FIELD(FLEXCOMM_SPI_FIFOINTENSET, RXERR, 1, 1);
+/* Transmit FIFO Level Interrupt Enable */
+FIELD(FLEXCOMM_SPI_FIFOINTENSET, TXLVL, 2, 1);
+/* Receive FIFO Level Interrupt Enable */
+FIELD(FLEXCOMM_SPI_FIFOINTENSET, RXLVL, 3, 1);
+
+/* FIFO Interrupt Enable Clear Register */
+REG32(FLEXCOMM_SPI_FIFOINTENCLR, 3604);
+/* TX Error Interrupt Enable */
+FIELD(FLEXCOMM_SPI_FIFOINTENCLR, TXERR, 0, 1);
+/* Receive Error Interrupt Enable */
+FIELD(FLEXCOMM_SPI_FIFOINTENCLR, RXERR, 1, 1);
+/* Transmit FIFO Level Interrupt Enable */
+FIELD(FLEXCOMM_SPI_FIFOINTENCLR, TXLVL, 2, 1);
+/* Receive FIFO Level Interrupt Enable */
+FIELD(FLEXCOMM_SPI_FIFOINTENCLR, RXLVL, 3, 1);
+
+/* FIFO Interrupt Status Register */
+REG32(FLEXCOMM_SPI_FIFOINTSTAT, 3608);
+/* TX FIFO Error Interrupt Status */
+FIELD(FLEXCOMM_SPI_FIFOINTSTAT, TXERR, 0, 1);
+/* RX FIFO Error Interrupt Status */
+FIELD(FLEXCOMM_SPI_FIFOINTSTAT, RXERR, 1, 1);
+/* Transmit FIFO Level Interrupt Status */
+FIELD(FLEXCOMM_SPI_FIFOINTSTAT, TXLVL, 2, 1);
+/* Receive FIFO Level Interrupt Status */
+FIELD(FLEXCOMM_SPI_FIFOINTSTAT, RXLVL, 3, 1);
+/* Peripheral Interrupt Status */
+FIELD(FLEXCOMM_SPI_FIFOINTSTAT, PERINT, 4, 1);
+
+/* FIFO Write Data Register */
+REG32(FLEXCOMM_SPI_FIFOWR, 3616);
+/* Transmit Data to the FIFO */
+FIELD(FLEXCOMM_SPI_FIFOWR, TXDATA, 0, 16);
+/* Transmit Slave Select 0 */
+FIELD(FLEXCOMM_SPI_FIFOWR, TXSSEL0_N, 16, 1);
+/* Transmit Slave Select 1 */
+FIELD(FLEXCOMM_SPI_FIFOWR, TXSSEL1_N, 17, 1);
+/* Transmit Slave Select 2 */
+FIELD(FLEXCOMM_SPI_FIFOWR, TXSSEL2_N, 18, 1);
+/* Transmit Slave Select 3 */
+FIELD(FLEXCOMM_SPI_FIFOWR, TXSSEL3_N, 19, 1);
+/* End of Transfer */
+FIELD(FLEXCOMM_SPI_FIFOWR, EOT, 20, 1);
+/* End of Frame */
+FIELD(FLEXCOMM_SPI_FIFOWR, EOF, 21, 1);
+/* Receive Ignore */
+FIELD(FLEXCOMM_SPI_FIFOWR, RXIGNORE, 22, 1);
+/* Transmit Ignore */
+FIELD(FLEXCOMM_SPI_FIFOWR, TXIGNORE, 23, 1);
+/* Data Length */
+FIELD(FLEXCOMM_SPI_FIFOWR, LEN, 24, 4);
+
+/* FIFO Read Data Register */
+REG32(FLEXCOMM_SPI_FIFORD, 3632);
+/* Received Data from the FIFO */
+FIELD(FLEXCOMM_SPI_FIFORD, RXDATA, 0, 16);
+/* Slave Select 0 for Receive */
+FIELD(FLEXCOMM_SPI_FIFORD, RXSSEL0_N, 16, 1);
+/* Slave Select 1 for Receive */
+FIELD(FLEXCOMM_SPI_FIFORD, RXSSEL1_N, 17, 1);
+/* Slave Select 2 for Receive */
+FIELD(FLEXCOMM_SPI_FIFORD, RXSSEL2_N, 18, 1);
+/* Slave Select 3 for Receive */
+FIELD(FLEXCOMM_SPI_FIFORD, RXSSEL3_N, 19, 1);
+/* Start of Transfer Flag */
+FIELD(FLEXCOMM_SPI_FIFORD, SOT, 20, 1);
+
+/* FIFO Data Read with no FIFO Pop Register */
+REG32(FLEXCOMM_SPI_FIFORDNOPOP, 3648);
+/* Received Data from the FIFO */
+FIELD(FLEXCOMM_SPI_FIFORDNOPOP, RXDATA, 0, 16);
+/* Slave Select 0 for Receive */
+FIELD(FLEXCOMM_SPI_FIFORDNOPOP, RXSSEL0_N, 16, 1);
+/* Slave Select 1 for Receive */
+FIELD(FLEXCOMM_SPI_FIFORDNOPOP, RXSSEL1_N, 17, 1);
+/* Slave Select 2 for Receive */
+FIELD(FLEXCOMM_SPI_FIFORDNOPOP, RXSSEL2_N, 18, 1);
+/* Slave Select 3 for Receive */
+FIELD(FLEXCOMM_SPI_FIFORDNOPOP, RXSSEL3_N, 19, 1);
+/* Start of Transfer Flag */
+FIELD(FLEXCOMM_SPI_FIFORDNOPOP, SOT, 20, 1);
+
+/* FIFO Size Register */
+REG32(FLEXCOMM_SPI_FIFOSIZE, 3656);
+/* FIFO Size */
+FIELD(FLEXCOMM_SPI_FIFOSIZE, FIFOSIZE, 0, 5);
+
+/* Peripheral Identification Register */
+REG32(FLEXCOMM_SPI_ID, 4092);
+/* Aperture */
+FIELD(FLEXCOMM_SPI_ID, APERTURE, 0, 8);
+/* Minor revision of module implementation */
+FIELD(FLEXCOMM_SPI_ID, MINOR_REV, 8, 4);
+/* Major revision of module implementation */
+FIELD(FLEXCOMM_SPI_ID, MAJOR_REV, 12, 4);
+/* Module identifier for the selected function */
+FIELD(FLEXCOMM_SPI_ID, ID, 16, 16);
+
+
+typedef enum {
+ /*
+ * Disabled. The SPI is disabled and the internal state machine and
+ * counters are reset.
+ */
+ FLEXCOMM_SPI_CFG_ENABLE_DISABLED = 0,
+ /* Enabled. The SPI is enabled for operation. */
+ FLEXCOMM_SPI_CFG_ENABLE_ENABLED = 1,
+} FLEXCOMM_SPI_CFG_ENABLE_Enum;
+
+typedef enum {
+ /*
+ * Slave mode. The SPI will operate in slave mode. SCK, MOSI, and the SSEL
+ * signals are inputs; MISO is an output.
+ */
+ FLEXCOMM_SPI_CFG_MASTER_SLAVE_MODE = 0,
+ /*
+ * Master mode. The SPI will operate in master mode. SCK, MOSI, and the
+ * SSEL signals are outputs; MISO is an input.
+ */
+ FLEXCOMM_SPI_CFG_MASTER_MASTER_MODE = 1,
+} FLEXCOMM_SPI_CFG_MASTER_Enum;
+
+typedef enum {
+ /*
+ * Standard. Data is transmitted and received in standard MSB-first order.
+ */
+ FLEXCOMM_SPI_CFG_LSBF_STANDARD = 0,
+ /*
+ * Reverse. Data is transmitted and received in reverse order (LSB first).
+ */
+ FLEXCOMM_SPI_CFG_LSBF_REVERSE = 1,
+} FLEXCOMM_SPI_CFG_LSBF_Enum;
+
+typedef enum {
+ /* Change */
+ FLEXCOMM_SPI_CFG_CPHA_CHANGE = 0,
+ /* Capture */
+ FLEXCOMM_SPI_CFG_CPHA_CAPTURE = 1,
+} FLEXCOMM_SPI_CFG_CPHA_Enum;
+
+typedef enum {
+ /* Low. The rest state of the clock (between transfers) is low. */
+ FLEXCOMM_SPI_CFG_CPOL_LOW = 0,
+ /* High. The rest state of the clock (between transfers) is high. */
+ FLEXCOMM_SPI_CFG_CPOL_HIGH = 1,
+} FLEXCOMM_SPI_CFG_CPOL_Enum;
+
+typedef enum {
+ /* Disabled */
+ FLEXCOMM_SPI_CFG_LOOP_DISABLED = 0,
+ /* Enabled */
+ FLEXCOMM_SPI_CFG_LOOP_ENABLED = 1,
+} FLEXCOMM_SPI_CFG_LOOP_Enum;
+
+typedef enum {
+ /* Low. The SSEL0 pin is active low. */
+ FLEXCOMM_SPI_CFG_SPOL0_LOW = 0,
+ /* High. The SSEL0 pin is active high. */
+ FLEXCOMM_SPI_CFG_SPOL0_HIGH = 1,
+} FLEXCOMM_SPI_CFG_SPOL0_Enum;
+
+typedef enum {
+ /* Low. The SSEL1 pin is active low. */
+ FLEXCOMM_SPI_CFG_SPOL1_LOW = 0,
+ /* High. The SSEL1 pin is active high. */
+ FLEXCOMM_SPI_CFG_SPOL1_HIGH = 1,
+} FLEXCOMM_SPI_CFG_SPOL1_Enum;
+
+typedef enum {
+ /* Low. The SSEL2 pin is active low. */
+ FLEXCOMM_SPI_CFG_SPOL2_LOW = 0,
+ /* High. The SSEL2 pin is active high. */
+ FLEXCOMM_SPI_CFG_SPOL2_HIGH = 1,
+} FLEXCOMM_SPI_CFG_SPOL2_Enum;
+
+typedef enum {
+ /* Low. The SSEL3 pin is active low. */
+ FLEXCOMM_SPI_CFG_SPOL3_LOW = 0,
+ /* High. The SSEL3 pin is active high. */
+ FLEXCOMM_SPI_CFG_SPOL3_HIGH = 1,
+} FLEXCOMM_SPI_CFG_SPOL3_Enum;
+
+typedef enum {
+ /* No additional time is inserted */
+ FLEXCOMM_SPI_DLY_PRE_DELAY_PRE_DELAY0 = 0,
+ /* 1 SPI clock time is inserted */
+ FLEXCOMM_SPI_DLY_PRE_DELAY_PRE_DELAY1 = 1,
+ /* 2 SPI clock times are inserted */
+ FLEXCOMM_SPI_DLY_PRE_DELAY_PRE_DELAY2 = 2,
+ /* 15 SPI clock times are inserted */
+ FLEXCOMM_SPI_DLY_PRE_DELAY_PRE_DELAY15 = 15,
+} FLEXCOMM_SPI_DLY_PRE_DELAY_Enum;
+
+typedef enum {
+ /* No additional time is inserted */
+ FLEXCOMM_SPI_DLY_POST_DELAY_POST_DELAY0 = 0,
+ /* 1 SPI clock time is inserted */
+ FLEXCOMM_SPI_DLY_POST_DELAY_POST_DELAY1 = 1,
+ /* 2 SPI clock times are inserted */
+ FLEXCOMM_SPI_DLY_POST_DELAY_POST_DELAY2 = 2,
+ /* 15 SPI clock times are inserted */
+ FLEXCOMM_SPI_DLY_POST_DELAY_POST_DELAY15 = 15,
+} FLEXCOMM_SPI_DLY_POST_DELAY_Enum;
+
+typedef enum {
+ /* No additional time is inserted */
+ FLEXCOMM_SPI_DLY_FRAME_DELAY_FRAME_DELAY0 = 0,
+ /* 1 SPI clock time is inserted */
+ FLEXCOMM_SPI_DLY_FRAME_DELAY_FRAME_DELAY1 = 1,
+ /* 2 SPI clock times are inserted */
+ FLEXCOMM_SPI_DLY_FRAME_DELAY_FRAME_DELAY2 = 2,
+ /* 15 SPI clock times are inserted */
+ FLEXCOMM_SPI_DLY_FRAME_DELAY_FRAME_DELAY15 = 15,
+} FLEXCOMM_SPI_DLY_FRAME_DELAY_Enum;
+
+typedef enum {
+ /*
+ * The minimum time that SSEL is deasserted is 1 SPI clock time (zero-added
+ * time)
+ */
+ FLEXCOMM_SPI_DLY_TRANSFER_DELAY_TRANSFER_DELAY1 = 0,
+ /* The minimum time that SSEL is deasserted is 2 SPI clock times */
+ FLEXCOMM_SPI_DLY_TRANSFER_DELAY_TRANSFER_DELAY2 = 1,
+ /* The minimum time that SSEL is deasserted is 3 SPI clock times */
+ FLEXCOMM_SPI_DLY_TRANSFER_DELAY_TRANSFER_DELAY3 = 2,
+ /* The minimum time that SSEL is deasserted is 16 SPI clock times */
+ FLEXCOMM_SPI_DLY_TRANSFER_DELAY_TRANSFER_DELAY16 = 15,
+} FLEXCOMM_SPI_DLY_TRANSFER_DELAY_Enum;
+
+typedef enum {
+ /*
+ * Disabled. No interrupt will be generated when any Slave Select
+ * transitions from deasserted to asserted.
+ */
+ FLEXCOMM_SPI_INTENSET_SSAEN_DISABLED = 0,
+ /*
+ * Enabled. An interrupt will be generated when any Slave Select
+ * transitions from deasserted to asserted.
+ */
+ FLEXCOMM_SPI_INTENSET_SSAEN_ENABLED = 1,
+} FLEXCOMM_SPI_INTENSET_SSAEN_Enum;
+
+typedef enum {
+ /*
+ * Disabled. No interrupt will be generated when all asserted Slave Selects
+ * transition to deasserted.
+ */
+ FLEXCOMM_SPI_INTENSET_SSDEN_DISABLED = 0,
+ /*
+ * Enabled. An interrupt will be generated when all asserted Slave Selects
+ * transition to deasserted.
+ */
+ FLEXCOMM_SPI_INTENSET_SSDEN_ENABLED = 1,
+} FLEXCOMM_SPI_INTENSET_SSDEN_Enum;
+
+typedef enum {
+ /* No interrupt will be generated when the SPI master function is idle. */
+ FLEXCOMM_SPI_INTENSET_MSTIDLEEN_DISABLED = 0,
+ /*
+ * An interrupt will be generated when the SPI master function is fully
+ * idle.
+ */
+ FLEXCOMM_SPI_INTENSET_MSTIDLEEN_ENABLED = 1,
+} FLEXCOMM_SPI_INTENSET_MSTIDLEEN_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_SPI_INTENCLR_SSAEN_NO_EFFECT = 0,
+ /* Clear the Slave Select Assert Interrupt Enable bit (INTENSET[SSAEN]) */
+ FLEXCOMM_SPI_INTENCLR_SSAEN_CLEAR_THE_SSAEN = 1,
+} FLEXCOMM_SPI_INTENCLR_SSAEN_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_SPI_INTENCLR_SSDEN_NO_EFFECT = 0,
+ /* Clear the Slave Select Deassert Interrupt Enable bit (INTENSET[SSDEN]) */
+ FLEXCOMM_SPI_INTENCLR_SSDEN_CLEAR_THE_SSDEN = 1,
+} FLEXCOMM_SPI_INTENCLR_SSDEN_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_SPI_INTENCLR_MSTIDLE_NO_EFFECT = 0,
+ /* Clear the Master Idle Interrupt Enable bit (INTENSET[MSTIDLE]) */
+ FLEXCOMM_SPI_INTENCLR_MSTIDLE_CLEAR_THE_MSTIDLE = 1,
+} FLEXCOMM_SPI_INTENCLR_MSTIDLE_Enum;
+
+typedef enum {
+ /* Disabled */
+ FLEXCOMM_SPI_INTSTAT_SSA_SSA_INTERRUPT_DISABLED = 0,
+ /* Enabled */
+ FLEXCOMM_SPI_INTSTAT_SSA_SSA_INTERRUPT_ENABLED = 1,
+} FLEXCOMM_SPI_INTSTAT_SSA_Enum;
+
+typedef enum {
+ /* Disabled */
+ FLEXCOMM_SPI_INTSTAT_SSD_SSD_INTERRUPT_DISABLED = 0,
+ /* Enabled */
+ FLEXCOMM_SPI_INTSTAT_SSD_SSD_INTERRUPT_ENABLED = 1,
+} FLEXCOMM_SPI_INTSTAT_SSD_Enum;
+
+typedef enum {
+ /* Disabled */
+ FLEXCOMM_SPI_INTSTAT_MSTIDLE_MSTIDLE_INTERRUPT_DISABLED = 0,
+ /* Enabled */
+ FLEXCOMM_SPI_INTSTAT_MSTIDLE_MSTIDLE_INTERRUPT_ENABLED = 1,
+} FLEXCOMM_SPI_INTSTAT_MSTIDLE_Enum;
+
+typedef enum {
+ /* The transmit FIFO is not enabled */
+ FLEXCOMM_SPI_FIFOCFG_ENABLETX_DISABLED = 0,
+ /* The transmit FIFO is enabled */
+ FLEXCOMM_SPI_FIFOCFG_ENABLETX_ENABLED = 1,
+} FLEXCOMM_SPI_FIFOCFG_ENABLETX_Enum;
+
+typedef enum {
+ /* The receive FIFO is not enabled */
+ FLEXCOMM_SPI_FIFOCFG_ENABLERX_DISABLED = 0,
+ /* The receive FIFO is enabled */
+ FLEXCOMM_SPI_FIFOCFG_ENABLERX_ENABLED = 1,
+} FLEXCOMM_SPI_FIFOCFG_ENABLERX_Enum;
+
+typedef enum {
+ /* FIFO is configured as 16 entries of 8 bits. */
+ FLEXCOMM_SPI_FIFOCFG_SIZE_SIZE16ENTRIES8BITS = 0,
+ /* FIFO is configured as 8 entries of 16 bits. */
+ FLEXCOMM_SPI_FIFOCFG_SIZE_SIZE8ENTRIES16BITS = 1,
+ /* Not used */
+ FLEXCOMM_SPI_FIFOCFG_SIZE_SIZEINVALID2 = 2,
+ /* Not used */
+ FLEXCOMM_SPI_FIFOCFG_SIZE_SIZEINVALID3 = 3,
+} FLEXCOMM_SPI_FIFOCFG_SIZE_Enum;
+
+typedef enum {
+ /* DMA is not used for the transmit function */
+ FLEXCOMM_SPI_FIFOCFG_DMATX_DISABLED = 0,
+ /*
+ * Issues DMA request for the transmit function if the FIFO is not full.
+ * Generally, data interrupts would be disabled if DMA is enabled.
+ */
+ FLEXCOMM_SPI_FIFOCFG_DMATX_ENABLED = 1,
+} FLEXCOMM_SPI_FIFOCFG_DMATX_Enum;
+
+typedef enum {
+ /* DMA is not used for the receive function. */
+ FLEXCOMM_SPI_FIFOCFG_DMARX_DISABLED = 0,
+ /*
+ * Issues a DMA request for the receive function if the FIFO is not empty.
+ * Generally, data interrupts would be disabled if DMA is enabled.
+ */
+ FLEXCOMM_SPI_FIFOCFG_DMARX_ENABLED = 1,
+} FLEXCOMM_SPI_FIFOCFG_DMARX_Enum;
+
+typedef enum {
+ /*
+ * Only enabled interrupts will wake up the device form reduced power modes
+ */
+ FLEXCOMM_SPI_FIFOCFG_WAKETX_DISABLED = 0,
+ /*
+ * A device wake-up for DMA will occur if the transmit FIFO level reaches
+ * the value specified by TXLVL in FIFOTRIG, even when the TXLVL interrupt
+ * is not enabled.
+ */
+ FLEXCOMM_SPI_FIFOCFG_WAKETX_ENABLED = 1,
+} FLEXCOMM_SPI_FIFOCFG_WAKETX_Enum;
+
+typedef enum {
+ /*
+ * Only enabled interrupts will wake up the device form reduced power
+ * modes.
+ */
+ FLEXCOMM_SPI_FIFOCFG_WAKERX_DISABLED = 0,
+ /*
+ * A device wake-up for DMA will occur if the receive FIFO level reaches
+ * the value specified by FIFOTRIG[RXLVL], even when the RXLVL interrupt is
+ * not enabled.
+ */
+ FLEXCOMM_SPI_FIFOCFG_WAKERX_ENABLED = 1,
+} FLEXCOMM_SPI_FIFOCFG_WAKERX_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_SPI_FIFOCFG_EMPTYTX_NO_EFFECT = 0,
+ /* The TX FIFO is emptied */
+ FLEXCOMM_SPI_FIFOCFG_EMPTYTX_EMPTY_THE_TX_FIFO = 1,
+} FLEXCOMM_SPI_FIFOCFG_EMPTYTX_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_SPI_FIFOCFG_EMPTYRX_NO_EFFECT = 0,
+ /* The RX FIFO is emptied */
+ FLEXCOMM_SPI_FIFOCFG_EMPTYRX_EMPTY_THE_RX_FIFO = 1,
+} FLEXCOMM_SPI_FIFOCFG_EMPTYRX_Enum;
+
+typedef enum {
+ /* Debug reads of the FIFO do not pop the FIFO */
+ FLEXCOMM_SPI_FIFOCFG_POPDBG_DO_NOT_POP = 0,
+ /* A debug read will cause the FIFO to pop */
+ FLEXCOMM_SPI_FIFOCFG_POPDBG_POP = 1,
+} FLEXCOMM_SPI_FIFOCFG_POPDBG_Enum;
+
+typedef enum {
+ /* A transmit FIFO error has not occurred. */
+ FLEXCOMM_SPI_FIFOSTAT_TXERR_NO_TXERR = 0,
+ /*
+ * A transmit FIFO error has occurred. This error could be an overflow
+ * caused by pushing data into a full FIFO, or by an underflow if the FIFO
+ * is empty when data is needed.
+ */
+ FLEXCOMM_SPI_FIFOSTAT_TXERR_TXERR = 1,
+} FLEXCOMM_SPI_FIFOSTAT_TXERR_Enum;
+
+typedef enum {
+ /* A receive FIFO overflow has not occurred */
+ FLEXCOMM_SPI_FIFOSTAT_RXERR_NO_RXERR = 0,
+ /*
+ * A receive FIFO overflow has occurred, caused by software or DMA not
+ * emptying the FIFO fast enough
+ */
+ FLEXCOMM_SPI_FIFOSTAT_RXERR_RXERR = 1,
+} FLEXCOMM_SPI_FIFOSTAT_RXERR_Enum;
+
+typedef enum {
+ /* The peripheral function has not asserted an interrupt */
+ FLEXCOMM_SPI_FIFOSTAT_PERINT_NO_PERINT = 0,
+ /*
+ * Indicates that the peripheral function has asserted an interrupt. More
+ * information can be found by reading the peripheral's status register
+ * (STAT).
+ */
+ FLEXCOMM_SPI_FIFOSTAT_PERINT_PERINT = 1,
+} FLEXCOMM_SPI_FIFOSTAT_PERINT_Enum;
+
+typedef enum {
+ /* The transmit FIFO is not empty */
+ FLEXCOMM_SPI_FIFOSTAT_TXEMPTY_TXFIFO_ISNOTEMPTY = 0,
+ /*
+ * The transmit FIFO is empty, although the peripheral may still be
+ * processing the last piece of data.
+ */
+ FLEXCOMM_SPI_FIFOSTAT_TXEMPTY_TXFIFO_ISEMPTY = 1,
+} FLEXCOMM_SPI_FIFOSTAT_TXEMPTY_Enum;
+
+typedef enum {
+ /* The transmit FIFO is full and another write would cause it to overflow */
+ FLEXCOMM_SPI_FIFOSTAT_TXNOTFULL_TXFIFO_ISFULL = 0,
+ /* The transmit FIFO is not full, so more data can be written */
+ FLEXCOMM_SPI_FIFOSTAT_TXNOTFULL_TXFIFO_ISNOTFULL = 1,
+} FLEXCOMM_SPI_FIFOSTAT_TXNOTFULL_Enum;
+
+typedef enum {
+ /* When 0, the receive FIFO is empty */
+ FLEXCOMM_SPI_FIFOSTAT_RXNOTEMPTY_RXFIFO_ISEMPTY = 0,
+ /* When 1, the receive FIFO is not empty, so data can be read */
+ FLEXCOMM_SPI_FIFOSTAT_RXNOTEMPTY_RXFIFO_ISNOTEMPTY = 1,
+} FLEXCOMM_SPI_FIFOSTAT_RXNOTEMPTY_Enum;
+
+typedef enum {
+ /* The receive FIFO is not full */
+ FLEXCOMM_SPI_FIFOSTAT_RXFULL_RXFIFO_ISNOTFULL = 0,
+ /*
+ * The receive FIFO is full. To prevent the peripheral from causing an
+ * overflow, data should be read out.
+ */
+ FLEXCOMM_SPI_FIFOSTAT_RXFULL_RXFIFO_ISFULL = 1,
+} FLEXCOMM_SPI_FIFOSTAT_RXFULL_Enum;
+
+typedef enum {
+ /* Transmit FIFO level does not generate a FIFO level trigger */
+ FLEXCOMM_SPI_FIFOTRIG_TXLVLENA_DISABLED = 0,
+ /*
+ * An trigger will be generated if the transmit FIFO level reaches the
+ * value specified by the FIFOTRIG[TXLVL] field.
+ */
+ FLEXCOMM_SPI_FIFOTRIG_TXLVLENA_ENABLED = 1,
+} FLEXCOMM_SPI_FIFOTRIG_TXLVLENA_Enum;
+
+typedef enum {
+ /* Receive FIFO level does not generate a FIFO level trigger */
+ FLEXCOMM_SPI_FIFOTRIG_RXLVLENA_DISABLED = 0,
+ /*
+ * An trigger will be generated if the receive FIFO level reaches the value
+ * specified by the FIFOTRIG[RXLVL] field.
+ */
+ FLEXCOMM_SPI_FIFOTRIG_RXLVLENA_ENABLED = 1,
+} FLEXCOMM_SPI_FIFOTRIG_RXLVLENA_Enum;
+
+typedef enum {
+ /* Trigger when the TX FIFO becomes empty */
+ FLEXCOMM_SPI_FIFOTRIG_TXLVL_TXLVL0 = 0,
+ /* Trigger when the TX FIFO level decreases to 1 entry */
+ FLEXCOMM_SPI_FIFOTRIG_TXLVL_TXLVL1 = 1,
+ /*
+ * Trigger when the TX FIFO level decreases to 15 entries (is no longer
+ * full)
+ */
+ FLEXCOMM_SPI_FIFOTRIG_TXLVL_TXLVL15 = 15,
+} FLEXCOMM_SPI_FIFOTRIG_TXLVL_Enum;
+
+typedef enum {
+ /* Trigger when the RX FIFO has received 1 entry (is no longer empty) */
+ FLEXCOMM_SPI_FIFOTRIG_RXLVL_RXLVL1 = 0,
+ /* Trigger when the RX FIFO has received 2 entries */
+ FLEXCOMM_SPI_FIFOTRIG_RXLVL_RXLVL2 = 1,
+ /* Trigger when the RX FIFO has received 16 entries (has become full) */
+ FLEXCOMM_SPI_FIFOTRIG_RXLVL_RXLVL15 = 15,
+} FLEXCOMM_SPI_FIFOTRIG_RXLVL_Enum;
+
+typedef enum {
+ /* No interrupt will be generated for a transmit error */
+ FLEXCOMM_SPI_FIFOINTENSET_TXERR_DISABLED = 0,
+ /* An interrupt will be generated when a transmit error occurs */
+ FLEXCOMM_SPI_FIFOINTENSET_TXERR_ENABLED = 1,
+} FLEXCOMM_SPI_FIFOINTENSET_TXERR_Enum;
+
+typedef enum {
+ /* No interrupt will be generated for a receive error */
+ FLEXCOMM_SPI_FIFOINTENSET_RXERR_DISABLED = 0,
+ /* An interrupt will be generated when a receive error occurs */
+ FLEXCOMM_SPI_FIFOINTENSET_RXERR_ENABLED = 1,
+} FLEXCOMM_SPI_FIFOINTENSET_RXERR_Enum;
+
+typedef enum {
+ /* No interrupt will be generated based on the TX FIFO level */
+ FLEXCOMM_SPI_FIFOINTENSET_TXLVL_DISABLED = 0,
+ /*
+ * If FIFOTRIG[TXLVLENA]=1, then an interrupt will be generated when the TX
+ * FIFO level decreases to the level specified by FIFOTRIG[TXLVL]
+ */
+ FLEXCOMM_SPI_FIFOINTENSET_TXLVL_ENABLED = 1,
+} FLEXCOMM_SPI_FIFOINTENSET_TXLVL_Enum;
+
+typedef enum {
+ /* No interrupt will be generated based on the RX FIFO level */
+ FLEXCOMM_SPI_FIFOINTENSET_RXLVL_DISABLED = 0,
+ /*
+ * If FIFOTRIG[RXLVLENA]=1, then an interrupt will be generated when the RX
+ * FIFO level increases to the level specified by FIFOTRIG[RXLVL]
+ */
+ FLEXCOMM_SPI_FIFOINTENSET_RXLVL_ENABLED = 1,
+} FLEXCOMM_SPI_FIFOINTENSET_RXLVL_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_SPI_FIFOINTENCLR_TXERR_NO_EFFECT = 0,
+ /* Clear the TX Error Interrupt Enable bit FIFOINTENSET[TXERR] */
+ FLEXCOMM_SPI_FIFOINTENCLR_TXERR_CLEAR_THE_TXERR = 1,
+} FLEXCOMM_SPI_FIFOINTENCLR_TXERR_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_SPI_FIFOINTENCLR_RXERR_NO_EFFECT = 0,
+ /* Clear the Receive Error Interrupt Enable bit FIFOINTENSET[RXERR] */
+ FLEXCOMM_SPI_FIFOINTENCLR_RXERR_CLEAR_THE_RXERR = 1,
+} FLEXCOMM_SPI_FIFOINTENCLR_RXERR_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_SPI_FIFOINTENCLR_TXLVL_NO_EFFECT = 0,
+ /* Clear the Transmit FIFO Level Interrupt Enable bit FIFOINTENSET[TXLVL] */
+ FLEXCOMM_SPI_FIFOINTENCLR_TXLVL_CLEAR_THE_TXLVL = 1,
+} FLEXCOMM_SPI_FIFOINTENCLR_TXLVL_Enum;
+
+typedef enum {
+ /* No effect */
+ FLEXCOMM_SPI_FIFOINTENCLR_RXLVL_NO_EFFECT = 0,
+ /* Clear the Receive FIFO Level Interrupt Enable bit FIFOINTENSET[RXLVL] */
+ FLEXCOMM_SPI_FIFOINTENCLR_RXLVL_CLEAR_THE_RXLVL = 1,
+} FLEXCOMM_SPI_FIFOINTENCLR_RXLVL_Enum;
+
+typedef enum {
+ /* Not pending */
+ FLEXCOMM_SPI_FIFOINTSTAT_TXERR_TXERR_ISNOTPENDING = 0,
+ /* Pending */
+ FLEXCOMM_SPI_FIFOINTSTAT_TXERR_TXERR_ISPENDING = 1,
+} FLEXCOMM_SPI_FIFOINTSTAT_TXERR_Enum;
+
+typedef enum {
+ /* Not pending */
+ FLEXCOMM_SPI_FIFOINTSTAT_RXERR_RXERR_ISNOTPENDING = 0,
+ /* Pending */
+ FLEXCOMM_SPI_FIFOINTSTAT_RXERR_RXERR_ISPENDING = 1,
+} FLEXCOMM_SPI_FIFOINTSTAT_RXERR_Enum;
+
+typedef enum {
+ /* Not pending */
+ FLEXCOMM_SPI_FIFOINTSTAT_TXLVL_TXLVL_ISNOTPENDING = 0,
+ /* Pending */
+ FLEXCOMM_SPI_FIFOINTSTAT_TXLVL_TXLVL_ISPENDING = 1,
+} FLEXCOMM_SPI_FIFOINTSTAT_TXLVL_Enum;
+
+typedef enum {
+ /* Not pending */
+ FLEXCOMM_SPI_FIFOINTSTAT_RXLVL_RXLVL_ISNOTPENDING = 0,
+ /* Pending */
+ FLEXCOMM_SPI_FIFOINTSTAT_RXLVL_RXLVL_ISPENDING = 1,
+} FLEXCOMM_SPI_FIFOINTSTAT_RXLVL_Enum;
+
+typedef enum {
+ /* Not pending */
+ FLEXCOMM_SPI_FIFOINTSTAT_PERINT_PERINT_ISNOTPENDING = 0,
+ /* Pending */
+ FLEXCOMM_SPI_FIFOINTSTAT_PERINT_PERINT_ISPENDING = 1,
+} FLEXCOMM_SPI_FIFOINTSTAT_PERINT_Enum;
+
+typedef enum {
+ /* SSEL0 is asserted */
+ FLEXCOMM_SPI_FIFOWR_TXSSEL0_N_ASSERTED = 0,
+ /* SSEL0 is not asserted */
+ FLEXCOMM_SPI_FIFOWR_TXSSEL0_N_NOT_ASSERTED = 1,
+} FLEXCOMM_SPI_FIFOWR_TXSSEL0_N_Enum;
+
+typedef enum {
+ /* SSEL1 is asserted */
+ FLEXCOMM_SPI_FIFOWR_TXSSEL1_N_ASSERTED = 0,
+ /* SSEL1 is not asserted */
+ FLEXCOMM_SPI_FIFOWR_TXSSEL1_N_NOT_ASSERTED = 1,
+} FLEXCOMM_SPI_FIFOWR_TXSSEL1_N_Enum;
+
+typedef enum {
+ /* SSEL2 is asserted */
+ FLEXCOMM_SPI_FIFOWR_TXSSEL2_N_ASSERTED = 0,
+ /* SSEL2 is not asserted */
+ FLEXCOMM_SPI_FIFOWR_TXSSEL2_N_NOT_ASSERTED = 1,
+} FLEXCOMM_SPI_FIFOWR_TXSSEL2_N_Enum;
+
+typedef enum {
+ /* SSEL3 is asserted */
+ FLEXCOMM_SPI_FIFOWR_TXSSEL3_N_ASSERTED = 0,
+ /* SSEL3 is not asserted */
+ FLEXCOMM_SPI_FIFOWR_TXSSEL3_N_NOT_ASSERTED = 1,
+} FLEXCOMM_SPI_FIFOWR_TXSSEL3_N_Enum;
+
+typedef enum {
+ /*
+ * SSEL is not deasserted. This piece of data is not treated as the end of
+ * a transfer. SSEL will not be deasserted at the end of this data.
+ */
+ FLEXCOMM_SPI_FIFOWR_EOT_NOT_DEASSERTED = 0,
+ /*
+ * SSEL is deasserted. This piece of data is treated as the end of a
+ * transfer. SSEL will be deasserted at the end of this piece of data.
+ */
+ FLEXCOMM_SPI_FIFOWR_EOT_DEASSERTED = 1,
+} FLEXCOMM_SPI_FIFOWR_EOT_Enum;
+
+typedef enum {
+ /*
+ * Data not EOF. This piece of data transmitted is not treated as the end
+ * of a frame.
+ */
+ FLEXCOMM_SPI_FIFOWR_EOF_NOT_EOF = 0,
+ /*
+ * Data EOF. This piece of data is treated as the end of a frame, causing
+ * the Frame_delay time to be inserted before subsequent data is
+ * transmitted.
+ */
+ FLEXCOMM_SPI_FIFOWR_EOF_EOF = 1,
+} FLEXCOMM_SPI_FIFOWR_EOF_Enum;
+
+typedef enum {
+ /*
+ * Read received data. Received data must be read, to allow transmission to
+ * proceed. SPI transmit will halt when the receive data FIFO is full. In
+ * slave mode, an overrun error will occur if received data is not read
+ * before new data is received.
+ */
+ FLEXCOMM_SPI_FIFOWR_RXIGNORE_READ = 0,
+ /*
+ * Ignore received data. Received data is ignored, allowing transmission
+ * without reading unneeded received data. No receiver flags are generated.
+ */
+ FLEXCOMM_SPI_FIFOWR_RXIGNORE_IGNORE = 1,
+} FLEXCOMM_SPI_FIFOWR_RXIGNORE_Enum;
+
+typedef enum {
+ /* Write transmit data */
+ FLEXCOMM_SPI_FIFOWR_TXIGNORE_WRITETXDATA = 0,
+ /* Ignore transmit data */
+ FLEXCOMM_SPI_FIFOWR_TXIGNORE_IGNORETXDATA = 1,
+} FLEXCOMM_SPI_FIFOWR_TXIGNORE_Enum;
+
+typedef enum {
+ /* Data transfer is 4 bits in length */
+ FLEXCOMM_SPI_FIFOWR_LEN_LEN_4BITS = 3,
+ /* Data transfer is 5 bits in length */
+ FLEXCOMM_SPI_FIFOWR_LEN_LEN_5BITS = 4,
+ /* Data transfer is 16 bits in length */
+ FLEXCOMM_SPI_FIFOWR_LEN_LEN_16BITS = 15,
+} FLEXCOMM_SPI_FIFOWR_LEN_Enum;
+
+typedef enum {
+ /* Slave Select 0 is active */
+ FLEXCOMM_SPI_FIFORD_RXSSEL0_N_RXSSEL0_ISACTIVE = 0,
+ /* Slave Select 0 is not active */
+ FLEXCOMM_SPI_FIFORD_RXSSEL0_N_RXSSEL0_ISNOTACTIVE = 1,
+} FLEXCOMM_SPI_FIFORD_RXSSEL0_N_Enum;
+
+typedef enum {
+ /* Slave Select 1 is active */
+ FLEXCOMM_SPI_FIFORD_RXSSEL1_N_RXSSEL1_ISACTIVE = 0,
+ /* Slave Select 1 is not active */
+ FLEXCOMM_SPI_FIFORD_RXSSEL1_N_RXSSEL1_ISNOTACTIVE = 1,
+} FLEXCOMM_SPI_FIFORD_RXSSEL1_N_Enum;
+
+typedef enum {
+ /* Slave Select 2 is active */
+ FLEXCOMM_SPI_FIFORD_RXSSEL2_N_RXSSEL2_ISACTIVE = 0,
+ /* Slave Select 2 is not active */
+ FLEXCOMM_SPI_FIFORD_RXSSEL2_N_RXSSEL2_ISNOTACTIVE = 1,
+} FLEXCOMM_SPI_FIFORD_RXSSEL2_N_Enum;
+
+typedef enum {
+ /* Slave Select 3 is active */
+ FLEXCOMM_SPI_FIFORD_RXSSEL3_N_RXSSEL3_ISACTIVE = 0,
+ /* Slave Select 3 is not active */
+ FLEXCOMM_SPI_FIFORD_RXSSEL3_N_RXSSEL3_ISNOTACTIVE = 1,
+} FLEXCOMM_SPI_FIFORD_RXSSEL3_N_Enum;
+
+typedef enum {
+ /*
+ * This is not the 1st data after the SSELs went from deasserted to
+ * asserted
+ */
+ FLEXCOMM_SPI_FIFORD_SOT_SOT0 = 0,
+ /*
+ * This is the 1st data after the SSELs went from deasserted to asserted
+ * (i.e., any previous transfer has ended). This information can be used to
+ * identify the 1st piece of data in cases where the transfer length is
+ * greater than 16 bits.
+ */
+ FLEXCOMM_SPI_FIFORD_SOT_SOT1 = 1,
+} FLEXCOMM_SPI_FIFORD_SOT_Enum;
+
+typedef enum {
+ /* Not selected */
+ FLEXCOMM_SPI_FIFORDNOPOP_RXSSEL0_N_NOT_SELECTED = 0,
+ /* Selected */
+ FLEXCOMM_SPI_FIFORDNOPOP_RXSSEL0_N_RXSSEL0_N_SELECTED = 1,
+} FLEXCOMM_SPI_FIFORDNOPOP_RXSSEL0_N_Enum;
+
+typedef enum {
+ /* Not selected */
+ FLEXCOMM_SPI_FIFORDNOPOP_RXSSEL1_N_NOT_SELECTED = 0,
+ /* Selected */
+ FLEXCOMM_SPI_FIFORDNOPOP_RXSSEL1_N_RXSSEL1_N_SELECTED = 1,
+} FLEXCOMM_SPI_FIFORDNOPOP_RXSSEL1_N_Enum;
+
+typedef enum {
+ /* Not selected */
+ FLEXCOMM_SPI_FIFORDNOPOP_RXSSEL2_N_NOT_SELECTED = 0,
+ /* Selected */
+ FLEXCOMM_SPI_FIFORDNOPOP_RXSSEL2_N_RXSSEL2_N_SELECTED = 1,
+} FLEXCOMM_SPI_FIFORDNOPOP_RXSSEL2_N_Enum;
+
+typedef enum {
+ /* Not selected */
+ FLEXCOMM_SPI_FIFORDNOPOP_RXSSEL3_N_NOT_SELECTED = 0,
+ /* Selected */
+ FLEXCOMM_SPI_FIFORDNOPOP_RXSSEL3_N_RXSSEL3_N_SELECTED = 1,
+} FLEXCOMM_SPI_FIFORDNOPOP_RXSSEL3_N_Enum;
+
+typedef enum {
+ /* Not active */
+ FLEXCOMM_SPI_FIFORDNOPOP_SOT_SOT_NOT_ACTIVE = 0,
+ /* Active */
+ FLEXCOMM_SPI_FIFORDNOPOP_SOT_SOT_ACTIVE = 1,
+} FLEXCOMM_SPI_FIFORDNOPOP_SOT_Enum;
+
+
+#define FLEXCOMM_SPI_REGISTER_ACCESS_INFO_ARRAY(_name) \
+ struct RegisterAccessInfo _name[FLEXCOMM_SPI_REGS_NO] = { \
+ [0 ... FLEXCOMM_SPI_REGS_NO - 1] = { \
+ .name = "", \
+ .addr = -1, \
+ }, \
+ [R_FLEXCOMM_SPI_CFG] = { \
+ .name = "CFG", \
+ .addr = 0x400, \
+ .ro = 0xFFFFF042, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_DLY] = { \
+ .name = "DLY", \
+ .addr = 0x404, \
+ .ro = 0xFFFF0000, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_STAT] = { \
+ .name = "STAT", \
+ .addr = 0x408, \
+ .ro = 0xFFFFFF4F, \
+ .reset = 0x100, \
+ }, \
+ [R_FLEXCOMM_SPI_INTENSET] = { \
+ .name = "INTENSET", \
+ .addr = 0x40C, \
+ .ro = 0xFFFFFECF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_INTENCLR] = { \
+ .name = "INTENCLR", \
+ .addr = 0x410, \
+ .ro = 0xFFFFFECF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_DIV] = { \
+ .name = "DIV", \
+ .addr = 0x424, \
+ .ro = 0xFFFF0000, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_INTSTAT] = { \
+ .name = "INTSTAT", \
+ .addr = 0x428, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_FIFOCFG] = { \
+ .name = "FIFOCFG", \
+ .addr = 0xE00, \
+ .ro = 0xFFF80FFC, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_FIFOSTAT] = { \
+ .name = "FIFOSTAT", \
+ .addr = 0xE04, \
+ .ro = 0xFFFFFFFC, \
+ .reset = 0x30, \
+ }, \
+ [R_FLEXCOMM_SPI_FIFOTRIG] = { \
+ .name = "FIFOTRIG", \
+ .addr = 0xE08, \
+ .ro = 0xFFF0F0FC, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_FIFOINTENSET] = { \
+ .name = "FIFOINTENSET", \
+ .addr = 0xE10, \
+ .ro = 0xFFFFFFF0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_FIFOINTENCLR] = { \
+ .name = "FIFOINTENCLR", \
+ .addr = 0xE14, \
+ .ro = 0xFFFFFFF0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_FIFOINTSTAT] = { \
+ .name = "FIFOINTSTAT", \
+ .addr = 0xE18, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_FIFOWR] = { \
+ .name = "FIFOWR", \
+ .addr = 0xE20, \
+ .ro = 0xF0000000, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_FIFORD] = { \
+ .name = "FIFORD", \
+ .addr = 0xE30, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_FIFORDNOPOP] = { \
+ .name = "FIFORDNOPOP", \
+ .addr = 0xE40, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_FIFOSIZE] = { \
+ .name = "FIFOSIZE", \
+ .addr = 0xE48, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXCOMM_SPI_ID] = { \
+ .name = "ID", \
+ .addr = 0xFFC, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0xE0201200, \
+ }, \
+ }
diff --git a/include/hw/misc/flexcomm.h b/include/hw/misc/flexcomm.h
index c9f1cd3890..757453df97 100644
--- a/include/hw/misc/flexcomm.h
+++ b/include/hw/misc/flexcomm.h
@@ -17,6 +17,7 @@
#include "qemu/fifo32.h"
#include "hw/char/flexcomm_usart.h"
#include "hw/i2c/flexcomm_i2c.h"
+#include "hw/ssi/flexcomm_spi.h"
#define FLEXCOMM_FUNC_USART 0
#define FLEXCOMM_FUNC_SPI 1
@@ -50,6 +51,7 @@ struct FlexcommState {
Fifo32 tx_fifo;
FlexcommUsartState usart;
FlexcommI2cState i2c;
+ FlexcommSpiState spi;
};
#endif /* HW_FLEXCOMM_H */
diff --git a/include/hw/ssi/flexcomm_spi.h b/include/hw/ssi/flexcomm_spi.h
new file mode 100644
index 0000000000..c39cc33de4
--- /dev/null
+++ b/include/hw/ssi/flexcomm_spi.h
@@ -0,0 +1,36 @@
+/*
+ * QEMU model for NXP's FLEXCOMM SPI
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_FLEXCOMM_SPI_H
+#define HW_FLEXCOMM_SPI_H
+
+#include "hw/misc/flexcomm_function.h"
+#include "hw/ssi/ssi.h"
+
+#define TYPE_FLEXCOMM_SPI "flexcomm-spi"
+OBJECT_DECLARE_TYPE(FlexcommSpiState, FlexcommSpiClass, FLEXCOMM_SPI);
+
+struct FlexcommSpiState {
+ FlexcommFunction parent_obj;
+
+ SSIBus *bus;
+ qemu_irq cs[4];
+ bool cs_asserted[4];
+ uint32_t tx_ctrl;
+};
+
+struct FlexcommSpiClass {
+ FlexcommFunctionClass parent_obj;
+
+ FlexcommFunctionSelect select;
+};
+
+#endif /* HW_FLEXCOMM_SPI_H */
diff --git a/hw/misc/flexcomm.c b/hw/misc/flexcomm.c
index b1a2f01acf..fef220eb5b 100644
--- a/hw/misc/flexcomm.c
+++ b/hw/misc/flexcomm.c
@@ -25,6 +25,7 @@
#include "hw/arm/svd/flexcomm_usart.h"
#include "hw/char/flexcomm_usart.h"
#include "hw/i2c/flexcomm_i2c.h"
+#include "hw/ssi/flexcomm_spi.h"
#define REG(s, reg) (s->regs[R_FLEXCOMM_##reg])
#define RF_WR(s, reg, field, val) \
@@ -222,6 +223,7 @@ static void flexcomm_init(Object *obj)
sysbus_init_irq(sbd, &s->irq);
object_initialize_child(obj, "usart", &s->usart, TYPE_FLEXCOMM_USART);
object_initialize_child(obj, "i2c", &s->i2c, TYPE_FLEXCOMM_I2C);
+ object_initialize_child(obj, "spi", &s->spi, TYPE_FLEXCOMM_SPI);
}
static void flexcomm_finalize(Object *obj)
@@ -253,6 +255,7 @@ static void flexcomm_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion_overlap(&s->container, 0, &s->mmio, -1);
flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->usart), errp);
flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->i2c), errp);
+ flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->spi), errp);
}
static const VMStateDescription vmstate_flexcomm = {
diff --git a/hw/ssi/flexcomm_spi.c b/hw/ssi/flexcomm_spi.c
new file mode 100644
index 0000000000..d8ecd37024
--- /dev/null
+++ b/hw/ssi/flexcomm_spi.c
@@ -0,0 +1,422 @@
+/*
+ * QEMU model for NXP's FLEXCOMM SPI
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "qemu/cutils.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "exec/address-spaces.h"
+#include "qapi/error.h"
+#include "trace.h"
+#include "migration/vmstate.h"
+#include "hw/misc/flexcomm.h"
+#include "hw/arm/svd/flexcomm_spi.h"
+
+#define REG(s, reg) (s->regs[R_FLEXCOMM_SPI_##reg])
+#define RF_WR(s, reg, field, val) \
+ ARRAY_FIELD_DP32(s->regs, FLEXCOMM_SPI_##reg, field, val)
+#define RF_RD(s, reg, field) \
+ ARRAY_FIELD_EX32(s->regs, FLEXCOMM_SPI_##reg, field)
+
+#define FLEXCOMM_SSEL_ASSERTED (0)
+#define FLEXCOMM_SSEL_DEASSERTED (1)
+
+#define FLEXCOMM_SPI_FIFOWR_LEN_MIN (3)
+#define FLEXCOMM_SPI_FIFOWR_LEN_MAX (15)
+
+static const FLEXCOMM_SPI_REGISTER_ACCESS_INFO_ARRAY(reg_info);
+
+static void flexcomm_spi_reset(FlexcommFunction *f)
+{
+ for (int i = 0; i < FLEXCOMM_SPI_REGS_NO; i++) {
+ hwaddr addr = reg_info[i].addr;
+
+ if (addr != -1) {
+ struct RegisterInfo ri = {
+ .data = &f->regs[addr / 4],
+ .data_size = 4,
+ .access = ®_info[i],
+ };
+
+ register_reset(&ri);
+ }
+ }
+
+ RF_WR(f, FIFOSIZE, FIFOSIZE, 0x8);
+}
+
+static void flexcomm_spi_irq_update(FlexcommFunction *f)
+{
+ bool irq, per_irqs, fifo_irqs, enabled = RF_RD(f, CFG, ENABLE);
+
+ flexcomm_update_fifostat(f);
+ fifo_irqs = REG(f, FIFOINTSTAT) & REG(f, FIFOINTENSET);
+
+ REG(f, INTSTAT) = REG(f, STAT) & REG(f, INTENSET);
+ per_irqs = REG(f, INTSTAT) != 0;
+
+ irq = enabled && (fifo_irqs || per_irqs);
+
+ trace_flexcomm_spi_irq(DEVICE(f)->id, irq, fifo_irqs, per_irqs, enabled);
+ flexcomm_set_irq(f, irq);
+}
+
+static void flexcomm_spi_select(FlexcommFunction *f, bool selected)
+{
+ FlexcommSpiState *s = FLEXCOMM_SPI(f);
+ FlexcommSpiClass *sc = FLEXCOMM_SPI_GET_CLASS(f);
+
+ if (selected) {
+ bool spol[] = {
+ RF_RD(f, CFG, SPOL0), RF_RD(f, CFG, SPOL1), RF_RD(f, CFG, SPOL2),
+ RF_RD(f, CFG, SPOL3),
+ };
+
+ flexcomm_spi_reset(f);
+ for (int i = 0; i < ARRAY_SIZE(s->cs); i++) {
+ s->cs_asserted[i] = false;
+ qemu_set_irq(s->cs[i], !spol[i]);
+ }
+ }
+ sc->select(f, selected);
+}
+
+static MemTxResult flexcomm_spi_reg_read(void *opaque, hwaddr addr,
+ uint64_t *data, unsigned size,
+ MemTxAttrs attrs)
+{
+ FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
+ MemTxResult ret = MEMTX_OK;
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+
+ /*
+ * Allow 8/16 bits access to the FIFORD LSB half-word. This is supported by
+ * hardware and required for 1/2 byte(s) width DMA transfers.
+ */
+ if (size != 4 && addr != A_FLEXCOMM_SPI_FIFORD) {
+ ret = MEMTX_ERROR;
+ goto out;
+ }
+
+ switch (addr) {
+ case A_FLEXCOMM_SPI_FIFORD:
+ {
+ /* If we are running in loopback mode get the data from TX FIFO */
+ if (RF_RD(f, CFG, LOOP) &&
+ RF_RD(f, CFG, MASTER))
+ {
+ if (!fifo32_is_empty(f->tx_fifo)) {
+ *data = fifo32_pop(f->tx_fifo);
+ }
+ break;
+ }
+
+ if (!fifo32_is_empty(f->rx_fifo)) {
+ *data = fifo32_pop(f->rx_fifo);
+ }
+ break;
+ }
+ case A_FLEXCOMM_SPI_FIFORDNOPOP:
+ {
+ if (!fifo32_is_empty(f->rx_fifo)) {
+ *data = fifo32_peek(f->rx_fifo);
+ }
+ break;
+ }
+ default:
+ *data = f->regs[addr / 4];
+ break;
+ }
+
+ flexcomm_spi_irq_update(f);
+
+out:
+ trace_flexcomm_spi_reg_read(DEVICE(f)->id, rai->name, addr, *data);
+ return ret;
+}
+
+static uint32_t fifowr_len_bits(uint32_t val)
+{
+ int len = FIELD_EX32(val, FLEXCOMM_SPI_FIFOWR, LEN);
+
+ if (len < FLEXCOMM_SPI_FIFOWR_LEN_MIN ||
+ len > FLEXCOMM_SPI_FIFOWR_LEN_MAX) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid spi xfer len %d\n",
+ __func__, val);
+ return 0;
+ }
+
+ return len + 1;
+}
+
+static inline uint32_t fifowr_len_bytes(uint32_t val)
+{
+ return fifowr_len_bits(val) > 8 ? 2 : 1;
+}
+
+static uint32_t flexcomm_spi_xfer_word(FlexcommSpiState *s, uint32_t out_data,
+ int bytes, bool be)
+{
+ uint32_t word = 0;
+ int out = 0;
+
+ for (int i = 0; i < bytes; i++) {
+ if (be) {
+ int byte_offset = bytes - i - 1;
+ out = (out_data & (0xFF << byte_offset * 8)) >> byte_offset * 8;
+ word |= ssi_transfer(s->bus, out) << byte_offset * 8;
+ } else {
+ out = (out_data & (0xFF << i * 8)) >> i * 8;
+ word |= ssi_transfer(s->bus, out) << i * 8;
+ }
+ }
+
+ return word;
+}
+
+static uint32_t flexcomm_spi_get_ss_mask(FlexcommSpiState *s,
+ uint32_t txfifo_val)
+{
+ FlexcommFunction *f = FLEXCOMM_FUNCTION(s);
+
+ uint32_t slave_select_mask = 0;
+ bool ss[] = {
+ FIELD_EX32(txfifo_val, FLEXCOMM_SPI_FIFOWR, TXSSEL0_N),
+ FIELD_EX32(txfifo_val, FLEXCOMM_SPI_FIFOWR, TXSSEL1_N),
+ FIELD_EX32(txfifo_val, FLEXCOMM_SPI_FIFOWR, TXSSEL2_N),
+ FIELD_EX32(txfifo_val, FLEXCOMM_SPI_FIFOWR, TXSSEL3_N),
+ };
+ bool spol[] = {
+ RF_RD(f, CFG, SPOL0), RF_RD(f, CFG, SPOL1), RF_RD(f, CFG, SPOL2),
+ RF_RD(f, CFG, SPOL3),
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(s->cs); i++) {
+ int irq_level = ss[i] ? spol[i] : !spol[i];
+
+ slave_select_mask |= (ss[i] << i);
+ s->cs_asserted[i] = ss[i];
+ qemu_set_irq(s->cs[i], irq_level);
+ }
+
+ return slave_select_mask;
+}
+
+static MemTxResult flexcomm_spi_reg_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size,
+ MemTxAttrs attrs)
+{
+ FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
+ FlexcommSpiState *s = FLEXCOMM_SPI(opaque);
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+ struct RegisterInfo ri = {
+ .data = &f->regs[addr / 4],
+ .data_size = 4,
+ .access = rai,
+ };
+ MemTxResult ret = MEMTX_OK;
+
+ trace_flexcomm_spi_reg_write(DEVICE(f)->id, rai->name, addr, value);
+
+ /*
+ * Allow 8/16 bits access to both the FIFOWR MSB and LSB half-words. The
+ * former is required for updating the control bits while the latter for DMA
+ * transfers of 1/2 byte(s) width.
+ */
+ if (size != 4 && (addr / 4 != R_FLEXCOMM_SPI_FIFOWR)) {
+ return MEMTX_ERROR;
+ }
+
+ switch (addr) {
+ case A_FLEXCOMM_SPI_CFG:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+ break;
+ }
+ case A_FLEXCOMM_SPI_INTENCLR:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+ REG(f, INTENSET) &= ~REG(f, INTENCLR);
+ break;
+ }
+ case A_FLEXCOMM_SPI_FIFOCFG:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+ flexcomm_reset_fifos(f);
+ break;
+ }
+ case A_FLEXCOMM_SPI_FIFOSTAT:
+ {
+ flexcomm_clear_fifostat(f, value);
+ break;
+ }
+ case A_FLEXCOMM_SPI_FIFOINTENSET:
+ {
+ REG(f, FIFOINTENSET) |= value;
+ break;
+ }
+ case A_FLEXCOMM_SPI_FIFOINTENCLR:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+ REG(f, FIFOINTENSET) &= ~REG(f, FIFOINTENCLR);
+ break;
+ }
+ /* update control bits but don't push into the FIFO */
+ case A_FLEXCOMM_SPI_FIFOWR + 2:
+ {
+ if (value != 0) {
+ s->tx_ctrl = value << 16;
+ }
+ break;
+ }
+ /* update control bits but don't push into the FIFO */
+ case A_FLEXCOMM_SPI_FIFOWR + 3:
+ {
+ if (value != 0) {
+ s->tx_ctrl = value << 24;
+ }
+ break;
+ }
+ case A_FLEXCOMM_SPI_FIFOWR:
+ {
+ /* fifo value contains both data and control bits */
+ uint32_t txfifo_val;
+ uint16_t tx_data = FIELD_EX32(value, FLEXCOMM_SPI_FIFOWR, TXDATA);
+ uint32_t tx_ctrl = value & 0xffff0000;
+
+ if (size > 2 && tx_ctrl != 0) {
+ /* non-zero writes to control bits updates them */
+ s->tx_ctrl = tx_ctrl;
+ }
+
+ /* push the data and control bits into the FIFO */
+ txfifo_val = tx_data | s->tx_ctrl;
+
+ if (!fifo32_is_full(f->tx_fifo)) {
+ fifo32_push(f->tx_fifo, txfifo_val);
+ }
+
+ if (!RF_RD(f, CFG, ENABLE) || !RF_RD(f, FIFOCFG, ENABLETX)) {
+ break;
+ }
+
+ /*
+ * On loopback mode we just insert the values in the TX FIFO. On slave
+ * mode master needs to initiate the SPI transfer.
+ */
+ if (RF_RD(f, CFG, LOOP) || !RF_RD(f, CFG, MASTER)) {
+ break;
+ }
+
+ while (!fifo32_is_empty(f->tx_fifo)) {
+ txfifo_val = fifo32_pop(f->tx_fifo);
+
+ uint32_t ss_mask = flexcomm_spi_get_ss_mask(s, txfifo_val);
+ uint32_t data = FIELD_EX32(txfifo_val, FLEXCOMM_SPI_FIFOWR, TXDATA);
+ uint8_t bytes = fifowr_len_bytes(txfifo_val);
+ bool msb = !RF_RD(f, CFG, LSBF);
+ uint32_t val32;
+
+ val32 = flexcomm_spi_xfer_word(s, data, bytes, msb);
+
+ if (!fifo32_is_full(f->rx_fifo)) {
+ /* Append the mask that informs which client is active */
+ val32 |= (ss_mask << R_FLEXCOMM_SPI_FIFORD_RXSSEL0_N_SHIFT);
+ fifo32_push(f->rx_fifo, val32);
+ }
+
+ /* If this is the end of the transfer raise the CS line */
+ if (FIELD_EX32(txfifo_val, FLEXCOMM_SPI_FIFOWR, EOT)) {
+ bool spol[ARRAY_SIZE(s->cs)] = {
+ RF_RD(f, CFG, SPOL0),
+ RF_RD(f, CFG, SPOL1),
+ RF_RD(f, CFG, SPOL2),
+ RF_RD(f, CFG, SPOL3),
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(s->cs); i++) {
+ if (s->cs_asserted[i]) {
+ s->cs_asserted[i] = false;
+ qemu_set_irq(s->cs[i], !spol[i]);
+ }
+ }
+ }
+ }
+ break;
+ }
+ default:
+ register_write(&ri, value, ~0, NULL, false);
+ break;
+ }
+
+ flexcomm_spi_irq_update(f);
+
+ return ret;
+}
+
+static const MemoryRegionOps flexcomm_spi_ops = {
+ .read_with_attrs = flexcomm_spi_reg_read,
+ .write_with_attrs = flexcomm_spi_reg_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ .unaligned = false,
+ },
+};
+
+static void flexcomm_spi_realize(DeviceState *dev, Error **error)
+{
+ FlexcommSpiState *s = FLEXCOMM_SPI(dev);
+
+ s->bus = ssi_create_bus(DEVICE(s), "bus");
+ qdev_init_gpio_out_named(DEVICE(s), s->cs, "cs", ARRAY_SIZE(s->cs));
+}
+
+static const VMStateDescription vmstate_flexcomm_spi = {
+ .name = "flexcomm-spi",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_BOOL_ARRAY(cs_asserted, FlexcommSpiState, 4),
+ VMSTATE_UINT32(tx_ctrl, FlexcommSpiState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void flexcomm_spi_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_CLASS(klass);
+ FlexcommSpiClass *sc = FLEXCOMM_SPI_CLASS(klass);
+
+ dc->realize = flexcomm_spi_realize;
+ dc->vmsd = &vmstate_flexcomm_spi;
+ sc->select = fc->select;
+ fc->select = flexcomm_spi_select;
+ fc->name = "spi";
+ fc->has_fifos = true;
+ fc->mmio_ops = &flexcomm_spi_ops;
+}
+
+static const TypeInfo flexcomm_spi_types[] = {
+ {
+ .name = TYPE_FLEXCOMM_SPI,
+ .parent = TYPE_FLEXCOMM_FUNCTION,
+ .instance_size = sizeof(FlexcommSpiState),
+ .class_init = flexcomm_spi_class_init,
+ .class_size = sizeof(FlexcommSpiClass),
+ },
+};
+
+DEFINE_TYPES(flexcomm_spi_types);
diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build
index 417491cd5c..7f1c847caf 100644
--- a/hw/arm/svd/meson.build
+++ b/hw/arm/svd/meson.build
@@ -10,4 +10,7 @@ if get_option('mcux-soc-svd')
run_target('svd-flexcomm-i2c', command: svd_gen_header +
[ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_i2c.h',
'-p', 'I2C0', '-t', 'FLEXCOMM_I2C'])
+ run_target('svd-flexcomm-spi', command: svd_gen_header +
+ [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_spi.h',
+ '-p', 'SPI0', '-t', 'FLEXCOMM_SPI'])
endif
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 9a244fa01d..b373e651e1 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -216,5 +216,6 @@ config XLNX_VERSAL_TRNG
config FLEXCOMM
bool
select I2C
+ select SSI
source macio/Kconfig
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
index b7ad7fca3b..4039e6d18d 100644
--- a/hw/ssi/meson.build
+++ b/hw/ssi/meson.build
@@ -13,3 +13,4 @@ system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c'))
system_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_spi_host.c'))
system_ss.add(when: 'CONFIG_BCM2835_SPI', if_true: files('bcm2835_spi.c'))
system_ss.add(when: 'CONFIG_PNV_SPI', if_true: files('pnv_spi.c'))
+system_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm_spi.c'))
diff --git a/hw/ssi/trace-events b/hw/ssi/trace-events
index 089d269994..f849f1f8be 100644
--- a/hw/ssi/trace-events
+++ b/hw/ssi/trace-events
@@ -53,3 +53,8 @@ pnv_spi_rx_read_N2frame(void) ""
pnv_spi_shift_rx(uint8_t byte, uint32_t index) "byte = 0x%2.2x into RDR from payload index %d"
pnv_spi_sequencer_stop_requested(const char* reason) "due to %s"
pnv_spi_RDR_match(const char* result) "%s"
+
+# flexcomm_spi.c
+flexcomm_spi_reg_read(const char *id, const char *reg_name, uint32_t addr, uint32_t val) " %s: %s[0x%04x] -> 0x%08x"
+flexcomm_spi_reg_write(const char *id, const char *reg_name, uint32_t addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x"
+flexcomm_spi_irq(const char *id, bool irq, bool fifoirqs, bool perirqs, bool enabled) "%s: %d %d %d %d"
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 10/25] hw/misc: add support for RT500's clock controller
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (8 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 09/25] hw/ssi: add support for flexcomm spi Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 11/25] hw/ssi: add support for flexspi Octavian Purdila
` (14 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
It supports system and audio PLL initialization and SYSTICK and
OSTIMER clock source selection.
The patch includes automatically generated headers which contains the
register layout and helpers.
The headers can be regenerated with the svd-rt500-clkctl0 and
svd-rt500-clkctl1 targets when the build is configured with
--enable-mcux-soc-svd.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
include/hw/arm/svd/rt500_clkctl0.h | 2483 ++++++++++++++++++++
include/hw/arm/svd/rt500_clkctl1.h | 3396 ++++++++++++++++++++++++++++
include/hw/misc/rt500_clk_freqs.h | 18 +
include/hw/misc/rt500_clkctl0.h | 35 +
include/hw/misc/rt500_clkctl1.h | 36 +
hw/misc/rt500_clkctl0.c | 253 +++
hw/misc/rt500_clkctl1.c | 238 ++
hw/arm/Kconfig | 5 +
hw/arm/svd/meson.build | 6 +
hw/misc/Kconfig | 3 +
hw/misc/meson.build | 1 +
hw/misc/trace-events | 8 +
12 files changed, 6482 insertions(+)
create mode 100644 include/hw/arm/svd/rt500_clkctl0.h
create mode 100644 include/hw/arm/svd/rt500_clkctl1.h
create mode 100644 include/hw/misc/rt500_clk_freqs.h
create mode 100644 include/hw/misc/rt500_clkctl0.h
create mode 100644 include/hw/misc/rt500_clkctl1.h
create mode 100644 hw/misc/rt500_clkctl0.c
create mode 100644 hw/misc/rt500_clkctl1.c
diff --git a/include/hw/arm/svd/rt500_clkctl0.h b/include/hw/arm/svd/rt500_clkctl0.h
new file mode 100644
index 0000000000..b5c86eed3e
--- /dev/null
+++ b/include/hw/arm/svd/rt500_clkctl0.h
@@ -0,0 +1,2483 @@
+/*
+ * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
+ */
+#pragma once
+
+#include "hw/register.h"
+
+/* Clock Controller 0 */
+#define RT500_CLKCTL0_REGS_NO (490)
+
+/* Clock Control 0 */
+REG32(RT500_CLKCTL0_PSCCTL0, 16);
+/* DSP clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, DSP_CLK, 1, 1);
+/* 128KB ROM Controller clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, ROM_CTRLR_CLK, 2, 1);
+/* AXI Switch clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, AXI_SWITCH_CLK, 3, 1);
+/* AXI Controller clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, AXI_CTLR_CLK, 4, 1);
+/* POWERQUAD clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, POWERQUAD_CLK, 8, 1);
+/* CASPER clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, CASPER_CLK, 9, 1);
+/* HASHCRYPT clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, HASHCRYPT_CLK, 10, 1);
+/* PUF clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, PUF_CLK, 11, 1);
+/* Random Number Generator (RNG) clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, RNG_CLK, 12, 1);
+/* FLEXSPI0 / OTFAD clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, FLEXSPI0_OTFAD_CLK, 16, 1);
+/* OTP Controller clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, OTP_CTLR_CLK, 17, 1);
+/* FLEXSPI1 clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, FLEXSPI1_CLK, 18, 1);
+/* USB HS PHY clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, USBHS_PHY_CLK, 20, 1);
+/* USB HS Device clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, USBHS_DEVICE_CLK, 21, 1);
+/* USB HS Host clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, USBHS_HOST_CLK, 22, 1);
+/* USB HS SRAM clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, USBHS_SRAM_CLK, 23, 1);
+/* SCT clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, SCT_CLK, 24, 1);
+/* GPU clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, GPU_CLK, 26, 1);
+/* Display Controller clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, DISPLAY_CTLR_CLK, 27, 1);
+/* MIPI-DSI Controller clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, MIPI_DSI_CTLR_CLK, 28, 1);
+/* Smart DMA clock control */
+FIELD(RT500_CLKCTL0_PSCCTL0, SMARTDMA_CLK, 30, 1);
+
+/* Clock Control 1 */
+REG32(RT500_CLKCTL0_PSCCTL1, 20);
+/* SDIO0 clock control */
+FIELD(RT500_CLKCTL0_PSCCTL1, SDIO0_CLK, 2, 1);
+/* SDIO1 clock control */
+FIELD(RT500_CLKCTL0_PSCCTL1, SDIO1_CLK, 3, 1);
+/* ACMP0 clock control */
+FIELD(RT500_CLKCTL0_PSCCTL1, ACMP0_CLK, 15, 1);
+/* ADC0 clock control */
+FIELD(RT500_CLKCTL0_PSCCTL1, ADC0_CLK, 16, 1);
+/* SHSGPIO0 clock control */
+FIELD(RT500_CLKCTL0_PSCCTL1, SHSGPIO0_CLK, 24, 1);
+
+/* Clock Control 2 */
+REG32(RT500_CLKCTL0_PSCCTL2, 24);
+/* Micro-Tick Timer 0 clock control */
+FIELD(RT500_CLKCTL0_PSCCTL2, UTICK0_CLK, 0, 1);
+/* Watchdog Timer 0 clock control */
+FIELD(RT500_CLKCTL0_PSCCTL2, WWDT0_CLK, 1, 1);
+/* Power Management Controller clock control */
+FIELD(RT500_CLKCTL0_PSCCTL2, PMC_CLK, 29, 1);
+
+/* Clock Control 0 Set */
+REG32(RT500_CLKCTL0_PSCCTL0_SET, 64);
+/* DSP clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, DSP_CLK, 1, 1);
+/* 128KB ROM Controller clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, ROM_CTRLR_CLK, 2, 1);
+/* AXI Switch clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, AXI_SWITCH_CLK, 3, 1);
+/* AXI Controller clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, AXI_CTLR_CLK, 4, 1);
+/* POWERQUAD clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, POWERQUAD_CLK, 8, 1);
+/* CASPER clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, CASPER_CLK, 9, 1);
+/* HASHCRYPT clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, HASHCRYPT_CLK, 10, 1);
+/* PUF clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, PUF_CLK, 11, 1);
+/* Random Number Generator (RNG) clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, RNG_CLK, 12, 1);
+/* FLEXSPI0 / OTFAD clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, FLEXSPI0_OTFAD_CLK, 16, 1);
+/* OTP Controller clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, OTP_CTLR_CLK, 17, 1);
+/* FLEXSPI1 clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, FLEXSPI1_CLK, 18, 1);
+/* USB HS PHY clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, USBHS_PHY_CLK, 20, 1);
+/* USB HS Device clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, USBHS_DEVICE_CLK, 21, 1);
+/* USB HS Host clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, USBHS_HOST_CLK, 22, 1);
+/* USB HS SRAM clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, USBHS_SRAM_CLK, 23, 1);
+/* SCT clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, SCT_CLK, 24, 1);
+/* GPU clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, GPU_CLK, 26, 1);
+/* Display Controller clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, DISPLAY_CTLR_CLK, 27, 1);
+/* MIPI-DSI Controller clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, MIPI_DSI_CTLR_CLK, 28, 1);
+/* Smart DMA clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_SET, SMARTDMA_CLK, 30, 1);
+
+/* Clock Control 1 Set */
+REG32(RT500_CLKCTL0_PSCCTL1_SET, 68);
+/* SDIO0 clock set */
+FIELD(RT500_CLKCTL0_PSCCTL1_SET, SDIO0_CLK, 2, 1);
+/* SDIO1 clock set */
+FIELD(RT500_CLKCTL0_PSCCTL1_SET, SDIO1_CLK, 3, 1);
+/* ACMP0 clock set */
+FIELD(RT500_CLKCTL0_PSCCTL1_SET, ACMP0_CLK, 15, 1);
+/* ADC0 clock set */
+FIELD(RT500_CLKCTL0_PSCCTL1_SET, ADC0_CLK, 16, 1);
+/* SHSGPIO0 clock set */
+FIELD(RT500_CLKCTL0_PSCCTL1_SET, SHSGPIO0_CLK, 24, 1);
+
+/* Clock Control 2 Set */
+REG32(RT500_CLKCTL0_PSCCTL2_SET, 72);
+/* Micro-Tick Timer 0 clock set */
+FIELD(RT500_CLKCTL0_PSCCTL2_SET, UTICK0_CLK, 0, 1);
+/* Watchdog Timer 0 clock set */
+FIELD(RT500_CLKCTL0_PSCCTL2_SET, WWDT0_CLK, 1, 1);
+/* Power Management Controller clock set */
+FIELD(RT500_CLKCTL0_PSCCTL2_SET, PMC, 29, 1);
+
+/* Clock Control 0 Clear */
+REG32(RT500_CLKCTL0_PSCCTL0_CLR, 112);
+/* DSP clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, DSP_CLK, 1, 1);
+/* 128KB ROM Controller clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, ROM_CTRLR_CLK, 2, 1);
+/* AXI Switch clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, AXI_SWITCH_CLK, 3, 1);
+/* AXI Controller clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, AXI_CTLR_CLK, 4, 1);
+/* POWERQUAD clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, POWERQUAD_CLK, 8, 1);
+/* CASPER clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, CASPER_CLK, 9, 1);
+/* HASHCRYPT clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, HASHCRYPT_CLK, 10, 1);
+/* PUF clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, PUF_CLK, 11, 1);
+/* RNG clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, RNG_CLK, 12, 1);
+/* FLEXSPI0 / OTFAD clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, FLEXSPI0_OTFAD_CLK, 16, 1);
+/* OTP Controller clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, OTP_CTLR_CLK, 17, 1);
+/* FLEXSPI1 clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, FLEXSPI1_CLK, 18, 1);
+/* USB HS PHY clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, USBHS_PHY_CLK, 20, 1);
+/* USB HS Device clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, USBHS_DEVICE_CLK, 21, 1);
+/* USB HS Host clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, USBHS_HOST_CLK, 22, 1);
+/* USB HS SRAM clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, USBHS_SRAM_CLK, 23, 1);
+/* SCT clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, SCT_CLK, 24, 1);
+/* GPU clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, GPU_CLK, 26, 1);
+/* Display Controller clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, DISPLAY_CTLR_CLK, 27, 1);
+/* MIPI-DSI Controller clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, MIPI_DSI_CTLR_CLK, 28, 1);
+/* Smart DMA clock set */
+FIELD(RT500_CLKCTL0_PSCCTL0_CLR, SMARTDMA_CLK, 30, 1);
+
+/* Clock Control 1 Clear */
+REG32(RT500_CLKCTL0_PSCCTL1_CLR, 116);
+/* SDIO0 clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL1_CLR, SDIO0_CLK, 2, 1);
+/* SDIO1 clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL1_CLR, SDIO1_CLK, 3, 1);
+/* ACMP0 clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL1_CLR, ACMP0_CLK, 15, 1);
+/* ADC0 clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL1_CLR, ADC0_CLK, 16, 1);
+/* SHSGPIO0 clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL1_CLR, SHSGPIO0_CLK, 24, 1);
+
+/* Clock Control 2 Clear */
+REG32(RT500_CLKCTL0_PSCCTL2_CLR, 120);
+/* Micro-Tick Timer 0 clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL2_CLR, UTICK0_CLK, 0, 1);
+/* Watchdog Timer 0 clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL2_CLR, WWDT0_CLK, 1, 1);
+/* Power Management Controller clock clear */
+FIELD(RT500_CLKCTL0_PSCCTL2_CLR, PMC_CLK, 29, 1);
+
+/* Free Running Oscillator Control */
+REG32(RT500_CLKCTL0_FRO_CONTROL, 128);
+/* Expected Count */
+FIELD(RT500_CLKCTL0_FRO_CONTROL, EXP_COUNT, 0, 16);
+/* Threshold Range Upper Limit */
+FIELD(RT500_CLKCTL0_FRO_CONTROL, THRESH_RANGE_UP, 16, 5);
+/* Threshold Range Lower Limit */
+FIELD(RT500_CLKCTL0_FRO_CONTROL, THRESH_RANGE_LOW, 21, 5);
+/* Enable Tuning */
+FIELD(RT500_CLKCTL0_FRO_CONTROL, ENA_TUNE, 31, 1);
+
+/* Free Running Oscillator Captured Value */
+REG32(RT500_CLKCTL0_FRO_CAPVAL, 132);
+/* Captured Value */
+FIELD(RT500_CLKCTL0_FRO_CAPVAL, CAPVAL, 0, 16);
+/* Data Valid */
+FIELD(RT500_CLKCTL0_FRO_CAPVAL, DATA_VALID, 31, 1);
+
+/* Free Running Oscillator Trim */
+REG32(RT500_CLKCTL0_FRO_RDTRIM, 140);
+/* It is the trim value supplied to the oscillator */
+FIELD(RT500_CLKCTL0_FRO_RDTRIM, TRIM, 0, 11);
+
+/* Free Running OscillatorSC Trim */
+REG32(RT500_CLKCTL0_FRO_SCTRIM, 144);
+/* sc_trim value for the oscillator. */
+FIELD(RT500_CLKCTL0_FRO_SCTRIM, TRIM, 0, 6);
+
+/* FRO Clock Divider */
+REG32(RT500_CLKCTL0_FRODIVSEL, 264);
+/* Select clock */
+FIELD(RT500_CLKCTL0_FRODIVSEL, SEL, 0, 2);
+
+/* FRO Clock Status */
+REG32(RT500_CLKCTL0_FROCLKSTATUS, 268);
+/* FRO Clock OK */
+FIELD(RT500_CLKCTL0_FROCLKSTATUS, CLK_OK, 0, 1);
+
+/* FRO Enable Register */
+REG32(RT500_CLKCTL0_FRODIVOEN, 272);
+/* FRO Divided-by-1 Clock Enable */
+FIELD(RT500_CLKCTL0_FRODIVOEN, FRO_DIV1_O_EN, 0, 1);
+/* FRO Divided-by-2 Clock Enable */
+FIELD(RT500_CLKCTL0_FRODIVOEN, FRO_DIV2_O_EN, 1, 1);
+/* FRO Divided-by-4 Clock Enable */
+FIELD(RT500_CLKCTL0_FRODIVOEN, FRO_DIV4_O_EN, 2, 1);
+/* FRO Divided-by-8 Clock Enable */
+FIELD(RT500_CLKCTL0_FRODIVOEN, FRO_DIV8_O_EN, 3, 1);
+/* FRO Divided-by-16 Clock Enable */
+FIELD(RT500_CLKCTL0_FRODIVOEN, FRO_DIV16_O_EN, 4, 1);
+
+/* Low Frequency Clock Divider */
+REG32(RT500_CLKCTL0_LOWFREQCLKDIV, 304);
+/* Low Frequency Clock Divider Value */
+FIELD(RT500_CLKCTL0_LOWFREQCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_LOWFREQCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_LOWFREQCLKDIV, HALT, 30, 1);
+/* Divider Status Flag */
+FIELD(RT500_CLKCTL0_LOWFREQCLKDIV, REQFLAG, 31, 1);
+
+/* System Oscillator Control 0 */
+REG32(RT500_CLKCTL0_SYSOSCCTL0, 352);
+/* Low Power Mode Enable */
+FIELD(RT500_CLKCTL0_SYSOSCCTL0, LP_ENABLE, 0, 1);
+/* Bypass Enable */
+FIELD(RT500_CLKCTL0_SYSOSCCTL0, BYPASS_ENABLE, 1, 1);
+
+/* OSC Clock Source Select */
+REG32(RT500_CLKCTL0_SYSOSCBYPASS, 360);
+/* Select SYSOSC Bypass */
+FIELD(RT500_CLKCTL0_SYSOSCBYPASS, SEL, 0, 3);
+
+/* Low Power Oscillator Control 0 */
+REG32(RT500_CLKCTL0_LPOSCCTL0, 400);
+/* LPOSC Clock Ready */
+FIELD(RT500_CLKCTL0_LPOSCCTL0, CLKRDY, 31, 1);
+
+/* 32 KHz Oscillator Control 0 */
+REG32(RT500_CLKCTL0_OSC32KHZCTL0, 448);
+/* 32 KHz Oscillator Enable */
+FIELD(RT500_CLKCTL0_OSC32KHZCTL0, ENA32KHZ, 0, 1);
+
+/* System PLL 0 Clock Select */
+REG32(RT500_CLKCTL0_SYSPLL0CLKSEL, 512);
+/* System PLL0 Reference Input Clock Source */
+FIELD(RT500_CLKCTL0_SYSPLL0CLKSEL, SEL, 0, 3);
+
+/* System PLL0 Control 0 */
+REG32(RT500_CLKCTL0_SYSPLL0CTL0, 516);
+/* SYSPLL0 BYPASS Mode */
+FIELD(RT500_CLKCTL0_SYSPLL0CTL0, BYPASS, 0, 1);
+/* SYSPLL0 Reset */
+FIELD(RT500_CLKCTL0_SYSPLL0CTL0, RESET, 1, 1);
+/* Hold Ring Off Control */
+FIELD(RT500_CLKCTL0_SYSPLL0CTL0, HOLDRINGOFF_ENA, 13, 1);
+/* Multiplication Factor */
+FIELD(RT500_CLKCTL0_SYSPLL0CTL0, MULT, 16, 8);
+
+/* System PLL0 Lock Time Div2 */
+REG32(RT500_CLKCTL0_SYSPLL0LOCKTIMEDIV2, 524);
+/* SYSPLL0 Lock Time Divide-by-2 */
+FIELD(RT500_CLKCTL0_SYSPLL0LOCKTIMEDIV2, LOCKTIMEDIV2, 0, 16);
+
+/* System PLL0 Numerator */
+REG32(RT500_CLKCTL0_SYSPLL0NUM, 528);
+/* Numerator of the SYSPLL0 fractional loop divider */
+FIELD(RT500_CLKCTL0_SYSPLL0NUM, NUM, 0, 30);
+
+/* System PLL0 Denominator */
+REG32(RT500_CLKCTL0_SYSPLL0DENOM, 532);
+/* Denominator of the SYSPLL0 fractional loop divider */
+FIELD(RT500_CLKCTL0_SYSPLL0DENOM, DENOM, 0, 30);
+
+/* System PLL0 PFD */
+REG32(RT500_CLKCTL0_SYSPLL0PFD, 536);
+/* PLL Fractional Divider 0 */
+FIELD(RT500_CLKCTL0_SYSPLL0PFD, PFD0, 0, 6);
+/* PFD0 Clock Ready Status Flag */
+FIELD(RT500_CLKCTL0_SYSPLL0PFD, PFD0_CLKRDY, 6, 1);
+/* PFD0 Clock Gate */
+FIELD(RT500_CLKCTL0_SYSPLL0PFD, PFD0_CLKGATE, 7, 1);
+/* PLL Fractional Divider 1 */
+FIELD(RT500_CLKCTL0_SYSPLL0PFD, PFD1, 8, 6);
+/* PFD1 Clock Ready Status Flag */
+FIELD(RT500_CLKCTL0_SYSPLL0PFD, PFD1_CLKRDY, 14, 1);
+/* PFD1 Clock Gate */
+FIELD(RT500_CLKCTL0_SYSPLL0PFD, PFD1_CLKGATE, 15, 1);
+/* PLL Fractional Divider 2 */
+FIELD(RT500_CLKCTL0_SYSPLL0PFD, PFD2, 16, 6);
+/* PFD2 Clock Ready Status Flag */
+FIELD(RT500_CLKCTL0_SYSPLL0PFD, PFD2_CLKRDY, 22, 1);
+/* PFD2 Clock Gate */
+FIELD(RT500_CLKCTL0_SYSPLL0PFD, PFD2_CLKGATE, 23, 1);
+/* PLL Fractional Divider 3 */
+FIELD(RT500_CLKCTL0_SYSPLL0PFD, PFD3, 24, 6);
+/* PFD3 Clock Ready Status Flag */
+FIELD(RT500_CLKCTL0_SYSPLL0PFD, PFD3_CLKRDY, 30, 1);
+/* PFD3 Clock Gate */
+FIELD(RT500_CLKCTL0_SYSPLL0PFD, PFD3_CLKGATE, 31, 1);
+
+/* Main PLL Clock Divider */
+REG32(RT500_CLKCTL0_MAINPLLCLKDIV, 576);
+/* Low Frequency Clock Divider Value */
+FIELD(RT500_CLKCTL0_MAINPLLCLKDIV, DIV, 0, 8);
+/* Resets the divider counter */
+FIELD(RT500_CLKCTL0_MAINPLLCLKDIV, RESET, 29, 1);
+/* Halts the divider counter */
+FIELD(RT500_CLKCTL0_MAINPLLCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_MAINPLLCLKDIV, REQFLAG, 31, 1);
+
+/* DSP PLL Clock Divider */
+REG32(RT500_CLKCTL0_DSPPLLCLKDIV, 580);
+/* Low Frequency Clock Divider Value */
+FIELD(RT500_CLKCTL0_DSPPLLCLKDIV, DIV, 0, 8);
+/* Resets the divider counter */
+FIELD(RT500_CLKCTL0_DSPPLLCLKDIV, RESET, 29, 1);
+/* Halts the divider counter */
+FIELD(RT500_CLKCTL0_DSPPLLCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_DSPPLLCLKDIV, REQFLAG, 31, 1);
+
+/* AUX0 PLL Clock Divider */
+REG32(RT500_CLKCTL0_AUX0PLLCLKDIV, 584);
+/* Low Frequency Clock Divider Value */
+FIELD(RT500_CLKCTL0_AUX0PLLCLKDIV, DIV, 0, 8);
+/* Resets the divider counter */
+FIELD(RT500_CLKCTL0_AUX0PLLCLKDIV, RESET, 29, 1);
+/* Halts the divider counter */
+FIELD(RT500_CLKCTL0_AUX0PLLCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_AUX0PLLCLKDIV, REQFLAG, 31, 1);
+
+/* AUX1 PLL Clock Divider */
+REG32(RT500_CLKCTL0_AUX1PLLCLKDIV, 588);
+/* Low Frequency Clock Divider Value */
+FIELD(RT500_CLKCTL0_AUX1PLLCLKDIV, DIV, 0, 8);
+/* Resets the divider counter */
+FIELD(RT500_CLKCTL0_AUX1PLLCLKDIV, RESET, 29, 1);
+/* Halts the divider counter */
+FIELD(RT500_CLKCTL0_AUX1PLLCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_AUX1PLLCLKDIV, REQFLAG, 31, 1);
+
+/* System CPU AHB Clock Divider */
+REG32(RT500_CLKCTL0_SYSCPUAHBCLKDIV, 1024);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_SYSCPUAHBCLKDIV, DIV, 0, 8);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_SYSCPUAHBCLKDIV, REQFLAG, 31, 1);
+
+/* Main Clock Select A */
+REG32(RT500_CLKCTL0_MAINCLKSELA, 1072);
+/* Control Main 1st Stage Control Clock Source */
+FIELD(RT500_CLKCTL0_MAINCLKSELA, SEL, 0, 2);
+
+/* Main Clock Select B */
+REG32(RT500_CLKCTL0_MAINCLKSELB, 1076);
+/* Main Clock Source Selection */
+FIELD(RT500_CLKCTL0_MAINCLKSELB, SEL, 0, 2);
+
+/* PFC divider 0 (trace clock) */
+REG32(RT500_CLKCTL0_PFC0DIV, 1280);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_PFC0DIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_PFC0DIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_PFC0DIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_PFC0DIV, REQFLAG, 31, 1);
+
+/* PFC divider 1 (USB HS PHY bus clock) */
+REG32(RT500_CLKCTL0_PFC1DIV, 1284);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_PFC1DIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_PFC1DIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_PFC1DIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_PFC1DIV, REQFLAG, 31, 1);
+
+/* FlexSPI0 Functional Clock Select */
+REG32(RT500_CLKCTL0_FLEXSPI0FCLKSEL, 1568);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_FLEXSPI0FCLKSEL, SEL, 0, 3);
+
+/* FlexSPI0 Functional Clock Divider */
+REG32(RT500_CLKCTL0_FLEXSPI0FCLKDIV, 1572);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_FLEXSPI0FCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_FLEXSPI0FCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_FLEXSPI0FCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_FLEXSPI0FCLKDIV, REQFLAG, 31, 1);
+
+/* FlexSPI1 Functional Clock Select */
+REG32(RT500_CLKCTL0_FLEXSPI1FCLKSEL, 1584);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_FLEXSPI1FCLKSEL, SEL, 0, 3);
+
+/* FlexSPI1 Functional Clock Divider */
+REG32(RT500_CLKCTL0_FLEXSPI1FCLKDIV, 1588);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_FLEXSPI1FCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_FLEXSPI1FCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_FLEXSPI1FCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_FLEXSPI1FCLKDIV, REQFLAG, 31, 1);
+
+/* SCT Functional Clock Select */
+REG32(RT500_CLKCTL0_SCTFCLKSEL, 1600);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_SCTFCLKSEL, SEL, 0, 3);
+
+/* SCT Functional Clock Divider */
+REG32(RT500_CLKCTL0_SCTIN7CLKDIV, 1604);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_SCTIN7CLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_SCTIN7CLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_SCTIN7CLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_SCTIN7CLKDIV, REQFLAG, 31, 1);
+
+/* High Speed USB Functional Clock Select */
+REG32(RT500_CLKCTL0_USBHSFCLKSEL, 1632);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_USBHSFCLKSEL, SEL, 0, 3);
+
+/* High Speed USB Functional Clock Divider */
+REG32(RT500_CLKCTL0_USBHSFCLKDIV, 1636);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_USBHSFCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_USBHSFCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_USBHSFCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_USBHSFCLKDIV, REQFLAG, 31, 1);
+
+/* SDIO0 Functional Clock Select */
+REG32(RT500_CLKCTL0_SDIO0FCLKSEL, 1664);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_SDIO0FCLKSEL, SEL, 0, 3);
+
+/* SDIO0 Functional Clock Divider */
+REG32(RT500_CLKCTL0_SDIO0FCLKDIV, 1668);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_SDIO0FCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_SDIO0FCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_SDIO0FCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_SDIO0FCLKDIV, REQFLAG, 31, 1);
+
+/* SDIO1 Functional Clock Select */
+REG32(RT500_CLKCTL0_SDIO1FCLKSEL, 1680);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_SDIO1FCLKSEL, SEL, 0, 3);
+
+/* SDIO1 Functional Clock Divider */
+REG32(RT500_CLKCTL0_SDIO1FCLKDIV, 1684);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_SDIO1FCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_SDIO1FCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_SDIO1FCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_SDIO1FCLKDIV, REQFLAG, 31, 1);
+
+/* ADC0 Functional Clock Select 0 */
+REG32(RT500_CLKCTL0_ADC0FCLKSEL0, 1744);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_ADC0FCLKSEL0, SEL, 0, 3);
+
+/* ADC0 Functional Clock Select 1 */
+REG32(RT500_CLKCTL0_ADC0FCLKSEL1, 1748);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_ADC0FCLKSEL1, SEL, 0, 3);
+
+/* ADC0 Functional Clock Divider */
+REG32(RT500_CLKCTL0_ADC0FCLKDIV, 1752);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_ADC0FCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_ADC0FCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_ADC0FCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_ADC0FCLKDIV, REQFLAG, 31, 1);
+
+/* UTICK Functional Clock Select */
+REG32(RT500_CLKCTL0_UTICKFCLKSEL, 1792);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_UTICKFCLKSEL, SEL, 0, 3);
+
+/* WDT0 Functional Clock Select */
+REG32(RT500_CLKCTL0_WDT0FCLKSEL, 1824);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_WDT0FCLKSEL, SEL, 0, 3);
+
+/* 32 KHz Wake Clock Source Select */
+REG32(RT500_CLKCTL0_A32KHZWAKECLKSEL, 1840);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_A32KHZWAKECLKSEL, SEL, 0, 3);
+
+/* 32 KHz Wake Clock Divider */
+REG32(RT500_CLKCTL0_A32KHZWAKECLKDIV, 1844);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_A32KHZWAKECLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_A32KHZWAKECLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_A32KHZWAKECLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_A32KHZWAKECLKDIV, REQFLAG, 31, 1);
+
+/* SYSTICK Functional Clock Select */
+REG32(RT500_CLKCTL0_SYSTICKFCLKSEL, 1888);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_SYSTICKFCLKSEL, SEL, 0, 3);
+
+/* SYSTICK Functional Clock Divider */
+REG32(RT500_CLKCTL0_SYSTICKFCLKDIV, 1892);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_SYSTICKFCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_SYSTICKFCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_SYSTICKFCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_SYSTICKFCLKDIV, REQFLAG, 31, 1);
+
+/* MIPI-DSI PHY Clock Select */
+REG32(RT500_CLKCTL0_DPHYCLKSEL, 1904);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_DPHYCLKSEL, SEL, 0, 3);
+
+/* MIPI-DSI PHY Clock Divider */
+REG32(RT500_CLKCTL0_DPHYCLKDIV, 1908);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_DPHYCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_DPHYCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_DPHYCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_DPHYCLKDIV, REQFLAG, 31, 1);
+
+/* MIPI-DSI DPHY Escape Mode Clock Select */
+REG32(RT500_CLKCTL0_DPHYESCCLKSEL, 1912);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_DPHYESCCLKSEL, SEL, 0, 3);
+
+/* MIPI-DSI DPHY Escape Mode Receive Clock Divider */
+REG32(RT500_CLKCTL0_DPHYESCRXCLKDIV, 1916);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_DPHYESCRXCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_DPHYESCRXCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_DPHYESCRXCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_DPHYESCRXCLKDIV, REQFLAG, 31, 1);
+
+/* MIPI-DSI DPHY Escape Mode Tramsmit Clock Divider */
+REG32(RT500_CLKCTL0_DPHYESCTXCLKDIV, 1920);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_DPHYESCTXCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_DPHYESCTXCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_DPHYESCTXCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_DPHYESCTXCLKDIV, REQFLAG, 31, 1);
+
+/* GPU Clock Select */
+REG32(RT500_CLKCTL0_GPUCLKSEL, 1936);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_GPUCLKSEL, SEL, 0, 3);
+
+/* GPU Clock Divider */
+REG32(RT500_CLKCTL0_GPUCLKDIV, 1940);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_GPUCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_GPUCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_GPUCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_GPUCLKDIV, REQFLAG, 31, 1);
+
+/* LCDIF Pixel Clock Select */
+REG32(RT500_CLKCTL0_DCPIXELCLKSEL, 1952);
+/* Select Clock Source */
+FIELD(RT500_CLKCTL0_DCPIXELCLKSEL, SEL, 0, 3);
+
+/* LCDIF Pixel Clock Divider */
+REG32(RT500_CLKCTL0_DCPIXELCLKDIV, 1956);
+/* Clock Divider Value Selection */
+FIELD(RT500_CLKCTL0_DCPIXELCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL0_DCPIXELCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL0_DCPIXELCLKDIV, HALT, 30, 1);
+/* Divider status flag */
+FIELD(RT500_CLKCTL0_DCPIXELCLKDIV, REQFLAG, 31, 1);
+
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_DSP_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_DSP_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_DSP_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_ROM_CTRLR_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_ROM_CTRLR_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_ROM_CTRLR_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_AXI_SWITCH_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_AXI_SWITCH_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_AXI_SWITCH_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_AXI_CTLR_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_AXI_CTLR_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_AXI_CTLR_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_POWERQUAD_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_POWERQUAD_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_POWERQUAD_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_CASPER_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_CASPER_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_CASPER_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_HASHCRYPT_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_HASHCRYPT_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_HASHCRYPT_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_PUF_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_PUF_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_PUF_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_RNG_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_RNG_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_RNG_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_FLEXSPI0_OTFAD_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_FLEXSPI0_OTFAD_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_FLEXSPI0_OTFAD_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_OTP_CTLR_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_OTP_CTLR_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_OTP_CTLR_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_FLEXSPI1_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_FLEXSPI1_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_FLEXSPI1_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_USBHS_PHY_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_USBHS_PHY_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_USBHS_PHY_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_USBHS_DEVICE_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_USBHS_DEVICE_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_USBHS_DEVICE_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_USBHS_HOST_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_USBHS_HOST_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_USBHS_HOST_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_USBHS_SRAM_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_USBHS_SRAM_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_USBHS_SRAM_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_SCT_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_SCT_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_SCT_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_GPU_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_GPU_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_GPU_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_DISPLAY_CTLR_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_DISPLAY_CTLR_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_DISPLAY_CTLR_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_MIPI_DSI_CTLR_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_MIPI_DSI_CTLR_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_MIPI_DSI_CTLR_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL0_SMARTDMA_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL0_SMARTDMA_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL0_SMARTDMA_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL1_SDIO0_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL1_SDIO0_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL1_SDIO0_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL1_SDIO1_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL1_SDIO1_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL1_SDIO1_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL1_ACMP0_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL1_ACMP0_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL1_ACMP0_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL1_ADC0_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL1_ADC0_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL1_ADC0_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL1_SHSGPIO0_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL1_SHSGPIO0_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL1_SHSGPIO0_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL2_UTICK0_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL2_UTICK0_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL2_UTICK0_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL2_WWDT0_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL2_WWDT0_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL2_WWDT0_CLK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_PSCCTL2_PMC_CLK_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_PSCCTL2_PMC_CLK_CLK_ENABLE = 1,
+} RT500_CLKCTL0_PSCCTL2_PMC_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_DSP_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_DSP_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_DSP_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_ROM_CTRLR_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_ROM_CTRLR_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_ROM_CTRLR_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_AXI_SWITCH_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_AXI_SWITCH_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_AXI_SWITCH_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_AXI_CTLR_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_AXI_CTLR_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_AXI_CTLR_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_POWERQUAD_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_POWERQUAD_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_POWERQUAD_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_CASPER_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_CASPER_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_CASPER_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_HASHCRYPT_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_HASHCRYPT_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_HASHCRYPT_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_PUF_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_PUF_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_PUF_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_RNG_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_RNG_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_RNG_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_FLEXSPI0_OTFAD_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_FLEXSPI0_OTFAD_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_FLEXSPI0_OTFAD_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_OTP_CTLR_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_OTP_CTLR_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_OTP_CTLR_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_FLEXSPI1_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_FLEXSPI1_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_FLEXSPI1_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_USBHS_PHY_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_USBHS_PHY_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_USBHS_PHY_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_USBHS_DEVICE_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_USBHS_DEVICE_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_USBHS_DEVICE_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_USBHS_HOST_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_USBHS_HOST_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_USBHS_HOST_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_USBHS_SRAM_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_USBHS_SRAM_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_USBHS_SRAM_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_SCT_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_SCT_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_SCT_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_GPU_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_GPU_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_GPU_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_DISPLAY_CTLR_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_DISPLAY_CTLR_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_DISPLAY_CTLR_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_MIPI_DSI_CTLR_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_MIPI_DSI_CTLR_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_MIPI_DSI_CTLR_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_SET_SMARTDMA_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_SET_SMARTDMA_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL0_SET_SMARTDMA_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL1_SET_SDIO0_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL1 register */
+ RT500_CLKCTL0_PSCCTL1_SET_SDIO0_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL1_SET_SDIO0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL1_SET_SDIO1_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL1 register */
+ RT500_CLKCTL0_PSCCTL1_SET_SDIO1_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL1_SET_SDIO1_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL1_SET_ACMP0_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL1 register */
+ RT500_CLKCTL0_PSCCTL1_SET_ACMP0_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL1_SET_ACMP0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL1_SET_ADC0_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL1 register */
+ RT500_CLKCTL0_PSCCTL1_SET_ADC0_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL1_SET_ADC0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL1_SET_SHSGPIO0_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL1 register */
+ RT500_CLKCTL0_PSCCTL1_SET_SHSGPIO0_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL1_SET_SHSGPIO0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL2_SET_UTICK0_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL2 register */
+ RT500_CLKCTL0_PSCCTL2_SET_UTICK0_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL2_SET_UTICK0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL2_SET_WWDT0_CLK_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL2 register */
+ RT500_CLKCTL0_PSCCTL2_SET_WWDT0_CLK_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL2_SET_WWDT0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL2_SET_PMC_NO_EFFECT = 0,
+ /* Sets the corresponding bit in PSCCTL2 register */
+ RT500_CLKCTL0_PSCCTL2_SET_PMC_CLK_ENABLE_SET = 1,
+} RT500_CLKCTL0_PSCCTL2_SET_PMC_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_DSP_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_DSP_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_DSP_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_ROM_CTRLR_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_ROM_CTRLR_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_ROM_CTRLR_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_AXI_SWITCH_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_AXI_SWITCH_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_AXI_SWITCH_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_AXI_CTLR_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_AXI_CTLR_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_AXI_CTLR_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_POWERQUAD_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_POWERQUAD_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_POWERQUAD_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_CASPER_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_CASPER_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_CASPER_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_HASHCRYPT_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_HASHCRYPT_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_HASHCRYPT_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_PUF_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_PUF_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_PUF_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_RNG_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_RNG_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_RNG_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_FLEXSPI0_OTFAD_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_FLEXSPI0_OTFAD_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_FLEXSPI0_OTFAD_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_OTP_CTLR_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_OTP_CTLR_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_OTP_CTLR_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_FLEXSPI1_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_FLEXSPI1_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_FLEXSPI1_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_USBHS_PHY_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_USBHS_PHY_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_USBHS_PHY_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_USBHS_DEVICE_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_USBHS_DEVICE_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_USBHS_DEVICE_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_USBHS_HOST_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_USBHS_HOST_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_USBHS_HOST_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_USBHS_SRAM_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_USBHS_SRAM_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_USBHS_SRAM_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_SCT_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_SCT_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_SCT_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_GPU_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_GPU_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_GPU_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_DISPLAY_CTLR_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_DISPLAY_CTLR_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_DISPLAY_CTLR_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_MIPI_DSI_CTLR_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_MIPI_DSI_CTLR_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_MIPI_DSI_CTLR_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL0_CLR_SMARTDMA_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL0 register */
+ RT500_CLKCTL0_PSCCTL0_CLR_SMARTDMA_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL0_CLR_SMARTDMA_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL1_CLR_SDIO0_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL1 register */
+ RT500_CLKCTL0_PSCCTL1_CLR_SDIO0_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL1_CLR_SDIO0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL1_CLR_SDIO1_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL1 register */
+ RT500_CLKCTL0_PSCCTL1_CLR_SDIO1_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL1_CLR_SDIO1_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL1_CLR_ACMP0_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL1 register */
+ RT500_CLKCTL0_PSCCTL1_CLR_ACMP0_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL1_CLR_ACMP0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL1_CLR_ADC0_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL1 register */
+ RT500_CLKCTL0_PSCCTL1_CLR_ADC0_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL1_CLR_ADC0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL1_CLR_SHSGPIO0_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL1 register */
+ RT500_CLKCTL0_PSCCTL1_CLR_SHSGPIO0_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL1_CLR_SHSGPIO0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL2_CLR_UTICK0_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL2 register */
+ RT500_CLKCTL0_PSCCTL2_CLR_UTICK0_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL2_CLR_UTICK0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL2_CLR_WWDT0_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL2 register */
+ RT500_CLKCTL0_PSCCTL2_CLR_WWDT0_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL2_CLR_WWDT0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PSCCTL2_CLR_PMC_CLK_NO_EFFECT = 0,
+ /* Clears the corresponding bit in PSCCTL2 register */
+ RT500_CLKCTL0_PSCCTL2_CLR_PMC_CLK_CLK_ENABLE_CLEAR = 1,
+} RT500_CLKCTL0_PSCCTL2_CLR_PMC_CLK_Enum;
+
+typedef enum {
+ /* Stop tuning */
+ RT500_CLKCTL0_FRO_CONTROL_ENA_TUNE_ENA_TUNE_CLEAR = 0,
+ /* Start tuning */
+ RT500_CLKCTL0_FRO_CONTROL_ENA_TUNE_ENA_TUNE_START = 1,
+} RT500_CLKCTL0_FRO_CONTROL_ENA_TUNE_Enum;
+
+typedef enum {
+ /* CAPVAL data is not valid */
+ RT500_CLKCTL0_FRO_CAPVAL_DATA_VALID_DATA_NOT_VALID = 0,
+ /* CAPVAL data is valid */
+ RT500_CLKCTL0_FRO_CAPVAL_DATA_VALID_DATA_VALID = 1,
+} RT500_CLKCTL0_FRO_CAPVAL_DATA_VALID_Enum;
+
+typedef enum {
+ /* FRO_DIV2 */
+ RT500_CLKCTL0_FRODIVSEL_SEL_DIVIDEBY2 = 0,
+ /* FRO_DIV4 */
+ RT500_CLKCTL0_FRODIVSEL_SEL_DIVIDEBY4 = 1,
+ /* FRO_DIV8 */
+ RT500_CLKCTL0_FRODIVSEL_SEL_DIVIDEBY8 = 2,
+ /* FRO_DIV16 */
+ RT500_CLKCTL0_FRODIVSEL_SEL_DIVIDEBY16 = 3,
+} RT500_CLKCTL0_FRODIVSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO clock has not yet reached 10% frequency accuracy */
+ RT500_CLKCTL0_FROCLKSTATUS_CLK_OK_CLK_NOT_OK = 0,
+ /* FRO clock has reached 10% frequency accuracy */
+ RT500_CLKCTL0_FROCLKSTATUS_CLK_OK_CLK_OK = 1,
+} RT500_CLKCTL0_FROCLKSTATUS_CLK_OK_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_FRODIVOEN_FRO_DIV1_O_EN_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_FRODIVOEN_FRO_DIV1_O_EN_CLK_ENABLE = 1,
+} RT500_CLKCTL0_FRODIVOEN_FRO_DIV1_O_EN_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_FRODIVOEN_FRO_DIV2_O_EN_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_FRODIVOEN_FRO_DIV2_O_EN_CLK_ENABLE = 1,
+} RT500_CLKCTL0_FRODIVOEN_FRO_DIV2_O_EN_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_FRODIVOEN_FRO_DIV4_O_EN_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_FRODIVOEN_FRO_DIV4_O_EN_CLK_ENABLE = 1,
+} RT500_CLKCTL0_FRODIVOEN_FRO_DIV4_O_EN_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_FRODIVOEN_FRO_DIV8_O_EN_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_FRODIVOEN_FRO_DIV8_O_EN_CLK_ENABLE = 1,
+} RT500_CLKCTL0_FRODIVOEN_FRO_DIV8_O_EN_Enum;
+
+typedef enum {
+ /* Disable clock */
+ RT500_CLKCTL0_FRODIVOEN_FRO_DIV16_O_EN_CLK_DISABLE = 0,
+ /* Enable clock */
+ RT500_CLKCTL0_FRODIVOEN_FRO_DIV16_O_EN_CLK_ENABLE = 1,
+} RT500_CLKCTL0_FRODIVOEN_FRO_DIV16_O_EN_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_LOWFREQCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_LOWFREQCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_LOWFREQCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_LOWFREQCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_LOWFREQCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_LOWFREQCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The Divider change has finished */
+ RT500_CLKCTL0_LOWFREQCLKDIV_REQFLAG_REQFLAG_CHANGE_FINISHED = 0,
+ /* The Divider value has changed */
+ RT500_CLKCTL0_LOWFREQCLKDIV_REQFLAG_REQFLAG_CHANGED = 1,
+} RT500_CLKCTL0_LOWFREQCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* Enable High Gain Mode (HP) */
+ RT500_CLKCTL0_SYSOSCCTL0_LP_ENABLE_HIGH_GAIN_ENABLE = 0,
+ /* Enable Low Power mode (LP) */
+ RT500_CLKCTL0_SYSOSCCTL0_LP_ENABLE_LOW_POWER_ENABLE = 1,
+} RT500_CLKCTL0_SYSOSCCTL0_LP_ENABLE_Enum;
+
+typedef enum {
+ /* Enable Normal mode. Oscillation with crystal connected. */
+ RT500_CLKCTL0_SYSOSCCTL0_BYPASS_ENABLE_NORMAL_ENABLE = 0,
+ /*
+ * Enable Bypass mode. In this mode a clock can be directly input into the
+ * XTALIN pin.
+ */
+ RT500_CLKCTL0_SYSOSCCTL0_BYPASS_ENABLE_BYPASS_ENABLE = 1,
+} RT500_CLKCTL0_SYSOSCCTL0_BYPASS_ENABLE_Enum;
+
+typedef enum {
+ /* Select OSC Clock */
+ RT500_CLKCTL0_SYSOSCBYPASS_SEL_SYOSC_CLOCK = 0,
+ /* Select Clock IN clock */
+ RT500_CLKCTL0_SYSOSCBYPASS_SEL_CLOCK_IN = 1,
+ /* None; this may be selected to reduce power when no output is needed */
+ RT500_CLKCTL0_SYSOSCBYPASS_SEL_NONE = 7,
+} RT500_CLKCTL0_SYSOSCBYPASS_SEL_Enum;
+
+typedef enum {
+ /* LPOSC clock is not ready */
+ RT500_CLKCTL0_LPOSCCTL0_CLKRDY_CLK_NOT_READY = 0,
+ /* LPOSC clock is ready */
+ RT500_CLKCTL0_LPOSCCTL0_CLKRDY_CLK_READY = 1,
+} RT500_CLKCTL0_LPOSCCTL0_CLKRDY_Enum;
+
+typedef enum {
+ /* Disable oscillator */
+ RT500_CLKCTL0_OSC32KHZCTL0_ENA32KHZ_ENA32KHZ_DISABLE = 0,
+ /* Enable oscillator */
+ RT500_CLKCTL0_OSC32KHZCTL0_ENA32KHZ_ENA32KHZ_ENABLE = 1,
+} RT500_CLKCTL0_OSC32KHZCTL0_ENA32KHZ_Enum;
+
+typedef enum {
+ /* FRO_DIV8 Clock */
+ RT500_CLKCTL0_SYSPLL0CLKSEL_SEL_FRRO_DIV8 = 0,
+ /* OSC_CLK clock */
+ RT500_CLKCTL0_SYSPLL0CLKSEL_SEL_OSC_CLK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL0_SYSPLL0CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_SYSPLL0CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* PFD outputs are PFD-programmed clocks */
+ RT500_CLKCTL0_SYSPLL0CTL0_BYPASS_PFD = 0,
+ /*
+ * Bypass Mode: PFD outputs are sourced directly from rhe reference input
+ * clock
+ */
+ RT500_CLKCTL0_SYSPLL0CTL0_BYPASS_BYPASS = 1,
+} RT500_CLKCTL0_SYSPLL0CTL0_BYPASS_Enum;
+
+typedef enum {
+ /* SYSPLL0 reset is removed */
+ RT500_CLKCTL0_SYSPLL0CTL0_RESET_NO_RESET = 0,
+ /* SYSPLL0 is placed into reset */
+ RT500_CLKCTL0_SYSPLL0CTL0_RESET_RESET = 1,
+} RT500_CLKCTL0_SYSPLL0CTL0_RESET_Enum;
+
+typedef enum {
+ /* Disable */
+ RT500_CLKCTL0_SYSPLL0CTL0_HOLDRINGOFF_ENA_DISABLE = 0,
+ /* Enable */
+ RT500_CLKCTL0_SYSPLL0CTL0_HOLDRINGOFF_ENA_ENABLE = 1,
+} RT500_CLKCTL0_SYSPLL0CTL0_HOLDRINGOFF_ENA_Enum;
+
+typedef enum {
+ /* Multiply by 16 */
+ RT500_CLKCTL0_SYSPLL0CTL0_MULT_DIV16 = 16,
+ /* Multiply by 17 */
+ RT500_CLKCTL0_SYSPLL0CTL0_MULT_DIV17 = 17,
+ /* Multiply by 18 */
+ RT500_CLKCTL0_SYSPLL0CTL0_MULT_DIV18 = 18,
+ /* Multiply by 19 */
+ RT500_CLKCTL0_SYSPLL0CTL0_MULT_DIV19 = 19,
+ /* Multiply by 20 */
+ RT500_CLKCTL0_SYSPLL0CTL0_MULT_DIV20 = 20,
+ /* Multiply by 21 */
+ RT500_CLKCTL0_SYSPLL0CTL0_MULT_DIV21 = 21,
+ /* Multiply by 22 */
+ RT500_CLKCTL0_SYSPLL0CTL0_MULT_DIV22 = 22,
+} RT500_CLKCTL0_SYSPLL0CTL0_MULT_Enum;
+
+typedef enum {
+ /* PFD0 clock is not ready */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD0_CLKRDY_NOTREADY = 0,
+ /* PFD0 clock is ready */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD0_CLKRDY_READY = 1,
+} RT500_CLKCTL0_SYSPLL0PFD_PFD0_CLKRDY_Enum;
+
+typedef enum {
+ /* PFD0 clock is not gated */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD0_CLKGATE_NOTGATED = 0,
+ /* PFD0 clock is gated */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD0_CLKGATE_GATED = 1,
+} RT500_CLKCTL0_SYSPLL0PFD_PFD0_CLKGATE_Enum;
+
+typedef enum {
+ /* PFD1 clock is not ready */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD1_CLKRDY_NOTREADY = 0,
+ /* PFD1 clock is ready */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD1_CLKRDY_READY = 1,
+} RT500_CLKCTL0_SYSPLL0PFD_PFD1_CLKRDY_Enum;
+
+typedef enum {
+ /* PFD1 clock is not gated */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD1_CLKGATE_NOTGATED = 0,
+ /* PFD1 clock is gated */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD1_CLKGATE_GATED = 1,
+} RT500_CLKCTL0_SYSPLL0PFD_PFD1_CLKGATE_Enum;
+
+typedef enum {
+ /* PFD2 clock is not ready */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD2_CLKRDY_NOTREADY = 0,
+ /* PFD2 clock is ready */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD2_CLKRDY_READY = 1,
+} RT500_CLKCTL0_SYSPLL0PFD_PFD2_CLKRDY_Enum;
+
+typedef enum {
+ /* PFD2 clock is not gated */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD2_CLKGATE_NOTGATED = 0,
+ /* PFD2 clock is gated */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD2_CLKGATE_GATED = 1,
+} RT500_CLKCTL0_SYSPLL0PFD_PFD2_CLKGATE_Enum;
+
+typedef enum {
+ /* PFD3 clock is not ready */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD3_CLKRDY_NOTREADY = 0,
+ /* PFD3 clock is ready */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD3_CLKRDY_READY = 1,
+} RT500_CLKCTL0_SYSPLL0PFD_PFD3_CLKRDY_Enum;
+
+typedef enum {
+ /* PFD3 clock is not gated */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD3_CLKGATE_NOTGATED = 0,
+ /* PFD3 clock is gated */
+ RT500_CLKCTL0_SYSPLL0PFD_PFD3_CLKGATE_GATED = 1,
+} RT500_CLKCTL0_SYSPLL0PFD_PFD3_CLKGATE_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_SYSCPUAHBCLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_SYSCPUAHBCLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_SYSCPUAHBCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* Low Power Oscillator Clock (LPOSC) */
+ RT500_CLKCTL0_MAINCLKSELA_SEL_LPOSC = 0,
+ /* FRODIV which is the output of the FRODIVSEL mux */
+ RT500_CLKCTL0_MAINCLKSELA_SEL_FRO_8 = 1,
+ /* OSC_CLK clock */
+ RT500_CLKCTL0_MAINCLKSELA_SEL_OSC_CLK = 2,
+ /* FRO_DIV1 clock */
+ RT500_CLKCTL0_MAINCLKSELA_SEL_FRO = 3,
+} RT500_CLKCTL0_MAINCLKSELA_SEL_Enum;
+
+typedef enum {
+ /* MAINCLKSELA 1st Stage Clock */
+ RT500_CLKCTL0_MAINCLKSELB_SEL_MAINCLKSELA = 0,
+ /* Main System PLL Clock */
+ RT500_CLKCTL0_MAINCLKSELB_SEL_SYSPLL = 1,
+ /* RTC 32 KHz Clock */
+ RT500_CLKCTL0_MAINCLKSELB_SEL_RTC32KHZ = 2,
+} RT500_CLKCTL0_MAINCLKSELB_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PFC0DIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_PFC0DIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_PFC0DIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PFC0DIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_PFC0DIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_PFC0DIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_PFC0DIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_PFC0DIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_PFC0DIV_REQFLAG_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PFC1DIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_PFC1DIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_PFC1DIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_PFC1DIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_PFC1DIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_PFC1DIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_PFC1DIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_PFC1DIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_PFC1DIV_REQFLAG_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL0_FLEXSPI0FCLKSEL_SEL_MAIN = 0,
+ /* Main System PLL Clock */
+ RT500_CLKCTL0_FLEXSPI0FCLKSEL_SEL_PLL = 1,
+ /* SYSPLL0 AUX0_PLL_Clock */
+ RT500_CLKCTL0_FLEXSPI0FCLKSEL_SEL_AUX0_PLL = 2,
+ /* FRO_DIV1 Clock */
+ RT500_CLKCTL0_FLEXSPI0FCLKSEL_SEL_FRO_192M = 3,
+ /* SYSPLL0 AUX1_PLL_Clock */
+ RT500_CLKCTL0_FLEXSPI0FCLKSEL_SEL_AUX1_PLL = 4,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_FLEXSPI0FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_FLEXSPI0FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_FLEXSPI0FCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_FLEXSPI0FCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_FLEXSPI0FCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_FLEXSPI0FCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_FLEXSPI0FCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_FLEXSPI0FCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_FLEXSPI0FCLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_FLEXSPI0FCLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_FLEXSPI0FCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL0_FLEXSPI1FCLKSEL_SEL_MAIN = 0,
+ /* Main System PLL Clock */
+ RT500_CLKCTL0_FLEXSPI1FCLKSEL_SEL_PLL = 1,
+ /* SYSPLL0 AUX0_PLL_Clock */
+ RT500_CLKCTL0_FLEXSPI1FCLKSEL_SEL_AUX0_PLL = 2,
+ /* FRO_DIV1 Clock */
+ RT500_CLKCTL0_FLEXSPI1FCLKSEL_SEL_FRO_192M = 3,
+ /* SYSPLL0 AUX1_PLL_Clock */
+ RT500_CLKCTL0_FLEXSPI1FCLKSEL_SEL_AUX1_PLL = 4,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_FLEXSPI1FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_FLEXSPI1FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_FLEXSPI1FCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_FLEXSPI1FCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_FLEXSPI1FCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_FLEXSPI1FCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_FLEXSPI1FCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_FLEXSPI1FCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_FLEXSPI1FCLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_FLEXSPI1FCLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_FLEXSPI1FCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL0_SCTFCLKSEL_SEL_MAIN = 0,
+ /* Main System PLL Clock */
+ RT500_CLKCTL0_SCTFCLKSEL_SEL_PLL = 1,
+ /* SYSPLL0 AUX0_PLL_Clock */
+ RT500_CLKCTL0_SCTFCLKSEL_SEL_AUX0_PLL = 2,
+ /* FRO_DIV1 Clock */
+ RT500_CLKCTL0_SCTFCLKSEL_SEL_FRO_192M = 3,
+ /* SYSPLL0 AUX1_PLL_Clock */
+ RT500_CLKCTL0_SCTFCLKSEL_SEL_AUX1_PLL = 4,
+ /* AUDIO PLL Clock */
+ RT500_CLKCTL0_SCTFCLKSEL_SEL_AUDIO_PLL = 5,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_SCTFCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_SCTFCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_SCTIN7CLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_SCTIN7CLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_SCTIN7CLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_SCTIN7CLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_SCTIN7CLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_SCTIN7CLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_SCTIN7CLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_SCTIN7CLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_SCTIN7CLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* OSC_CLK Clock */
+ RT500_CLKCTL0_USBHSFCLKSEL_SEL_OSC_CLK = 0,
+ /* Main Clock */
+ RT500_CLKCTL0_USBHSFCLKSEL_SEL_MAIN = 1,
+ /* AUX0_PLL_CLOCK */
+ RT500_CLKCTL0_USBHSFCLKSEL_SEL_AUX0_PLL_CLOCK = 3,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_USBHSFCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_USBHSFCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_USBHSFCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_USBHSFCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_USBHSFCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_USBHSFCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_USBHSFCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_USBHSFCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_USBHSFCLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_USBHSFCLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_USBHSFCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL0_SDIO0FCLKSEL_SEL_MAIN = 0,
+ /* System PLL Clock */
+ RT500_CLKCTL0_SDIO0FCLKSEL_SEL_PLL = 1,
+ /* SYSPLL0 AUX0_PLL_Clock */
+ RT500_CLKCTL0_SDIO0FCLKSEL_SEL_AUX0_PLL = 2,
+ /* FRO_DIV2 */
+ RT500_CLKCTL0_SDIO0FCLKSEL_SEL_FRO_DIV2 = 3,
+ /* SYSPLL0 AUX1_PLL_Clock */
+ RT500_CLKCTL0_SDIO0FCLKSEL_SEL_AUX1_PLL = 4,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_SDIO0FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_SDIO0FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_SDIO0FCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_SDIO0FCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_SDIO0FCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_SDIO0FCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_SDIO0FCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_SDIO0FCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_SDIO0FCLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_SDIO0FCLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_SDIO0FCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL0_SDIO1FCLKSEL_SEL_MAIN = 0,
+ /* Main System PLL Clock */
+ RT500_CLKCTL0_SDIO1FCLKSEL_SEL_PLL = 1,
+ /* SYSPLL0 AUX0_PLL_Clock */
+ RT500_CLKCTL0_SDIO1FCLKSEL_SEL_AUX0_PLL = 2,
+ /* FRO_DIV2 */
+ RT500_CLKCTL0_SDIO1FCLKSEL_SEL_FRO_DIV2 = 3,
+ /* SYSPLL0 AUX1_PLL_Clock */
+ RT500_CLKCTL0_SDIO1FCLKSEL_SEL_AUX1_PLL = 4,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_SDIO1FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_SDIO1FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_SDIO1FCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_SDIO1FCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_SDIO1FCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_SDIO1FCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_SDIO1FCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_SDIO1FCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_SDIO1FCLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_SDIO1FCLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_SDIO1FCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* OSC_CLK Clock */
+ RT500_CLKCTL0_ADC0FCLKSEL0_SEL_OSC_CLK = 0,
+ /* Low Power Oscillator Clock (LPOSC) */
+ RT500_CLKCTL0_ADC0FCLKSEL0_SEL_LPOSC = 1,
+ /* FRO_DIV4 */
+ RT500_CLKCTL0_ADC0FCLKSEL0_SEL_FRO_DIV4 = 2,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_ADC0FCLKSEL0_SEL_NONE = 7,
+} RT500_CLKCTL0_ADC0FCLKSEL0_SEL_Enum;
+
+typedef enum {
+ /* ADC0FCLKSEL0 Multiplexed Output */
+ RT500_CLKCTL0_ADC0FCLKSEL1_SEL_ADC0FCLKSEL0_MUX = 0,
+ /* SYSPLL0 MAIN_CLK (PFD0 Output) */
+ RT500_CLKCTL0_ADC0FCLKSEL1_SEL_SYSPLL0_MAIN = 1,
+ /* SYSPLL0 AUX0_PLL_Clock */
+ RT500_CLKCTL0_ADC0FCLKSEL1_SEL_SYSPLL0_AUX0_PLL = 2,
+ /* SYSPLL0 AUX1_PLL_Clock */
+ RT500_CLKCTL0_ADC0FCLKSEL1_SEL_SYSPLL0_AUX1_PLL = 3,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_ADC0FCLKSEL1_SEL_NONE = 7,
+} RT500_CLKCTL0_ADC0FCLKSEL1_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_ADC0FCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_ADC0FCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_ADC0FCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_ADC0FCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_ADC0FCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_ADC0FCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_ADC0FCLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_ADC0FCLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_ADC0FCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* Low Power Oscillator Clock (LPOSC) */
+ RT500_CLKCTL0_UTICKFCLKSEL_SEL_LPOSC = 0,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_UTICKFCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_UTICKFCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Low Power Oscillator Clock (LPOSC) */
+ RT500_CLKCTL0_WDT0FCLKSEL_SEL_LPOSC = 0,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_WDT0FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_WDT0FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* 32 KHz */
+ RT500_CLKCTL0_A32KHZWAKECLKSEL_SEL_A32KHZ = 0,
+ /* Low Power Oscillator Clock (LPOSC); divided by 32 by default */
+ RT500_CLKCTL0_A32KHZWAKECLKSEL_SEL_LPOSC = 1,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_A32KHZWAKECLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_A32KHZWAKECLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_A32KHZWAKECLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_A32KHZWAKECLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_A32KHZWAKECLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_A32KHZWAKECLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_A32KHZWAKECLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_A32KHZWAKECLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_A32KHZWAKECLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_A32KHZWAKECLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_A32KHZWAKECLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* Systick Divider Output Clock */
+ RT500_CLKCTL0_SYSTICKFCLKSEL_SEL_SYSTICK_DIV_OUTPUT = 0,
+ /* Low Power Oscillator Clock (LPOSC) */
+ RT500_CLKCTL0_SYSTICKFCLKSEL_SEL_LPOSC = 1,
+ /* 32 KHz RTC Clock */
+ RT500_CLKCTL0_SYSTICKFCLKSEL_SEL_A32KHZ_RTC = 2,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_SYSTICKFCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_SYSTICKFCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_SYSTICKFCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_SYSTICKFCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_SYSTICKFCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_SYSTICKFCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_SYSTICKFCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_SYSTICKFCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_SYSTICKFCLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_SYSTICKFCLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_SYSTICKFCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* FRO_DIV1 Clock */
+ RT500_CLKCTL0_DPHYCLKSEL_SEL_FRO = 0,
+ /* SYSPLL0 MAIN_CLK (PFD0 Output) */
+ RT500_CLKCTL0_DPHYCLKSEL_SEL_SYSPLL0_MAIN = 1,
+ /* SYSPLL0 AUX0_PLL_Clock */
+ RT500_CLKCTL0_DPHYCLKSEL_SEL_SYSPLL0_AUX0 = 2,
+ /* SYSPLL0 AUX1_PLL_Clock */
+ RT500_CLKCTL0_DPHYCLKSEL_SEL_SYSPLL0_AUX1 = 3,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_DPHYCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_DPHYCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_DPHYCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_DPHYCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_DPHYCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_DPHYCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_DPHYCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_DPHYCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_DPHYCLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_DPHYCLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_DPHYCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* FRO_DIV1 clock */
+ RT500_CLKCTL0_DPHYESCCLKSEL_SEL_FRO_DIV1 = 0,
+ /* FRO_DIV16 Clock */
+ RT500_CLKCTL0_DPHYESCCLKSEL_SEL_FRO_DIV16 = 1,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_DPHYESCCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_DPHYESCCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_DPHYESCRXCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_DPHYESCRXCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_DPHYESCRXCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_DPHYESCRXCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_DPHYESCRXCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_DPHYESCRXCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_DPHYESCRXCLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_DPHYESCRXCLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_DPHYESCRXCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_DPHYESCTXCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_DPHYESCTXCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_DPHYESCTXCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_DPHYESCTXCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_DPHYESCTXCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_DPHYESCTXCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_DPHYESCTXCLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_DPHYESCTXCLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_DPHYESCTXCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL0_GPUCLKSEL_SEL_MAIN = 0,
+ /* FRO_DIV1 clock */
+ RT500_CLKCTL0_GPUCLKSEL_SEL_FRO = 1,
+ /* SYSPLL0 MAIN_CLK (PFD0 Output) */
+ RT500_CLKCTL0_GPUCLKSEL_SEL_SYSPLL0_MAIN = 2,
+ /* SYSPLL0 AUX0_PLL_Clock */
+ RT500_CLKCTL0_GPUCLKSEL_SEL_SYSPLL0_AUX0 = 3,
+ /* SYSPLL0 AUX1_PLL_Clock */
+ RT500_CLKCTL0_GPUCLKSEL_SEL_SYSPLL0_AUX1 = 4,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_GPUCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_GPUCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_GPUCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_GPUCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_GPUCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_GPUCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_GPUCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_GPUCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_GPUCLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_GPUCLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_GPUCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* MIPI-DSI PHY Clock */
+ RT500_CLKCTL0_DCPIXELCLKSEL_SEL_MIPI_DSI_PHY = 0,
+ /* Main Clock */
+ RT500_CLKCTL0_DCPIXELCLKSEL_SEL_MAIN = 1,
+ /* FRO_DIV1 Clock */
+ RT500_CLKCTL0_DCPIXELCLKSEL_SEL_FRO = 2,
+ /* SYSPLL0 MAIN_CLK (PFD0 Output) */
+ RT500_CLKCTL0_DCPIXELCLKSEL_SEL_SYSPLL0_MAIN = 3,
+ /* SYSPLL0 AUX0_PLL_Clock */
+ RT500_CLKCTL0_DCPIXELCLKSEL_SEL_SYSPLL0_AUX0 = 4,
+ /* SYSPLL0 AUX1_PLL_Clock */
+ RT500_CLKCTL0_DCPIXELCLKSEL_SEL_SYSPLL0_AUX1 = 5,
+ /* None; this may be selected to reduce power when no output is needed. */
+ RT500_CLKCTL0_DCPIXELCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL0_DCPIXELCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_DCPIXELCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL0_DCPIXELCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL0_DCPIXELCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL0_DCPIXELCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL0_DCPIXELCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL0_DCPIXELCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The change to the divider value has finished */
+ RT500_CLKCTL0_DCPIXELCLKDIV_REQFLAG_DIVIDER_READY = 0,
+ /* A change is being made to the divider value */
+ RT500_CLKCTL0_DCPIXELCLKDIV_REQFLAG_DIVIDER_NOT_READY = 1,
+} RT500_CLKCTL0_DCPIXELCLKDIV_REQFLAG_Enum;
+
+
+#define RT500_CLKCTL0_REGISTER_ACCESS_INFO_ARRAY(_name) \
+ struct RegisterAccessInfo _name[RT500_CLKCTL0_REGS_NO] = { \
+ [0 ... RT500_CLKCTL0_REGS_NO - 1] = { \
+ .name = "", \
+ .addr = -1, \
+ }, \
+ [R_RT500_CLKCTL0_PSCCTL0] = { \
+ .name = "PSCCTL0", \
+ .addr = 0x10, \
+ .ro = 0xA208E0E1, \
+ .reset = 0x5, \
+ }, \
+ [R_RT500_CLKCTL0_PSCCTL1] = { \
+ .name = "PSCCTL1", \
+ .addr = 0x14, \
+ .ro = 0xFEFE7FF3, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_PSCCTL2] = { \
+ .name = "PSCCTL2", \
+ .addr = 0x18, \
+ .ro = 0xDFFFFFFC, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_PSCCTL0_SET] = { \
+ .name = "PSCCTL0_SET", \
+ .addr = 0x40, \
+ .ro = 0xA208E0E1, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_PSCCTL1_SET] = { \
+ .name = "PSCCTL1_SET", \
+ .addr = 0x44, \
+ .ro = 0xFEFE7FF3, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_PSCCTL2_SET] = { \
+ .name = "PSCCTL2_SET", \
+ .addr = 0x48, \
+ .ro = 0xDFFFFFFC, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_PSCCTL0_CLR] = { \
+ .name = "PSCCTL0_CLR", \
+ .addr = 0x70, \
+ .ro = 0xA208E0E1, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_PSCCTL1_CLR] = { \
+ .name = "PSCCTL1_CLR", \
+ .addr = 0x74, \
+ .ro = 0xFEFE7FF3, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_PSCCTL2_CLR] = { \
+ .name = "PSCCTL2_CLR", \
+ .addr = 0x78, \
+ .ro = 0xDFFFFFFC, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_FRO_CONTROL] = { \
+ .name = "FRO_CONTROL", \
+ .addr = 0x80, \
+ .ro = 0x7C000000, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_FRO_CAPVAL] = { \
+ .name = "FRO_CAPVAL", \
+ .addr = 0x84, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_FRO_RDTRIM] = { \
+ .name = "FRO_RDTRIM", \
+ .addr = 0x8C, \
+ .ro = 0xFFFFF800, \
+ .reset = 0x3BF, \
+ }, \
+ [R_RT500_CLKCTL0_FRO_SCTRIM] = { \
+ .name = "FRO_SCTRIM", \
+ .addr = 0x90, \
+ .ro = 0xFFFFFFC0, \
+ .reset = 0x20, \
+ }, \
+ [R_RT500_CLKCTL0_FRODIVSEL] = { \
+ .name = "FRODIVSEL", \
+ .addr = 0x108, \
+ .ro = 0xFFFFFFFC, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_FROCLKSTATUS] = { \
+ .name = "FROCLKSTATUS", \
+ .addr = 0x10C, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_FRODIVOEN] = { \
+ .name = "FRODIVOEN", \
+ .addr = 0x110, \
+ .ro = 0xFFFFFFE0, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_LOWFREQCLKDIV] = { \
+ .name = "LOWFREQCLKDIV", \
+ .addr = 0x130, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_SYSOSCCTL0] = { \
+ .name = "SYSOSCCTL0", \
+ .addr = 0x160, \
+ .ro = 0xFFFFFFFC, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_SYSOSCBYPASS] = { \
+ .name = "SYSOSCBYPASS", \
+ .addr = 0x168, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_LPOSCCTL0] = { \
+ .name = "LPOSCCTL0", \
+ .addr = 0x190, \
+ .ro = 0x7FFFFFFF, \
+ .reset = 0x807BC4D4, \
+ }, \
+ [R_RT500_CLKCTL0_OSC32KHZCTL0] = { \
+ .name = "OSC32KHZCTL0", \
+ .addr = 0x1C0, \
+ .ro = 0xFFFFFFFE, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_SYSPLL0CLKSEL] = { \
+ .name = "SYSPLL0CLKSEL", \
+ .addr = 0x200, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_SYSPLL0CTL0] = { \
+ .name = "SYSPLL0CTL0", \
+ .addr = 0x204, \
+ .ro = 0xFF00DFFC, \
+ .reset = 0x160002, \
+ }, \
+ [R_RT500_CLKCTL0_SYSPLL0LOCKTIMEDIV2] = { \
+ .name = "SYSPLL0LOCKTIMEDIV2", \
+ .addr = 0x20C, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xCAFE, \
+ }, \
+ [R_RT500_CLKCTL0_SYSPLL0NUM] = { \
+ .name = "SYSPLL0NUM", \
+ .addr = 0x210, \
+ .ro = 0xC0000000, \
+ .reset = 0x4DD2F15, \
+ }, \
+ [R_RT500_CLKCTL0_SYSPLL0DENOM] = { \
+ .name = "SYSPLL0DENOM", \
+ .addr = 0x214, \
+ .ro = 0xC0000000, \
+ .reset = 0x1FFFFFDB, \
+ }, \
+ [R_RT500_CLKCTL0_SYSPLL0PFD] = { \
+ .name = "SYSPLL0PFD", \
+ .addr = 0x218, \
+ .ro = 0x0, \
+ .reset = 0x80808080, \
+ }, \
+ [R_RT500_CLKCTL0_MAINPLLCLKDIV] = { \
+ .name = "MAINPLLCLKDIV", \
+ .addr = 0x240, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_DSPPLLCLKDIV] = { \
+ .name = "DSPPLLCLKDIV", \
+ .addr = 0x244, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_AUX0PLLCLKDIV] = { \
+ .name = "AUX0PLLCLKDIV", \
+ .addr = 0x248, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_AUX1PLLCLKDIV] = { \
+ .name = "AUX1PLLCLKDIV", \
+ .addr = 0x24C, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_SYSCPUAHBCLKDIV] = { \
+ .name = "SYSCPUAHBCLKDIV", \
+ .addr = 0x400, \
+ .ro = 0x7FFFFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_MAINCLKSELA] = { \
+ .name = "MAINCLKSELA", \
+ .addr = 0x430, \
+ .ro = 0xFFFFFFFC, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_MAINCLKSELB] = { \
+ .name = "MAINCLKSELB", \
+ .addr = 0x434, \
+ .ro = 0xFFFFFFFC, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_PFC0DIV] = { \
+ .name = "PFC0DIV", \
+ .addr = 0x500, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL0_PFC1DIV] = { \
+ .name = "PFC1DIV", \
+ .addr = 0x504, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL0_FLEXSPI0FCLKSEL] = { \
+ .name = "FLEXSPI0FCLKSEL", \
+ .addr = 0x620, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_FLEXSPI0FCLKDIV] = { \
+ .name = "FLEXSPI0FCLKDIV", \
+ .addr = 0x624, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL0_FLEXSPI1FCLKSEL] = { \
+ .name = "FLEXSPI1FCLKSEL", \
+ .addr = 0x630, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_FLEXSPI1FCLKDIV] = { \
+ .name = "FLEXSPI1FCLKDIV", \
+ .addr = 0x634, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL0_SCTFCLKSEL] = { \
+ .name = "SCTFCLKSEL", \
+ .addr = 0x640, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_SCTIN7CLKDIV] = { \
+ .name = "SCTIN7CLKDIV", \
+ .addr = 0x644, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL0_USBHSFCLKSEL] = { \
+ .name = "USBHSFCLKSEL", \
+ .addr = 0x660, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_USBHSFCLKDIV] = { \
+ .name = "USBHSFCLKDIV", \
+ .addr = 0x664, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL0_SDIO0FCLKSEL] = { \
+ .name = "SDIO0FCLKSEL", \
+ .addr = 0x680, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_SDIO0FCLKDIV] = { \
+ .name = "SDIO0FCLKDIV", \
+ .addr = 0x684, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL0_SDIO1FCLKSEL] = { \
+ .name = "SDIO1FCLKSEL", \
+ .addr = 0x690, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_SDIO1FCLKDIV] = { \
+ .name = "SDIO1FCLKDIV", \
+ .addr = 0x694, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL0_ADC0FCLKSEL0] = { \
+ .name = "ADC0FCLKSEL0", \
+ .addr = 0x6D0, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_ADC0FCLKSEL1] = { \
+ .name = "ADC0FCLKSEL1", \
+ .addr = 0x6D4, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_ADC0FCLKDIV] = { \
+ .name = "ADC0FCLKDIV", \
+ .addr = 0x6D8, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL0_UTICKFCLKSEL] = { \
+ .name = "UTICKFCLKSEL", \
+ .addr = 0x700, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_WDT0FCLKSEL] = { \
+ .name = "WDT0FCLKSEL", \
+ .addr = 0x720, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL0_A32KHZWAKECLKSEL] = { \
+ .name = "A32KHZWAKECLKSEL", \
+ .addr = 0x730, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x1, \
+ }, \
+ [R_RT500_CLKCTL0_A32KHZWAKECLKDIV] = { \
+ .name = "A32KHZWAKECLKDIV", \
+ .addr = 0x734, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x1F, \
+ }, \
+ [R_RT500_CLKCTL0_SYSTICKFCLKSEL] = { \
+ .name = "SYSTICKFCLKSEL", \
+ .addr = 0x760, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_SYSTICKFCLKDIV] = { \
+ .name = "SYSTICKFCLKDIV", \
+ .addr = 0x764, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL0_DPHYCLKSEL] = { \
+ .name = "DPHYCLKSEL", \
+ .addr = 0x770, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_DPHYCLKDIV] = { \
+ .name = "DPHYCLKDIV", \
+ .addr = 0x774, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL0_DPHYESCCLKSEL] = { \
+ .name = "DPHYESCCLKSEL", \
+ .addr = 0x778, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_DPHYESCRXCLKDIV] = { \
+ .name = "DPHYESCRXCLKDIV", \
+ .addr = 0x77C, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000010, \
+ }, \
+ [R_RT500_CLKCTL0_DPHYESCTXCLKDIV] = { \
+ .name = "DPHYESCTXCLKDIV", \
+ .addr = 0x780, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000011, \
+ }, \
+ [R_RT500_CLKCTL0_GPUCLKSEL] = { \
+ .name = "GPUCLKSEL", \
+ .addr = 0x790, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_GPUCLKDIV] = { \
+ .name = "GPUCLKDIV", \
+ .addr = 0x794, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL0_DCPIXELCLKSEL] = { \
+ .name = "DCPIXELCLKSEL", \
+ .addr = 0x7A0, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL0_DCPIXELCLKDIV] = { \
+ .name = "DCPIXELCLKDIV", \
+ .addr = 0x7A4, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ }
diff --git a/include/hw/arm/svd/rt500_clkctl1.h b/include/hw/arm/svd/rt500_clkctl1.h
new file mode 100644
index 0000000000..5a83129c6e
--- /dev/null
+++ b/include/hw/arm/svd/rt500_clkctl1.h
@@ -0,0 +1,3396 @@
+/*
+ * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
+ */
+#pragma once
+
+#include "hw/register.h"
+
+/* Clock Controller 1 */
+#define RT500_CLKCTL1_REGS_NO (526)
+
+/* Clock Control 0 */
+REG32(RT500_CLKCTL1_PSCCTL0, 16);
+/* Flexcomm Interface 0 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC0_CLK, 8, 1);
+/* Flexcomm Interface 1 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC1_CLK, 9, 1);
+/* Flexcomm Interface 2 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC2_CLK, 10, 1);
+/* Flexcomm Interface 3 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC3_CLK, 11, 1);
+/* Flexcomm Interface 4 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC4_CLK, 12, 1);
+/* Flexcomm Interface 5 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC5_CLK, 13, 1);
+/* Flexcomm Interface 6 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC6_CLK, 14, 1);
+/* Flexcomm Interface 7 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC7_CLK, 15, 1);
+/* Flexcomm Interface 8 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC8_CLK, 16, 1);
+/* Flexcomm Interface 9 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC9_CLK, 17, 1);
+/* Flexcomm Interface 10 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC10_CLK, 18, 1);
+/* Flexcomm Interface 11 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC11_CLK, 19, 1);
+/* Flexcomm Interface 12 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC12_CLK, 20, 1);
+/* Flexcomm Interface 13 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC13_CLK, 21, 1);
+/* Flexcomm Interface 14 SPI clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC14_SPI_CLK, 22, 1);
+/* Flexcomm Interface 15 I2C clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC15_I2C_CLK, 23, 1);
+/* DMIC0 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, DMIC0, 24, 1);
+/* Flexcomm Interface 16 SPI clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FC16_SPI_CLK, 25, 1);
+/* OS event timer bus clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, OSEVENT_TIMER, 27, 1);
+/* FlexIO clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0, FlexIO, 29, 1);
+
+/* Clock Control 1 */
+REG32(RT500_CLKCTL1_PSCCTL1, 20);
+/* Non-secure GPIO0 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, HSGPIO0_CLK, 0, 1);
+/* Non-secure GPIO1 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, HSGPIO1_CLK, 1, 1);
+/* Non-secure GPIO2 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, HSGPIO2_CLK, 2, 1);
+/* Non-secure GPIO3 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, HSGPIO3_CLK, 3, 1);
+/* Non-secure GPIO4 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, HSGPIO4_CLK, 4, 1);
+/* Non-secure GPIO5 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, HSGPIO5_CLK, 5, 1);
+/* Non-secure GPIO6 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, HSGPIO6_CLK, 6, 1);
+/* Non-secure GPIO7 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, HSGPIO7_CLK, 7, 1);
+/* CRC clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, CRC_CLK, 16, 1);
+/* DMAC0 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, DMAC0_CLK, 23, 1);
+/* DMAC1 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, DMAC1_CLK, 24, 1);
+/* Messaging Unit clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, MU_CLK, 28, 1);
+/* Semaphore clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, SEMA_CLK, 29, 1);
+/* Frequency Measurement clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1, FREQME_CLK, 31, 1);
+
+/* Clock Control 2 */
+REG32(RT500_CLKCTL1_PSCCTL2, 24);
+/* CT32BIT bit timer 0 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL2, CT32BIT0_CLK, 0, 1);
+/* CT32BIT bit timer 1 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL2, CT32BIT1_CLK, 1, 1);
+/* CT32BIT bit timer 2 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL2, CT32BIT2_CLK, 2, 1);
+/* CT32BIT bit timer 3 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL2, CT32BIT3_CLK, 3, 1);
+/* CT32BIT bit timer 4 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL2, CT32BIT4_CLK, 4, 1);
+/* RTC clock control */
+FIELD(RT500_CLKCTL1_PSCCTL2, RTCLITE_CLK, 7, 1);
+/* Multi-Rate Timer 0 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL2, MRT0_CLK, 8, 1);
+/* Watchdog Timer 1 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL2, WWDT1_CLK, 10, 1);
+/* I3C0 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL2, I3C0_CLK, 16, 1);
+/* I3C1 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL2, I3C1_CLK, 17, 1);
+/* PINT clock control */
+FIELD(RT500_CLKCTL1_PSCCTL2, GPIOINTCTL_CLK, 30, 1);
+/* INPUTMUX clock control */
+FIELD(RT500_CLKCTL1_PSCCTL2, PIMCTL_CLK, 31, 1);
+
+/* Clock Set 0 */
+REG32(RT500_CLKCTL1_PSCCTL0_SET, 64);
+/* Flexcomm Interface 0 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC0_CLK, 8, 1);
+/* Flexcomm Interface 1 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC1_CLK, 9, 1);
+/* Flexcomm Interface 2 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC2_CLK, 10, 1);
+/* Flexcomm Interface 3 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC3_CLK, 11, 1);
+/* Flexcomm Interface 4 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC4_CLK, 12, 1);
+/* Flexcomm Interface 5 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC5_CLK, 13, 1);
+/* Flexcomm Interface 6 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC6_CLK, 14, 1);
+/* Flexcomm Interface 7 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC7_CLK, 15, 1);
+/* Flexcomm Interface 8 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC8_CLK, 16, 1);
+/* Flexcomm Interface 9 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC9_CLK, 17, 1);
+/* Flexcomm Interface 10 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC10_CLK, 18, 1);
+/* Flexcomm Interface 11 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC11_CLK, 19, 1);
+/* Flexcomm Interface 12 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC12_CLK, 20, 1);
+/* Flexcomm Interface 13 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC13_CLK, 21, 1);
+/* Flexcomm Interface 14 SPI clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC14_SPI_CLK, 22, 1);
+/* Flexcomm Interface 15 I2C clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC15_I2C_CLK, 23, 1);
+/* DMIC0 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, DMIC0, 24, 1);
+/* Flexcomm Interface 16 SPI clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FC16_SPI_CLK, 25, 1);
+/* OS event timer bus clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, OSEVENT_TIMER, 27, 1);
+/* FlexIO clock control */
+FIELD(RT500_CLKCTL1_PSCCTL0_SET, FlexIO, 29, 1);
+
+/* Clock Set 1 */
+REG32(RT500_CLKCTL1_PSCCTL1_SET, 68);
+/* Non-secure GPIO0 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, HSGPIO0_CLK, 0, 1);
+/* Non-secure GPIO1 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, HSGPIO1_CLK, 1, 1);
+/* Non-secure GPIO2 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, HSGPIO2_CLK, 2, 1);
+/* Non-secure GPIO3 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, HSGPIO3_CLK, 3, 1);
+/* Non-secure GPIO4 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, HSGPIO4_CLK, 4, 1);
+/* Non-secure GPIO5 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, HSGPIO5_CLK, 5, 1);
+/* Non-secure GPIO6 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, HSGPIO6_CLK, 6, 1);
+/* Non-secure GPIO7 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, HSGPIO7_CLK, 7, 1);
+/* CRC clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, CRC_CLK, 16, 1);
+/* DMAC0 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, DMAC0_CLK, 23, 1);
+/* DMAC1 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, DMAC1_CLK, 24, 1);
+/* Messaging Unit clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, MU_CLK, 28, 1);
+/* Semaphore clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, SEMA_CLK, 29, 1);
+/* Frequency Measurement clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL1_SET, FREQME_CLK, 31, 1);
+
+/* Clock Set 2 */
+REG32(RT500_CLKCTL1_PSCCTL2_SET, 72);
+/* CT32BIT bit timer 0 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL2_SET, CT32BIT0_CLK, 0, 1);
+/* CT32BIT bit timer 1 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL2_SET, CT32BIT1_CLK, 1, 1);
+/* CT32BIT bit timer 2 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL2_SET, CT32BIT2_CLK, 2, 1);
+/* CT32BIT bit timer 3 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL2_SET, CT32BIT3_CLK, 3, 1);
+/* CT32BIT bit timer 4 clock set */
+FIELD(RT500_CLKCTL1_PSCCTL2_SET, CT32BIT4_CLK, 4, 1);
+/* RTC clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL2_SET, RTCLITE_CLK, 7, 1);
+/* Multi-Rate Timer 0 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL2_SET, MRT0_CLK, 8, 1);
+/* Watchdog Timer 1 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL2_SET, WWDT1_CLK, 10, 1);
+/* I3C0 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL2_SET, I3C0_CLK, 16, 1);
+/* I3C1 clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL2_SET, I3C1_CLK, 17, 1);
+/* PINT clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL2_SET, GPIOINTCTL_CLK, 30, 1);
+/* INPUTMUX clock control set */
+FIELD(RT500_CLKCTL1_PSCCTL2_SET, PIMCTL_CLK, 31, 1);
+
+/* Clock Clear 0 */
+REG32(RT500_CLKCTL1_PSCCTL0_CLR, 112);
+/* Flexcomm Interface 0 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC0_CLK, 8, 1);
+/* Flexcomm Interface 1 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC1_CLK, 9, 1);
+/* Flexcomm Interface 2 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC2_CLK, 10, 1);
+/* Flexcomm Interface 3 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC3_CLK, 11, 1);
+/* Flexcomm Interface 4 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC4_CLK, 12, 1);
+/* Flexcomm Interface 5 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC5_CLK, 13, 1);
+/* Flexcomm Interface 6 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC6_CLK, 14, 1);
+/* Flexcomm Interface 7 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC7_CLK, 15, 1);
+/* Flexcomm Interface 8 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC8_CLK, 16, 1);
+/* Flexcomm Interface 9 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC9_CLK, 17, 1);
+/* Flexcomm Interface 10 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC10_CLK, 18, 1);
+/* Flexcomm Interface 11 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC11_CLK, 19, 1);
+/* Flexcomm Interface 12 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC12_CLK, 20, 1);
+/* Flexcomm Interface 13 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC13_CLK, 21, 1);
+/* Flexcomm Interface 14 SPI clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC14_SPI_CLK, 22, 1);
+/* Flexcomm Interface 15 I2C clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC15_I2C_CLK, 23, 1);
+/* DMIC0 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, DMIC0, 24, 1);
+/* Flexcomm Interface 16 SPI clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FC16_SPI_CLK, 25, 1);
+/* OS event timer bus clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, OSEVENT_TIMER, 27, 1);
+/* FlexIO clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL0_CLR, FlexIO, 29, 1);
+
+/* Clock Clear 1 */
+REG32(RT500_CLKCTL1_PSCCTL1_CLR, 116);
+/* Non-secure GPIO0 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, HSGPIO0_CLK, 0, 1);
+/* Non-secure GPIO1 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, HSGPIO1_CLK, 1, 1);
+/* Non-secure GPIO2 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, HSGPIO2_CLK, 2, 1);
+/* Non-secure GPIO3 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, HSGPIO3_CLK, 3, 1);
+/* Non-secure GPIO4 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, HSGPIO4_CLK, 4, 1);
+/* Non-secure GPIO5 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, HSGPIO5_CLK, 5, 1);
+/* Non-secure GPIO6 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, HSGPIO6_CLK, 6, 1);
+/* Non-secure GPIO7 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, HSGPIO7_CLK, 7, 1);
+/* CRC clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, CRC_CLK, 16, 1);
+/* DMAC0 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, DMAC0_CLK, 23, 1);
+/* DMAC1 clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, DMAC1_CLK, 24, 1);
+/* Messaging Unit clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, MU_CLK, 28, 1);
+/* Semaphore clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, SEMA_CLK, 29, 1);
+/* Frequency Measurement clock control */
+FIELD(RT500_CLKCTL1_PSCCTL1_CLR, FREQME_CLK, 31, 1);
+
+/* Clock Clear 2 */
+REG32(RT500_CLKCTL1_PSCCTL2_CLR, 120);
+/* CT32BIT bit timer 0 clock clear */
+FIELD(RT500_CLKCTL1_PSCCTL2_CLR, CT32BIT0_CLK, 0, 1);
+/* CT32BIT bit timer 1 clock clear */
+FIELD(RT500_CLKCTL1_PSCCTL2_CLR, CT32BIT1_CLK, 1, 1);
+/* CT32BIT bit timer 2 clock clear */
+FIELD(RT500_CLKCTL1_PSCCTL2_CLR, CT32BIT2_CLK, 2, 1);
+/* CT32BIT bit timer 3 clock clear */
+FIELD(RT500_CLKCTL1_PSCCTL2_CLR, CT32BIT3_CLK, 3, 1);
+/* CT32BIT bit timer 4 clock clear */
+FIELD(RT500_CLKCTL1_PSCCTL2_CLR, CT32BIT4_CLK, 4, 1);
+/* RTC clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL2_CLR, RTCLITE_CLK, 7, 1);
+/* Multi-Rate Timer 0 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL2_CLR, MRT0_CLK, 8, 1);
+/* Watchdog Timer 1 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL2_CLR, WWDT1_CLK, 10, 1);
+/* I3C0 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL2_CLR, I3C0_CLK, 16, 1);
+/* I3C1 clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL2_CLR, I3C1_CLK, 17, 1);
+/* PINT clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL2_CLR, GPIOINTCTL_CLK, 30, 1);
+/* INPUTMUX clock control clear */
+FIELD(RT500_CLKCTL1_PSCCTL2_CLR, PIMCTL_CLK, 31, 1);
+
+/* Audio PLL0 Clock Select */
+REG32(RT500_CLKCTL1_AUDIOPLL0CLKSEL, 512);
+/* Audio PLL0 Clock Select */
+FIELD(RT500_CLKCTL1_AUDIOPLL0CLKSEL, SEL, 0, 3);
+
+/* Audio PLL0 Control 0 */
+REG32(RT500_CLKCTL1_AUDIOPLL0CTL0, 516);
+/* AUDIOPLL0 BYPASS Mode */
+FIELD(RT500_CLKCTL1_AUDIOPLL0CTL0, BYPASS, 0, 1);
+/* AUDIOPLL0 Reset */
+FIELD(RT500_CLKCTL1_AUDIOPLL0CTL0, RESET, 1, 1);
+/* Hold Ring Off Control */
+FIELD(RT500_CLKCTL1_AUDIOPLL0CTL0, HOLDRINGOFF_ENA, 13, 1);
+/* Multiplication Factor */
+FIELD(RT500_CLKCTL1_AUDIOPLL0CTL0, MULT, 16, 8);
+
+/* Audio PLL0 Lock Time Divide-by-2 */
+REG32(RT500_CLKCTL1_AUDIOPLL0LOCKTIMEDIV2, 524);
+/* AUDIOPLL0 Lock Time Divide-by-2 */
+FIELD(RT500_CLKCTL1_AUDIOPLL0LOCKTIMEDIV2, LOCKTIMEDIV2, 0, 16);
+
+/* Audio PLL0 Numerator */
+REG32(RT500_CLKCTL1_AUDIOPLL0NUM, 528);
+/* Numerator */
+FIELD(RT500_CLKCTL1_AUDIOPLL0NUM, NUM, 0, 30);
+
+/* Audio PLL0 Denominator */
+REG32(RT500_CLKCTL1_AUDIOPLL0DENOM, 532);
+/* Denominator */
+FIELD(RT500_CLKCTL1_AUDIOPLL0DENOM, DENOM, 0, 30);
+
+/* Audio PLL0 PFD */
+REG32(RT500_CLKCTL1_AUDIOPLL0PFD, 536);
+/* PLL Fractional Divider 0 */
+FIELD(RT500_CLKCTL1_AUDIOPLL0PFD, PFD0, 0, 6);
+/* PFD0 Clock Ready Status Flag */
+FIELD(RT500_CLKCTL1_AUDIOPLL0PFD, PFD0_CLKRDY, 6, 1);
+/* PFD0 Clock Gate */
+FIELD(RT500_CLKCTL1_AUDIOPLL0PFD, PFD0_CLKGATE, 7, 1);
+/* PLL Fractional Divider 1 */
+FIELD(RT500_CLKCTL1_AUDIOPLL0PFD, PFD1, 8, 6);
+/* PFD1 Clock Ready Status Flag */
+FIELD(RT500_CLKCTL1_AUDIOPLL0PFD, PFD1_CLKRDY, 14, 1);
+/* PFD1 Clock Gate */
+FIELD(RT500_CLKCTL1_AUDIOPLL0PFD, PFD1_CLKGATE, 15, 1);
+/* PLL Fractional Divider 2 */
+FIELD(RT500_CLKCTL1_AUDIOPLL0PFD, PFD2, 16, 6);
+/* PFD2 Clock Ready Status Flag */
+FIELD(RT500_CLKCTL1_AUDIOPLL0PFD, PFD2_CLKRDY, 22, 1);
+/* PFD2 Clock Gate */
+FIELD(RT500_CLKCTL1_AUDIOPLL0PFD, PFD2_CLKGATE, 23, 1);
+/* PLL Fractional Divider 3 */
+FIELD(RT500_CLKCTL1_AUDIOPLL0PFD, PFD3, 24, 6);
+/* PFD3 Clock Ready Status Flag */
+FIELD(RT500_CLKCTL1_AUDIOPLL0PFD, PFD3_CLKRDY, 30, 1);
+/* PFD3 Clock Gate */
+FIELD(RT500_CLKCTL1_AUDIOPLL0PFD, PFD3_CLKGATE, 31, 1);
+
+/* Audio PLL Clock Divider */
+REG32(RT500_CLKCTL1_AUDIOPLLCLKDIV, 576);
+/* Audio PLL Clock Divider Value */
+FIELD(RT500_CLKCTL1_AUDIOPLLCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL1_AUDIOPLLCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL1_AUDIOPLLCLKDIV, HALT, 30, 1);
+/* Divider Status Flag */
+FIELD(RT500_CLKCTL1_AUDIOPLLCLKDIV, REQFLAG, 31, 1);
+
+/* DSP CPU Clock Divider */
+REG32(RT500_CLKCTL1_DSPCPUCLKDIV, 1024);
+/* DSP Clock Divider Value */
+FIELD(RT500_CLKCTL1_DSPCPUCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL1_DSPCPUCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL1_DSPCPUCLKDIV, HALT, 30, 1);
+/* Divider Status Flag */
+FIELD(RT500_CLKCTL1_DSPCPUCLKDIV, REQFLAG, 31, 1);
+
+/* DSP CPU Clock Select A */
+REG32(RT500_CLKCTL1_DSPCPUCLKSELA, 1072);
+/* DSP Main 1st Stage Control Clock Source */
+FIELD(RT500_CLKCTL1_DSPCPUCLKSELA, SEL, 0, 2);
+
+/* DSP CPU Clock Select B */
+REG32(RT500_CLKCTL1_DSPCPUCLKSELB, 1076);
+/* Main Clock Source */
+FIELD(RT500_CLKCTL1_DSPCPUCLKSELB, SEL, 0, 2);
+
+/* OS Event Timer Functional Clock Select */
+REG32(RT500_CLKCTL1_OSEVENTTFCLKSEL, 1152);
+/* OS Event Timer Functional Clock Source */
+FIELD(RT500_CLKCTL1_OSEVENTTFCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 0 Clock Select */
+REG32(RT500_CLKCTL1_FRG0CLKSEL, 1280);
+/* Fractional Generator 0 Clock Source */
+FIELD(RT500_CLKCTL1_FRG0CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 0 Control */
+REG32(RT500_CLKCTL1_FRG0CTL, 1284);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG0CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG0CTL, MULT, 8, 8);
+
+/* Flexcomm0 Clock Select */
+REG32(RT500_CLKCTL1_FC0FCLKSEL, 1288);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC0FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 1 Clock Select */
+REG32(RT500_CLKCTL1_FRG1CLKSEL, 1312);
+/* Fractional Generator 1 Clock Source */
+FIELD(RT500_CLKCTL1_FRG1CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 1 Control */
+REG32(RT500_CLKCTL1_FRG1CTL, 1316);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG1CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG1CTL, MULT, 8, 8);
+
+/* Flexcomm1 Clock Select */
+REG32(RT500_CLKCTL1_FC1FCLKSEL, 1320);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC1FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 2 Clock Select */
+REG32(RT500_CLKCTL1_FRG2CLKSEL, 1344);
+/* Fractional Generator 2 Clock Source */
+FIELD(RT500_CLKCTL1_FRG2CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 2 Control */
+REG32(RT500_CLKCTL1_FRG2CTL, 1348);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG2CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG2CTL, MULT, 8, 8);
+
+/* Flexcomm2 Clock Select */
+REG32(RT500_CLKCTL1_FC2FCLKSEL, 1352);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC2FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 3 Clock Select */
+REG32(RT500_CLKCTL1_FRG3CLKSEL, 1376);
+/* Fractional Generator 3 Clock Source */
+FIELD(RT500_CLKCTL1_FRG3CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 3 Control */
+REG32(RT500_CLKCTL1_FRG3CTL, 1380);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG3CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG3CTL, MULT, 8, 8);
+
+/* Flexcomm3 Clock Select */
+REG32(RT500_CLKCTL1_FC3FCLKSEL, 1384);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC3FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 4 Clock Select */
+REG32(RT500_CLKCTL1_FRG4CLKSEL, 1408);
+/* Fractional Generator 4 Clock Source */
+FIELD(RT500_CLKCTL1_FRG4CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 4 Control */
+REG32(RT500_CLKCTL1_FRG4CTL, 1412);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG4CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG4CTL, MULT, 8, 8);
+
+/* Flexcomm4 Clock Select */
+REG32(RT500_CLKCTL1_FC4FCLKSEL, 1416);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC4FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 5 Clock Select */
+REG32(RT500_CLKCTL1_FRG5CLKSEL, 1440);
+/* Fractional Generator 5 Clock Source */
+FIELD(RT500_CLKCTL1_FRG5CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 5 Control */
+REG32(RT500_CLKCTL1_FRG5CTL, 1444);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG5CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG5CTL, MULT, 8, 8);
+
+/* Flexcomm5 Clock Select */
+REG32(RT500_CLKCTL1_FC5FCLKSEL, 1448);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC5FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 6 Clock Select */
+REG32(RT500_CLKCTL1_FRG6CLKSEL, 1472);
+/* Fractional Generator 6 Clock Source */
+FIELD(RT500_CLKCTL1_FRG6CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 6 Control */
+REG32(RT500_CLKCTL1_FRG6CTL, 1476);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG6CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG6CTL, MULT, 8, 8);
+
+/* Flexcomm6 Clock Select */
+REG32(RT500_CLKCTL1_FC6FCLKSEL, 1480);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC6FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 7 Clock Select */
+REG32(RT500_CLKCTL1_FRG7CLKSEL, 1504);
+/* Fractional Generator 7 Clock Source */
+FIELD(RT500_CLKCTL1_FRG7CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 7 Control */
+REG32(RT500_CLKCTL1_FRG7CTL, 1508);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG7CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG7CTL, MULT, 8, 8);
+
+/* Flexcomm7 Clock Select */
+REG32(RT500_CLKCTL1_FC7FCLKSEL, 1512);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC7FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 8 Clock Select */
+REG32(RT500_CLKCTL1_FRG8CLKSEL, 1536);
+/* Fractional Generator 8 Clock Source */
+FIELD(RT500_CLKCTL1_FRG8CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 8 Control */
+REG32(RT500_CLKCTL1_FRG8CTL, 1540);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG8CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG8CTL, MULT, 8, 8);
+
+/* Flexcomm8 Clock Select */
+REG32(RT500_CLKCTL1_FC8FCLKSEL, 1544);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC8FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 9 Clock Select */
+REG32(RT500_CLKCTL1_FRG9CLKSEL, 1568);
+/* Fractional Generator 9 Clock Source */
+FIELD(RT500_CLKCTL1_FRG9CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 9 Control */
+REG32(RT500_CLKCTL1_FRG9CTL, 1572);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG9CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG9CTL, MULT, 8, 8);
+
+/* Flexcomm9 Clock Select */
+REG32(RT500_CLKCTL1_FC9FCLKSEL, 1576);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC9FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 10 Clock Select */
+REG32(RT500_CLKCTL1_FRG10CLKSEL, 1600);
+/* Fractional Generator 10 Clock Source */
+FIELD(RT500_CLKCTL1_FRG10CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 10 Control */
+REG32(RT500_CLKCTL1_FRG10CTL, 1604);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG10CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG10CTL, MULT, 8, 8);
+
+/* Flexcomm10 Clock Select */
+REG32(RT500_CLKCTL1_FC10FCLKSEL, 1608);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC10FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 11 Clock Select */
+REG32(RT500_CLKCTL1_FRG11CLKSEL, 1632);
+/* Fractional Generator 11 Clock Source */
+FIELD(RT500_CLKCTL1_FRG11CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 11 Control */
+REG32(RT500_CLKCTL1_FRG11CTL, 1636);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG11CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG11CTL, MULT, 8, 8);
+
+/* Flexcomm11 Clock Select */
+REG32(RT500_CLKCTL1_FC11FCLKSEL, 1640);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC11FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 12 Clock Select */
+REG32(RT500_CLKCTL1_FRG12CLKSEL, 1664);
+/* Fractional Generator 12 Clock Source */
+FIELD(RT500_CLKCTL1_FRG12CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 12 Control */
+REG32(RT500_CLKCTL1_FRG12CTL, 1668);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG12CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG12CTL, MULT, 8, 8);
+
+/* Flexcomm12 Clock Select */
+REG32(RT500_CLKCTL1_FC12FCLKSEL, 1672);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC12FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 13 Clock Select */
+REG32(RT500_CLKCTL1_FRG13CLKSEL, 1696);
+/* Fractional Generator 13 Clock Source */
+FIELD(RT500_CLKCTL1_FRG13CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 13 Control */
+REG32(RT500_CLKCTL1_FRG13CTL, 1700);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG13CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG13CTL, MULT, 8, 8);
+
+/* Flexcomm13 Clock Select */
+REG32(RT500_CLKCTL1_FC13FCLKSEL, 1704);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC13FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 14 Clock Select */
+REG32(RT500_CLKCTL1_FRG14CLKSEL, 1728);
+/* Fractional Generator 14 Clock Source */
+FIELD(RT500_CLKCTL1_FRG14CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 14 Control */
+REG32(RT500_CLKCTL1_FRG14CTL, 1732);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG14CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG14CTL, MULT, 8, 8);
+
+/* Flexcomm14 Clock Select */
+REG32(RT500_CLKCTL1_FC14FCLKSEL, 1736);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC14FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 15 Clock Select */
+REG32(RT500_CLKCTL1_FRG15CLKSEL, 1760);
+/* Fractional Generator 15 Clock Source */
+FIELD(RT500_CLKCTL1_FRG15CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 15 Control */
+REG32(RT500_CLKCTL1_FRG15CTL, 1764);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG15CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG15CTL, MULT, 8, 8);
+
+/* Flexcomm15 Clock Select */
+REG32(RT500_CLKCTL1_FC15FCLKSEL, 1768);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC15FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 16 Clock Select */
+REG32(RT500_CLKCTL1_FRG16CLKSEL, 1792);
+/* Fractional Generator 16 Clock Source */
+FIELD(RT500_CLKCTL1_FRG16CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 16 Control */
+REG32(RT500_CLKCTL1_FRG16CTL, 1796);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG16CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG16CTL, MULT, 8, 8);
+
+/* Flexcomm16 Clock Select */
+REG32(RT500_CLKCTL1_FC16FCLKSEL, 1800);
+/* Flexcomm Functional Clock Source */
+FIELD(RT500_CLKCTL1_FC16FCLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 17 Clock Select */
+REG32(RT500_CLKCTL1_FRG17CLKSEL, 1824);
+/* Fractional Generator 17 Clock Source */
+FIELD(RT500_CLKCTL1_FRG17CLKSEL, SEL, 0, 3);
+
+/* Fractional Rate Generator 17 Control */
+REG32(RT500_CLKCTL1_FRG17CTL, 1828);
+/*
+ * Denominator of the fractional divider: DIV is equal to the programmed value
+ * +1
+ */
+FIELD(RT500_CLKCTL1_FRG17CTL, DIV, 0, 8);
+/*
+ * Numerator of the fractional divider: MULT is equal to the programmed value.
+ */
+FIELD(RT500_CLKCTL1_FRG17CTL, MULT, 8, 8);
+
+/* FlexIO Clock Select */
+REG32(RT500_CLKCTL1_FLEXIOCLKSEL, 1832);
+/* FlexIO Functional Clock Source */
+FIELD(RT500_CLKCTL1_FLEXIOCLKSEL, SEL, 0, 3);
+
+/* FlexIO Clock Divider */
+REG32(RT500_CLKCTL1_FLEXIOCLKDIV, 1856);
+/* FLEXIO Clock Divider Value */
+FIELD(RT500_CLKCTL1_FLEXIOCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL1_FLEXIOCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL1_FLEXIOCLKDIV, HALT, 30, 1);
+/* Divider Status Flag */
+FIELD(RT500_CLKCTL1_FLEXIOCLKDIV, REQFLAG, 31, 1);
+
+/* Fractional Rate Generator PLL Clock Divider */
+REG32(RT500_CLKCTL1_FRGPLLCLKDIV, 1888);
+/* FRG PLL Clock Divider Value */
+FIELD(RT500_CLKCTL1_FRGPLLCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL1_FRGPLLCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL1_FRGPLLCLKDIV, HALT, 30, 1);
+/* Divider Status Flag */
+FIELD(RT500_CLKCTL1_FRGPLLCLKDIV, REQFLAG, 31, 1);
+
+/* DMIC0 Functional Clock Select */
+REG32(RT500_CLKCTL1_DMIC0FCLKSEL, 1920);
+/* DMIC Functional Clock Source */
+FIELD(RT500_CLKCTL1_DMIC0FCLKSEL, SEL, 0, 3);
+
+/* DMIC0 Functional Clock Divider */
+REG32(RT500_CLKCTL1_DMIC0FCLKDIV, 1924);
+/* 32 KHz Wake Clock Divider Value */
+FIELD(RT500_CLKCTL1_DMIC0FCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL1_DMIC0FCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL1_DMIC0FCLKDIV, HALT, 30, 1);
+/* Divider Status Flag */
+FIELD(RT500_CLKCTL1_DMIC0FCLKDIV, REQFLAG, 31, 1);
+
+/* CT32BIT bit timer index Functional Clock Select */
+REG32(RT500_CLKCTL1_CT32BITFCLKSEL0, 1952);
+REG32(RT500_CLKCTL1_CT32BITFCLKSEL1, 1956);
+REG32(RT500_CLKCTL1_CT32BITFCLKSEL2, 1960);
+REG32(RT500_CLKCTL1_CT32BITFCLKSEL3, 1964);
+REG32(RT500_CLKCTL1_CT32BITFCLKSEL4, 1968);
+/* CT32BIT bit timer 0 Functional Clock Source */
+SHARED_FIELD(RT500_CLKCTL1_CT32BITFCLKSEL_SEL, 0, 3);
+
+/* Audio MCLK Clock Select */
+REG32(RT500_CLKCTL1_AUDIOMCLKSEL, 1984);
+/* Audio MCLK Clock Source Select */
+FIELD(RT500_CLKCTL1_AUDIOMCLKSEL, SEL, 0, 3);
+
+/* Audio MCLK Clock Divider */
+REG32(RT500_CLKCTL1_AUDIOMCLKDIV, 1988);
+/* Audio MCLK Clock Divider Value */
+FIELD(RT500_CLKCTL1_AUDIOMCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL1_AUDIOMCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL1_AUDIOMCLKDIV, HALT, 30, 1);
+/* Divider Status Flag */
+FIELD(RT500_CLKCTL1_AUDIOMCLKDIV, REQFLAG, 31, 1);
+
+/* CLKOUT Clock Select 0 */
+REG32(RT500_CLKCTL1_CLKOUTSEL0, 2016);
+/* Clock Output Select 1st Stage */
+FIELD(RT500_CLKCTL1_CLKOUTSEL0, SEL, 0, 3);
+
+/* CLKOUT Clock Select 1 */
+REG32(RT500_CLKCTL1_CLKOUTSEL1, 2020);
+/* Clock Out Source */
+FIELD(RT500_CLKCTL1_CLKOUTSEL1, SEL, 0, 3);
+
+/* CLKOUT Functional Clock Divider */
+REG32(RT500_CLKCTL1_CLKOUTFCLKDIV, 2024);
+/* Clock-Out Clock Divider Value */
+FIELD(RT500_CLKCTL1_CLKOUTFCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL1_CLKOUTFCLKDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL1_CLKOUTFCLKDIV, HALT, 30, 1);
+/* Divider Status Flag */
+FIELD(RT500_CLKCTL1_CLKOUTFCLKDIV, REQFLAG, 31, 1);
+
+/* I3C0, I3C1 Functional Clock Select */
+REG32(RT500_CLKCTL1_I3C01FCLKSEL, 2048);
+/* I3C0, I3C1 Clock Source */
+FIELD(RT500_CLKCTL1_I3C01FCLKSEL, SEL, 0, 3);
+
+/* I3C0, I3C1 Functional Slow Time Control Clock Select */
+REG32(RT500_CLKCTL1_I3C01FCLKSTCSEL, 2052);
+/* I3C0, I3C1 Clock Source */
+FIELD(RT500_CLKCTL1_I3C01FCLKSTCSEL, SEL, 0, 3);
+
+/* I3C0, I3C1 Functional Slow Time Control Clock Divider */
+REG32(RT500_CLKCTL1_I3C01FCLKSTCDIV, 2056);
+/* I3C0, I3C1 Clock Divider Value */
+FIELD(RT500_CLKCTL1_I3C01FCLKSTCDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL1_I3C01FCLKSTCDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL1_I3C01FCLKSTCDIV, HALT, 30, 1);
+/* Divider Status Flag */
+FIELD(RT500_CLKCTL1_I3C01FCLKSTCDIV, REQFLAG, 31, 1);
+
+/* I3C0, I3C1 Functional Slow Clock Divider */
+REG32(RT500_CLKCTL1_I3C01FCLKSDIV, 2060);
+/* I3C0, I3C1 Clock Divider Value */
+FIELD(RT500_CLKCTL1_I3C01FCLKSDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL1_I3C01FCLKSDIV, RESET, 29, 1);
+/* Halt the Divider Counter */
+FIELD(RT500_CLKCTL1_I3C01FCLKSDIV, HALT, 30, 1);
+/* Divider Status Flag */
+FIELD(RT500_CLKCTL1_I3C01FCLKSDIV, REQFLAG, 31, 1);
+
+/* I3C0, I3C1 Functional Clock Divider */
+REG32(RT500_CLKCTL1_I3C01FCLKDIV, 2064);
+/* I3C0, I3C1 Clock Divider Value */
+FIELD(RT500_CLKCTL1_I3C01FCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL1_I3C01FCLKDIV, RESET, 29, 1);
+/* Halts the Divider Counter */
+FIELD(RT500_CLKCTL1_I3C01FCLKDIV, HALT, 30, 1);
+/* Divider Status Flag */
+FIELD(RT500_CLKCTL1_I3C01FCLKDIV, REQFLAG, 31, 1);
+
+/* I3C01 Functional Clock Select */
+REG32(RT500_CLKCTL1_I3C01FCLKSTSTCLKSEL, 2068);
+/* I3C0, I3C1 FCLK Test Clock Source */
+FIELD(RT500_CLKCTL1_I3C01FCLKSTSTCLKSEL, SEL, 0, 3);
+
+/* Watchdog Timer 1 Functional Clock Select */
+REG32(RT500_CLKCTL1_WDT1FCLKSEL, 2080);
+/* WDT1 Functional Clock Source */
+FIELD(RT500_CLKCTL1_WDT1FCLKSEL, SEL, 0, 3);
+
+/* Analog Comparator 0 Clock Select */
+REG32(RT500_CLKCTL1_ACMP0FCLKSEL, 2096);
+/* ACMP0 Fast Functional Clock Source */
+FIELD(RT500_CLKCTL1_ACMP0FCLKSEL, SEL, 0, 3);
+
+/* Analog comparator 0 FCLK divider */
+REG32(RT500_CLKCTL1_ACMP0FCLKDIV, 2100);
+/* Clock Out Clock Divider Value */
+FIELD(RT500_CLKCTL1_ACMP0FCLKDIV, DIV, 0, 8);
+/* Reset the Divider Counter */
+FIELD(RT500_CLKCTL1_ACMP0FCLKDIV, RESET, 29, 1);
+/* Halts the Divider Counter */
+FIELD(RT500_CLKCTL1_ACMP0FCLKDIV, HALT, 30, 1);
+/* Divider Status Flag */
+FIELD(RT500_CLKCTL1_ACMP0FCLKDIV, REQFLAG, 31, 1);
+
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC0_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC0_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC1_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC1_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC2_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC2_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC2_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC3_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC3_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC3_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC4_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC4_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC4_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC5_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC5_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC5_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC6_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC6_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC6_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC7_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC7_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC7_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC8_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC8_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC8_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC9_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC9_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC9_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC10_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC10_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC10_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC11_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC11_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC11_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC12_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC12_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC12_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC13_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC13_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC13_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC14_SPI_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC14_SPI_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC14_SPI_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC15_I2C_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC15_I2C_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC15_I2C_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_DMIC0_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_DMIC0_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_DMIC0_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC16_SPI_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FC16_SPI_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FC16_SPI_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_OSEVENT_TIMER_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_OSEVENT_TIMER_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_OSEVENT_TIMER_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL0_FlexIO_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL0_FlexIO_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_FlexIO_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO0_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_HSGPIO0_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO1_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_HSGPIO1_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO2_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO2_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_HSGPIO2_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO3_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO3_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_HSGPIO3_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO4_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO4_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_HSGPIO4_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO5_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO5_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_HSGPIO5_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO6_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO6_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_HSGPIO6_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO7_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_HSGPIO7_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_HSGPIO7_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_CRC_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_CRC_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CRC_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_DMAC0_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_DMAC0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_DMAC0_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_DMAC1_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_DMAC1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_DMAC1_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_MU_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_MU_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_MU_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_SEMA_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_SEMA_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SEMA_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL1_FREQME_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL1_FREQME_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_FREQME_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_CT32BIT0_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_CT32BIT0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_CT32BIT0_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_CT32BIT1_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_CT32BIT1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_CT32BIT1_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_CT32BIT2_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_CT32BIT2_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_CT32BIT2_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_CT32BIT3_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_CT32BIT3_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_CT32BIT3_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_CT32BIT4_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_CT32BIT4_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_CT32BIT4_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_RTCLITE_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_RTCLITE_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_RTCLITE_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_MRT0_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_MRT0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_MRT0_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_WWDT1_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_WWDT1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_WWDT1_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_I3C0_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_I3C0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_I3C0_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_I3C1_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_I3C1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_I3C1_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_GPIOINTCTL_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_GPIOINTCTL_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_GPIOINTCTL_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_PIMCTL_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_PIMCTL_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_PIMCTL_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC0_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC1_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC1_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC2_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC2_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC2_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC3_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC3_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC3_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC4_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC4_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC4_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC5_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC5_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC5_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC6_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC6_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC6_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC7_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC7_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC7_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC8_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC8_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC8_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC9_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC9_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC9_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC10_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC10_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC10_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC11_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC11_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC11_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC12_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC12_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC12_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC13_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC13_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC13_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC14_SPI_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC14_SPI_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC14_SPI_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC15_I2C_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC15_I2C_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC15_I2C_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_DMIC0_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_DMIC0_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_DMIC0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FC16_SPI_CLK_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FC16_SPI_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FC16_SPI_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_OSEVENT_TIMER_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_OSEVENT_TIMER_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_OSEVENT_TIMER_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_SET_FlexIO_DISABLE = 0,
+ /* Sets the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_SET_FlexIO_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_SET_FlexIO_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO0_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_HSGPIO0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO1_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_HSGPIO1_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO2_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO2_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_HSGPIO2_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO3_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO3_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_HSGPIO3_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO4_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO4_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_HSGPIO4_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO5_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO5_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_HSGPIO5_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO6_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO6_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_HSGPIO6_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO7_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_HSGPIO7_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_HSGPIO7_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_CRC_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_CRC_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_CRC_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_DMAC0_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_DMAC0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_DMAC0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_DMAC1_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_DMAC1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_DMAC1_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_MU_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_MU_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_MU_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_SEMA_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_SEMA_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_SEMA_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_SET_FREQME_CLK_DISABLE = 0,
+ /* Sets the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_SET_FREQME_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_SET_FREQME_CLK_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_CLKCTL1_PSCCTL2_SET_CT32BIT0_CLK_NO_EFFECT = 0,
+ /* Set Bit */
+ RT500_CLKCTL1_PSCCTL2_SET_CT32BIT0_CLK_SET_BIT = 1,
+} RT500_CLKCTL1_PSCCTL2_SET_CT32BIT0_CLK_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_CLKCTL1_PSCCTL2_SET_CT32BIT1_CLK_NO_EFFECT = 0,
+ /* Set Bit */
+ RT500_CLKCTL1_PSCCTL2_SET_CT32BIT1_CLK_SET_BIT = 1,
+} RT500_CLKCTL1_PSCCTL2_SET_CT32BIT1_CLK_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_CLKCTL1_PSCCTL2_SET_CT32BIT2_CLK_NO_EFFECT = 0,
+ /* Set Bit */
+ RT500_CLKCTL1_PSCCTL2_SET_CT32BIT2_CLK_SET_BIT = 1,
+} RT500_CLKCTL1_PSCCTL2_SET_CT32BIT2_CLK_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_CLKCTL1_PSCCTL2_SET_CT32BIT3_CLK_NO_EFFECT = 0,
+ /* Set Bit */
+ RT500_CLKCTL1_PSCCTL2_SET_CT32BIT3_CLK_SET_BIT = 1,
+} RT500_CLKCTL1_PSCCTL2_SET_CT32BIT3_CLK_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_CLKCTL1_PSCCTL2_SET_CT32BIT4_CLK_NO_EFFECT = 0,
+ /* Set Bit */
+ RT500_CLKCTL1_PSCCTL2_SET_CT32BIT4_CLK_SET_BIT = 1,
+} RT500_CLKCTL1_PSCCTL2_SET_CT32BIT4_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_RTCLITE_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_RTCLITE_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_SET_RTCLITE_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_MRT0_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_MRT0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_SET_MRT0_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_WWDT1_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_WWDT1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_SET_WWDT1_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_I3C0_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_I3C0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_SET_I3C0_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_I3C1_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_I3C1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_SET_I3C1_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_GPIOINTCTL_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_GPIOINTCTL_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_SET_GPIOINTCTL_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_PIMCTL_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_SET_PIMCTL_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_SET_PIMCTL_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC0_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC1_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC1_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC2_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC2_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC2_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC3_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC3_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC3_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC4_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC4_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC4_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC5_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC5_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC5_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC6_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC6_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC6_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC7_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC7_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC7_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC8_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC8_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC8_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC9_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC9_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC9_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC10_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC10_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC10_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC11_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC11_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC11_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC12_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC12_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC12_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC13_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC13_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC13_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC14_SPI_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC14_SPI_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC14_SPI_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC15_I2C_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC15_I2C_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC15_I2C_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_DMIC0_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_DMIC0_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_DMIC0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC16_SPI_CLK_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FC16_SPI_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FC16_SPI_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_OSEVENT_TIMER_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_OSEVENT_TIMER_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_OSEVENT_TIMER_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL0_CLR_FlexIO_DISABLE = 0,
+ /* Clears the PSCCTL0 bit */
+ RT500_CLKCTL1_PSCCTL0_CLR_FlexIO_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL0_CLR_FlexIO_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO0_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO1_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO1_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO2_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO2_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO2_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO3_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO3_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO3_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO4_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO4_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO4_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO5_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO5_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO5_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO6_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO6_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO6_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO7_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO7_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_HSGPIO7_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_CRC_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_CRC_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_CRC_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_DMAC0_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_DMAC0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_DMAC0_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_DMAC1_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_DMAC1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_DMAC1_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_MU_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_MU_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_MU_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_SEMA_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_SEMA_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_SEMA_CLK_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_PSCCTL1_CLR_FREQME_CLK_DISABLE = 0,
+ /* Clears the PSCCTL1 bit */
+ RT500_CLKCTL1_PSCCTL1_CLR_FREQME_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL1_CLR_FREQME_CLK_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT0_CLK_NO_EFFECT = 0,
+ /* Set Bit */
+ RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT0_CLK_SET_BIT = 1,
+} RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT0_CLK_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT1_CLK_NO_EFFECT = 0,
+ /* Set Bit */
+ RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT1_CLK_SET_BIT = 1,
+} RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT1_CLK_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT2_CLK_NO_EFFECT = 0,
+ /* Set Bit */
+ RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT2_CLK_SET_BIT = 1,
+} RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT2_CLK_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT3_CLK_NO_EFFECT = 0,
+ /* Set Bit */
+ RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT3_CLK_SET_BIT = 1,
+} RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT3_CLK_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT4_CLK_NO_EFFECT = 0,
+ /* Set Bit */
+ RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT4_CLK_SET_BIT = 1,
+} RT500_CLKCTL1_PSCCTL2_CLR_CT32BIT4_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_RTCLITE_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_RTCLITE_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_CLR_RTCLITE_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_MRT0_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_MRT0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_CLR_MRT0_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_WWDT1_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_WWDT1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_CLR_WWDT1_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_I3C0_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_I3C0_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_CLR_I3C0_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_I3C1_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_I3C1_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_CLR_I3C1_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_GPIOINTCTL_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_GPIOINTCTL_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_CLR_GPIOINTCTL_CLK_Enum;
+
+typedef enum {
+ /* Disable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_PIMCTL_CLK_DISABLE = 0,
+ /* Enable Clock */
+ RT500_CLKCTL1_PSCCTL2_CLR_PIMCTL_CLK_ENABLE = 1,
+} RT500_CLKCTL1_PSCCTL2_CLR_PIMCTL_CLK_Enum;
+
+typedef enum {
+ /* FRO_DIV8 */
+ RT500_CLKCTL1_AUDIOPLL0CLKSEL_SEL_FRRO_DIV8 = 0,
+ /* OSC_CLK clock (User-Selectable) */
+ RT500_CLKCTL1_AUDIOPLL0CLKSEL_SEL_OSC_CLK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_AUDIOPLL0CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_AUDIOPLL0CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* PFD outputs are PFD-programmed clocks */
+ RT500_CLKCTL1_AUDIOPLL0CTL0_BYPASS_PFD = 0,
+ /*
+ * Bypass Mode. PFD outputs are sourced directly from the reference input
+ * clock
+ */
+ RT500_CLKCTL1_AUDIOPLL0CTL0_BYPASS_BYPASS = 1,
+} RT500_CLKCTL1_AUDIOPLL0CTL0_BYPASS_Enum;
+
+typedef enum {
+ /* AUDIOPLL0 reset is removed */
+ RT500_CLKCTL1_AUDIOPLL0CTL0_RESET_NO_RESET = 0,
+ /* AUDIOPLL0 is placed into reset */
+ RT500_CLKCTL1_AUDIOPLL0CTL0_RESET_RESET = 1,
+} RT500_CLKCTL1_AUDIOPLL0CTL0_RESET_Enum;
+
+typedef enum {
+ /* Disable */
+ RT500_CLKCTL1_AUDIOPLL0CTL0_HOLDRINGOFF_ENA_DISABLE = 0,
+ /* Enable */
+ RT500_CLKCTL1_AUDIOPLL0CTL0_HOLDRINGOFF_ENA_ENABLE = 1,
+} RT500_CLKCTL1_AUDIOPLL0CTL0_HOLDRINGOFF_ENA_Enum;
+
+typedef enum {
+ /* Multiply by 16 */
+ RT500_CLKCTL1_AUDIOPLL0CTL0_MULT_DIV16 = 16,
+ /* Multiply by 17 */
+ RT500_CLKCTL1_AUDIOPLL0CTL0_MULT_DIV17 = 17,
+ /* Multiply by 18 */
+ RT500_CLKCTL1_AUDIOPLL0CTL0_MULT_DIV18 = 18,
+ /* Multiply by 19 */
+ RT500_CLKCTL1_AUDIOPLL0CTL0_MULT_DIV19 = 19,
+ /* Multiply by 20 */
+ RT500_CLKCTL1_AUDIOPLL0CTL0_MULT_DIV20 = 20,
+ /* Multiply by 21 */
+ RT500_CLKCTL1_AUDIOPLL0CTL0_MULT_DIV21 = 21,
+ /* Multiply by 22 */
+ RT500_CLKCTL1_AUDIOPLL0CTL0_MULT_DIV22 = 22,
+} RT500_CLKCTL1_AUDIOPLL0CTL0_MULT_Enum;
+
+typedef enum {
+ /* Not ready */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD0_CLKRDY_NOT_READY = 0,
+ /* Ready */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD0_CLKRDY_READY = 1,
+} RT500_CLKCTL1_AUDIOPLL0PFD_PFD0_CLKRDY_Enum;
+
+typedef enum {
+ /* PFD0 clock is not gated */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD0_CLKGATE_NOT_GATED = 0,
+ /* PFD0 clock is gated */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD0_CLKGATE_GATED = 1,
+} RT500_CLKCTL1_AUDIOPLL0PFD_PFD0_CLKGATE_Enum;
+
+typedef enum {
+ /* Not ready */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD1_CLKRDY_NOT_READY = 0,
+ /* Ready */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD1_CLKRDY_READY = 1,
+} RT500_CLKCTL1_AUDIOPLL0PFD_PFD1_CLKRDY_Enum;
+
+typedef enum {
+ /* PFD1 clock is not gated */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD1_CLKGATE_NOT_GATED = 0,
+ /* PFD1 clock is gated */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD1_CLKGATE_GATED = 1,
+} RT500_CLKCTL1_AUDIOPLL0PFD_PFD1_CLKGATE_Enum;
+
+typedef enum {
+ /* Not ready */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD2_CLKRDY_NOT_READY = 0,
+ /* Ready */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD2_CLKRDY_READY = 1,
+} RT500_CLKCTL1_AUDIOPLL0PFD_PFD2_CLKRDY_Enum;
+
+typedef enum {
+ /* PFD2 clock is not gated */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD2_CLKGATE_NOT_GATED = 0,
+ /* PFD2 clock is gated */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD2_CLKGATE_GATED = 1,
+} RT500_CLKCTL1_AUDIOPLL0PFD_PFD2_CLKGATE_Enum;
+
+typedef enum {
+ /* Not ready */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD3_CLKRDY_NOT_READY = 0,
+ /* Ready */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD3_CLKRDY_READY = 1,
+} RT500_CLKCTL1_AUDIOPLL0PFD_PFD3_CLKRDY_Enum;
+
+typedef enum {
+ /* PFD3 clock is not gated */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD3_CLKGATE_NOT_GATED = 0,
+ /* PFD3 clock is gated */
+ RT500_CLKCTL1_AUDIOPLL0PFD_PFD3_CLKGATE_GATED = 1,
+} RT500_CLKCTL1_AUDIOPLL0PFD_PFD3_CLKGATE_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_AUDIOPLLCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL1_AUDIOPLLCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL1_AUDIOPLLCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_AUDIOPLLCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL1_AUDIOPLLCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL1_AUDIOPLLCLKDIV_HALT_Enum;
+
+typedef enum {
+ /* The Divider change has finished */
+ RT500_CLKCTL1_AUDIOPLLCLKDIV_REQFLAG_REQFLAG_CHANGE_FINISHED = 0,
+ /* The Divider value has changed */
+ RT500_CLKCTL1_AUDIOPLLCLKDIV_REQFLAG_REQFLAG_CHANGED = 1,
+} RT500_CLKCTL1_AUDIOPLLCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_DSPCPUCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL1_DSPCPUCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL1_DSPCPUCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_DSPCPUCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL1_DSPCPUCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL1_DSPCPUCLKDIV_HALT_Enum;
+
+typedef enum {
+ /*
+ * The Divider change has finished (clock being divided must be running for
+ * this status to change).
+ */
+ RT500_CLKCTL1_DSPCPUCLKDIV_REQFLAG_REQFLAG_CHANGE_FINISHED = 0,
+ /* The Divider value has changed. */
+ RT500_CLKCTL1_DSPCPUCLKDIV_REQFLAG_REQFLAG_CHANGED = 1,
+} RT500_CLKCTL1_DSPCPUCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* FRO_DIV1 Clock */
+ RT500_CLKCTL1_DSPCPUCLKSELA_SEL_FRO = 0,
+ /* OSC_CLK Clock */
+ RT500_CLKCTL1_DSPCPUCLKSELA_SEL_OSC_CLK = 1,
+ /* Low Power Oscillator Clock (LPOSC) */
+ RT500_CLKCTL1_DSPCPUCLKSELA_SEL_LPOSC = 2,
+} RT500_CLKCTL1_DSPCPUCLKSELA_SEL_Enum;
+
+typedef enum {
+ /* MAINCLKSELA 1st Stage Clock */
+ RT500_CLKCTL1_DSPCPUCLKSELB_SEL_MAINCLKSELA = 0,
+ /* Main System PLL Clock */
+ RT500_CLKCTL1_DSPCPUCLKSELB_SEL_MAIN_PLL = 1,
+ /* DSP System PLL Clock */
+ RT500_CLKCTL1_DSPCPUCLKSELB_SEL_DSP_PLL = 2,
+ /* RTC 32 KHz Clock */
+ RT500_CLKCTL1_DSPCPUCLKSELB_SEL_RTC_32KHZ = 3,
+} RT500_CLKCTL1_DSPCPUCLKSELB_SEL_Enum;
+
+typedef enum {
+ /* Low Power Oscillator Clock (LPOSC) */
+ RT500_CLKCTL1_OSEVENTTFCLKSEL_SEL_LPOSC = 0,
+ /* RTC 32 KHz Clock */
+ RT500_CLKCTL1_OSEVENTTFCLKSEL_SEL_RTC_32KHZ = 1,
+ /* HCLK Free-Running Clock (Global Time Stamping) */
+ RT500_CLKCTL1_OSEVENTTFCLKSEL_SEL_TEAL = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_OSEVENTTFCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_OSEVENTTFCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG0CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG0CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG0CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG0CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG0CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC0FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC0FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC0FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC0FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG1CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG1CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG1CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG1CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG1CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC1FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC1FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC1FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC1FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG2CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG2CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG2CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG2CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG2CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC2FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC2FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC2FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC2FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG3CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG3CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG3CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG3CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG3CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC3FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC3FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC3FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC3FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG4CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG4CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG4CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG4CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG4CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC4FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC4FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC4FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC4FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG5CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG5CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG5CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG5CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG5CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC5FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC5FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC5FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC5FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG6CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG6CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG6CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG6CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG6CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC6FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC6FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC6FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC6FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG7CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG7CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG7CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG7CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG7CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC7FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC7FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC7FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC7FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG8CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG8CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG8CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG8CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG8CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC8FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC8FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC8FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC8FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG9CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG9CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG9CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG9CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG9CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC9FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC9FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC9FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC9FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG10CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG10CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG10CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG10CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG10CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC10FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC10FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC10FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC10FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG11CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG11CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG11CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG11CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG11CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC11FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC11FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC11FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC11FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG12CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG12CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG12CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG12CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG12CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC12FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC12FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC12FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC12FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG13CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG13CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG13CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG13CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG13CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC13FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC13FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC13FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC13FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG14CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG14CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG14CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG14CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG14CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC14FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC14FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC14FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC14FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG15CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG15CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG15CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG15CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG15CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC15FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC15FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC15FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC15FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG16CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG16CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG16CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG16CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG16CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FC16FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FC16FCLKSEL_SEL_MASTER_CLOCK = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FC16FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FC16FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_FRG17CLKSEL_SEL_MAIN = 0,
+ /* FRG PLL Clock */
+ RT500_CLKCTL1_FRG17CLKSEL_SEL_FRG_PLL = 1,
+ /* FRO_DIV4 clock */
+ RT500_CLKCTL1_FRG17CLKSEL_SEL_FRRO_DIV4 = 2,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FRG17CLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FRG17CLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV2 Clock */
+ RT500_CLKCTL1_FLEXIOCLKSEL_SEL_FRRO_DIV2 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_FLEXIOCLKSEL_SEL_OSC_CLK = 1,
+ /* Master Clock In */
+ RT500_CLKCTL1_FLEXIOCLKSEL_SEL_MASTER_CLKIN = 2,
+ /* FC17 FRG Clock */
+ RT500_CLKCTL1_FLEXIOCLKSEL_SEL_FC17_FRG = 3,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_FLEXIOCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_FLEXIOCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_FLEXIOCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL1_FLEXIOCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL1_FLEXIOCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_FLEXIOCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL1_FLEXIOCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL1_FLEXIOCLKDIV_HALT_Enum;
+
+typedef enum {
+ /*
+ * The Divider change has finished (clock being divided must be running for
+ * this status to change).
+ */
+ RT500_CLKCTL1_FLEXIOCLKDIV_REQFLAG_REQFLAG_CHANGE_FINISHED = 0,
+ /* The Divider value has changed */
+ RT500_CLKCTL1_FLEXIOCLKDIV_REQFLAG_REQFLAG_CHANGED = 1,
+} RT500_CLKCTL1_FLEXIOCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_FRGPLLCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL1_FRGPLLCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL1_FRGPLLCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_FRGPLLCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL1_FRGPLLCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL1_FRGPLLCLKDIV_HALT_Enum;
+
+typedef enum {
+ /*
+ * The Divider change has finished (clock being divided must be running for
+ * this status to change).
+ */
+ RT500_CLKCTL1_FRGPLLCLKDIV_REQFLAG_REQFLAG_CHANGE_FINISHED = 0,
+ /* The Divider value has changed. */
+ RT500_CLKCTL1_FRGPLLCLKDIV_REQFLAG_REQFLAG_CHANGED = 1,
+} RT500_CLKCTL1_FRGPLLCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* FRO Clock (Divided-by-4 selection) */
+ RT500_CLKCTL1_DMIC0FCLKSEL_SEL_FRRO_DIV4 = 0,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_DMIC0FCLKSEL_SEL_AUDIO_PLL = 1,
+ /* Master Clock In */
+ RT500_CLKCTL1_DMIC0FCLKSEL_SEL_MASTER_CLOCK = 2,
+ /* Low Power Oscillator Clock (LPOSC) */
+ RT500_CLKCTL1_DMIC0FCLKSEL_SEL_LPOSC = 3,
+ /* 32 KHz Wake Clock */
+ RT500_CLKCTL1_DMIC0FCLKSEL_SEL_WAKE_32KHZ = 4,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_DMIC0FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_DMIC0FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_DMIC0FCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL1_DMIC0FCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL1_DMIC0FCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_DMIC0FCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL1_DMIC0FCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL1_DMIC0FCLKDIV_HALT_Enum;
+
+typedef enum {
+ /*
+ * The Divider change has finished (clock being divided must be running for
+ * this status to change).
+ */
+ RT500_CLKCTL1_DMIC0FCLKDIV_REQFLAG_REQFLAG_CHANGE_FINISHED = 0,
+ /* The Divider value has changed. */
+ RT500_CLKCTL1_DMIC0FCLKDIV_REQFLAG_REQFLAG_CHANGED = 1,
+} RT500_CLKCTL1_DMIC0FCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_CT32BITFCLKSEL_SEL_MAIN = 0,
+ /* FRO_DIV1 Clock */
+ RT500_CLKCTL1_CT32BITFCLKSEL_SEL_FRO = 1,
+ /* Audio PLL Clock */
+ RT500_CLKCTL1_CT32BITFCLKSEL_SEL_AUDIO_PLL = 2,
+ /* Master Clock In */
+ RT500_CLKCTL1_CT32BITFCLKSEL_SEL_MASTER_CLOCK = 3,
+ /* 32 KHZ Wake Clock */
+ RT500_CLKCTL1_CT32BITFCLKSEL_SEL_WAKE_32KHZ = 4,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_CT32BITFCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_CT32BITFCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* FRO_DIV8 Clock */
+ RT500_CLKCTL1_AUDIOMCLKSEL_SEL_FRRO_DIV8 = 0,
+ /* AUDIO PLL Clock (Shared Domain) */
+ RT500_CLKCTL1_AUDIOMCLKSEL_SEL_AUDIO_PLL = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_AUDIOMCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_AUDIOMCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_AUDIOMCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL1_AUDIOMCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL1_AUDIOMCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_AUDIOMCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL1_AUDIOMCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL1_AUDIOMCLKDIV_HALT_Enum;
+
+typedef enum {
+ /*
+ * The Divider change has finished (clock being divided must be running for
+ * this status to change).
+ */
+ RT500_CLKCTL1_AUDIOMCLKDIV_REQFLAG_REQFLAG_CHANGE_FINISHED = 0,
+ /* The Divider value has changed. */
+ RT500_CLKCTL1_AUDIOMCLKDIV_REQFLAG_REQFLAG_CHANGED = 1,
+} RT500_CLKCTL1_AUDIOMCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* OSC_CLK Clock */
+ RT500_CLKCTL1_CLKOUTSEL0_SEL_OSC_CLK = 0,
+ /* Low Power Oscillator Clock (LPOSC) */
+ RT500_CLKCTL1_CLKOUTSEL0_SEL_LPOSC = 1,
+ /* FRO_DIV2 Clock */
+ RT500_CLKCTL1_CLKOUTSEL0_SEL_FRO = 2,
+ /* Main Clock */
+ RT500_CLKCTL1_CLKOUTSEL0_SEL_MAIN = 3,
+ /* DSP Main Clock */
+ RT500_CLKCTL1_CLKOUTSEL0_SEL_DSP_MAIN = 4,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_CLKOUTSEL0_SEL_NONE = 7,
+} RT500_CLKCTL1_CLKOUTSEL0_SEL_Enum;
+
+typedef enum {
+ /* CLKOUTSEL0 Multiplexed Output */
+ RT500_CLKCTL1_CLKOUTSEL1_SEL_CLKOUTSEL0_MUX_OUT = 0,
+ /* Main System PLL Clock */
+ RT500_CLKCTL1_CLKOUTSEL1_SEL_MAIN_PLL = 1,
+ /* SYSPLL0 AUX0_PLL_Clock */
+ RT500_CLKCTL1_CLKOUTSEL1_SEL_SYSPLL0_AUX0_PLL = 2,
+ /* DSP PLL Clock */
+ RT500_CLKCTL1_CLKOUTSEL1_SEL_DSP_PLL = 3,
+ /* SYSPLL0 AUX1_PLL_Clock */
+ RT500_CLKCTL1_CLKOUTSEL1_SEL_SYSPLL0_AUX1_PLL = 4,
+ /* AUDIO PLL Clock */
+ RT500_CLKCTL1_CLKOUTSEL1_SEL_AUDIO_PLL = 5,
+ /* 32 KHz RTC Clock */
+ RT500_CLKCTL1_CLKOUTSEL1_SEL_RTC_32KHZ = 6,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_CLKOUTSEL1_SEL_NONE = 7,
+} RT500_CLKCTL1_CLKOUTSEL1_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_CLKOUTFCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL1_CLKOUTFCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL1_CLKOUTFCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_CLKOUTFCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL1_CLKOUTFCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL1_CLKOUTFCLKDIV_HALT_Enum;
+
+typedef enum {
+ /*
+ * The Divider change has finished (clock being divided must be running for
+ * this status to change).
+ */
+ RT500_CLKCTL1_CLKOUTFCLKDIV_REQFLAG_REQFLAG_CHANGE_FINISHED = 0,
+ /* The Divider value has changed */
+ RT500_CLKCTL1_CLKOUTFCLKDIV_REQFLAG_REQFLAG_CHANGED = 1,
+} RT500_CLKCTL1_CLKOUTFCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_I3C01FCLKSEL_SEL_MAIN = 0,
+ /* FRO_DIV8 Clock */
+ RT500_CLKCTL1_I3C01FCLKSEL_SEL_FRRO_DIV8 = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_I3C01FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_I3C01FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* I3C0 FCLK */
+ RT500_CLKCTL1_I3C01FCLKSTCSEL_SEL_I3C0 = 0,
+ /* Low Power Oscillator Clock (LPOSC) */
+ RT500_CLKCTL1_I3C01FCLKSTCSEL_SEL_LPOSC = 1,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_I3C01FCLKSTCSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_I3C01FCLKSTCSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_I3C01FCLKSTCDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL1_I3C01FCLKSTCDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL1_I3C01FCLKSTCDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_I3C01FCLKSTCDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL1_I3C01FCLKSTCDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL1_I3C01FCLKSTCDIV_HALT_Enum;
+
+typedef enum {
+ /*
+ * The Divider change has finished (clock being divided must be running for
+ * this status to change).
+ */
+ RT500_CLKCTL1_I3C01FCLKSTCDIV_REQFLAG_REQFLAG_CHANGE_FINISHED = 0,
+ /* The Divider value has changed. */
+ RT500_CLKCTL1_I3C01FCLKSTCDIV_REQFLAG_REQFLAG_CHANGED = 1,
+} RT500_CLKCTL1_I3C01FCLKSTCDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_I3C01FCLKSDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL1_I3C01FCLKSDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL1_I3C01FCLKSDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_I3C01FCLKSDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL1_I3C01FCLKSDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL1_I3C01FCLKSDIV_HALT_Enum;
+
+typedef enum {
+ /*
+ * The Divider change has finished (clock being divided must be running for
+ * this status to change).
+ */
+ RT500_CLKCTL1_I3C01FCLKSDIV_REQFLAG_REQFLAG_CHANGE_FINISHED = 0,
+ /* The Divider value has changed. */
+ RT500_CLKCTL1_I3C01FCLKSDIV_REQFLAG_REQFLAG_CHANGED = 1,
+} RT500_CLKCTL1_I3C01FCLKSDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_I3C01FCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL1_I3C01FCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL1_I3C01FCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_I3C01FCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL1_I3C01FCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL1_I3C01FCLKDIV_HALT_Enum;
+
+typedef enum {
+ /*
+ * The Divider change has finished (clock being divided must be running for
+ * this status to change).
+ */
+ RT500_CLKCTL1_I3C01FCLKDIV_REQFLAG_REQFLAG_CHANGE_FINISHED = 0,
+ /* The Divider value has changed. */
+ RT500_CLKCTL1_I3C01FCLKDIV_REQFLAG_REQFLAG_CHANGED = 1,
+} RT500_CLKCTL1_I3C01FCLKDIV_REQFLAG_Enum;
+
+typedef enum {
+ /* Low Power Oscillator Clock (LPOSC) */
+ RT500_CLKCTL1_I3C01FCLKSTSTCLKSEL_SEL_LPOSC = 0,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_I3C01FCLKSTSTCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_I3C01FCLKSTSTCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Low Power Oscillator Clock (LPOSC) */
+ RT500_CLKCTL1_WDT1FCLKSEL_SEL_LPOSC = 0,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_WDT1FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_WDT1FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* Main Clock */
+ RT500_CLKCTL1_ACMP0FCLKSEL_SEL_MAIN = 0,
+ /* FRO_DIV4 Clock */
+ RT500_CLKCTL1_ACMP0FCLKSEL_SEL_FRRO_DIV4 = 1,
+ /* SYSPLL0 AUX0_PLL_Clock */
+ RT500_CLKCTL1_ACMP0FCLKSEL_SEL_SYSPLL0_AUX0_PLL = 2,
+ /* SYSPLL0 AUX1_PLL_Clock */
+ RT500_CLKCTL1_ACMP0FCLKSEL_SEL_SYSPLL0_AUX1_PLL = 3,
+ /* None, output gated to reduce power */
+ RT500_CLKCTL1_ACMP0FCLKSEL_SEL_NONE = 7,
+} RT500_CLKCTL1_ACMP0FCLKSEL_SEL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_ACMP0FCLKDIV_RESET_DIVIDER_COUNTER_NOT_RESET = 0,
+ /* Reset the Divider Counter */
+ RT500_CLKCTL1_ACMP0FCLKDIV_RESET_DIVIDER_COUNTER_RESET = 1,
+} RT500_CLKCTL1_ACMP0FCLKDIV_RESET_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_CLKCTL1_ACMP0FCLKDIV_HALT_DIVIDER_COUNTER_NOT_HALT = 0,
+ /* Halt (stop) the Divider Counter */
+ RT500_CLKCTL1_ACMP0FCLKDIV_HALT_DIVIDER_COUNTER_HALT = 1,
+} RT500_CLKCTL1_ACMP0FCLKDIV_HALT_Enum;
+
+typedef enum {
+ /*
+ * The Divider change has finished (clock being divided must be running for
+ * this status to change).
+ */
+ RT500_CLKCTL1_ACMP0FCLKDIV_REQFLAG_REQFLAG_CHANGE_FINISHED = 0,
+ /* The Divider value has changed. */
+ RT500_CLKCTL1_ACMP0FCLKDIV_REQFLAG_REQFLAG_CHANGED = 1,
+} RT500_CLKCTL1_ACMP0FCLKDIV_REQFLAG_Enum;
+
+
+#define RT500_CLKCTL1_REGISTER_ACCESS_INFO_ARRAY(_name) \
+ struct RegisterAccessInfo _name[RT500_CLKCTL1_REGS_NO] = { \
+ [0 ... RT500_CLKCTL1_REGS_NO - 1] = { \
+ .name = "", \
+ .addr = -1, \
+ }, \
+ [R_RT500_CLKCTL1_PSCCTL0] = { \
+ .name = "PSCCTL0", \
+ .addr = 0x10, \
+ .ro = 0xD40000FF, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_PSCCTL1] = { \
+ .name = "PSCCTL1", \
+ .addr = 0x14, \
+ .ro = 0x4E7EFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_PSCCTL2] = { \
+ .name = "PSCCTL2", \
+ .addr = 0x18, \
+ .ro = 0x3FFCFA60, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_PSCCTL0_SET] = { \
+ .name = "PSCCTL0_SET", \
+ .addr = 0x40, \
+ .ro = 0xD40000FF, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_PSCCTL1_SET] = { \
+ .name = "PSCCTL1_SET", \
+ .addr = 0x44, \
+ .ro = 0x4E7EFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_PSCCTL2_SET] = { \
+ .name = "PSCCTL2_SET", \
+ .addr = 0x48, \
+ .ro = 0x3FFCFA60, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_PSCCTL0_CLR] = { \
+ .name = "PSCCTL0_CLR", \
+ .addr = 0x70, \
+ .ro = 0xD40000FF, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_PSCCTL1_CLR] = { \
+ .name = "PSCCTL1_CLR", \
+ .addr = 0x74, \
+ .ro = 0x4E7EFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_PSCCTL2_CLR] = { \
+ .name = "PSCCTL2_CLR", \
+ .addr = 0x78, \
+ .ro = 0x3FFCFA60, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_AUDIOPLL0CLKSEL] = { \
+ .name = "AUDIOPLL0CLKSEL", \
+ .addr = 0x200, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_AUDIOPLL0CTL0] = { \
+ .name = "AUDIOPLL0CTL0", \
+ .addr = 0x204, \
+ .ro = 0xFF00DFFC, \
+ .reset = 0x160002, \
+ }, \
+ [R_RT500_CLKCTL1_AUDIOPLL0LOCKTIMEDIV2] = { \
+ .name = "AUDIOPLL0LOCKTIMEDIV2", \
+ .addr = 0x20C, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xCAFE, \
+ }, \
+ [R_RT500_CLKCTL1_AUDIOPLL0NUM] = { \
+ .name = "AUDIOPLL0NUM", \
+ .addr = 0x210, \
+ .ro = 0xC0000000, \
+ .reset = 0x4DD2F15, \
+ }, \
+ [R_RT500_CLKCTL1_AUDIOPLL0DENOM] = { \
+ .name = "AUDIOPLL0DENOM", \
+ .addr = 0x214, \
+ .ro = 0xC0000000, \
+ .reset = 0x1FFFFFDB, \
+ }, \
+ [R_RT500_CLKCTL1_AUDIOPLL0PFD] = { \
+ .name = "AUDIOPLL0PFD", \
+ .addr = 0x218, \
+ .ro = 0x0, \
+ .reset = 0x80808080, \
+ }, \
+ [R_RT500_CLKCTL1_AUDIOPLLCLKDIV] = { \
+ .name = "AUDIOPLLCLKDIV", \
+ .addr = 0x240, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL1_DSPCPUCLKDIV] = { \
+ .name = "DSPCPUCLKDIV", \
+ .addr = 0x400, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL1_DSPCPUCLKSELA] = { \
+ .name = "DSPCPUCLKSELA", \
+ .addr = 0x430, \
+ .ro = 0xFFFFFFFC, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_DSPCPUCLKSELB] = { \
+ .name = "DSPCPUCLKSELB", \
+ .addr = 0x434, \
+ .ro = 0xFFFFFFFC, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_OSEVENTTFCLKSEL] = { \
+ .name = "OSEVENTTFCLKSEL", \
+ .addr = 0x480, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_FRG0CLKSEL] = { \
+ .name = "FRG0CLKSEL", \
+ .addr = 0x500, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG0CTL] = { \
+ .name = "FRG0CTL", \
+ .addr = 0x504, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC0FCLKSEL] = { \
+ .name = "FC0FCLKSEL", \
+ .addr = 0x508, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG1CLKSEL] = { \
+ .name = "FRG1CLKSEL", \
+ .addr = 0x520, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG1CTL] = { \
+ .name = "FRG1CTL", \
+ .addr = 0x524, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC1FCLKSEL] = { \
+ .name = "FC1FCLKSEL", \
+ .addr = 0x528, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG2CLKSEL] = { \
+ .name = "FRG2CLKSEL", \
+ .addr = 0x540, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG2CTL] = { \
+ .name = "FRG2CTL", \
+ .addr = 0x544, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC2FCLKSEL] = { \
+ .name = "FC2FCLKSEL", \
+ .addr = 0x548, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG3CLKSEL] = { \
+ .name = "FRG3CLKSEL", \
+ .addr = 0x560, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG3CTL] = { \
+ .name = "FRG3CTL", \
+ .addr = 0x564, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC3FCLKSEL] = { \
+ .name = "FC3FCLKSEL", \
+ .addr = 0x568, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG4CLKSEL] = { \
+ .name = "FRG4CLKSEL", \
+ .addr = 0x580, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG4CTL] = { \
+ .name = "FRG4CTL", \
+ .addr = 0x584, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC4FCLKSEL] = { \
+ .name = "FC4FCLKSEL", \
+ .addr = 0x588, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG5CLKSEL] = { \
+ .name = "FRG5CLKSEL", \
+ .addr = 0x5A0, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG5CTL] = { \
+ .name = "FRG5CTL", \
+ .addr = 0x5A4, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC5FCLKSEL] = { \
+ .name = "FC5FCLKSEL", \
+ .addr = 0x5A8, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG6CLKSEL] = { \
+ .name = "FRG6CLKSEL", \
+ .addr = 0x5C0, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG6CTL] = { \
+ .name = "FRG6CTL", \
+ .addr = 0x5C4, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC6FCLKSEL] = { \
+ .name = "FC6FCLKSEL", \
+ .addr = 0x5C8, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG7CLKSEL] = { \
+ .name = "FRG7CLKSEL", \
+ .addr = 0x5E0, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG7CTL] = { \
+ .name = "FRG7CTL", \
+ .addr = 0x5E4, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC7FCLKSEL] = { \
+ .name = "FC7FCLKSEL", \
+ .addr = 0x5E8, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG8CLKSEL] = { \
+ .name = "FRG8CLKSEL", \
+ .addr = 0x600, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG8CTL] = { \
+ .name = "FRG8CTL", \
+ .addr = 0x604, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC8FCLKSEL] = { \
+ .name = "FC8FCLKSEL", \
+ .addr = 0x608, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG9CLKSEL] = { \
+ .name = "FRG9CLKSEL", \
+ .addr = 0x620, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG9CTL] = { \
+ .name = "FRG9CTL", \
+ .addr = 0x624, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC9FCLKSEL] = { \
+ .name = "FC9FCLKSEL", \
+ .addr = 0x628, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG10CLKSEL] = { \
+ .name = "FRG10CLKSEL", \
+ .addr = 0x640, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG10CTL] = { \
+ .name = "FRG10CTL", \
+ .addr = 0x644, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC10FCLKSEL] = { \
+ .name = "FC10FCLKSEL", \
+ .addr = 0x648, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG11CLKSEL] = { \
+ .name = "FRG11CLKSEL", \
+ .addr = 0x660, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG11CTL] = { \
+ .name = "FRG11CTL", \
+ .addr = 0x664, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC11FCLKSEL] = { \
+ .name = "FC11FCLKSEL", \
+ .addr = 0x668, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG12CLKSEL] = { \
+ .name = "FRG12CLKSEL", \
+ .addr = 0x680, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG12CTL] = { \
+ .name = "FRG12CTL", \
+ .addr = 0x684, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC12FCLKSEL] = { \
+ .name = "FC12FCLKSEL", \
+ .addr = 0x688, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG13CLKSEL] = { \
+ .name = "FRG13CLKSEL", \
+ .addr = 0x6A0, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG13CTL] = { \
+ .name = "FRG13CTL", \
+ .addr = 0x6A4, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC13FCLKSEL] = { \
+ .name = "FC13FCLKSEL", \
+ .addr = 0x6A8, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG14CLKSEL] = { \
+ .name = "FRG14CLKSEL", \
+ .addr = 0x6C0, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG14CTL] = { \
+ .name = "FRG14CTL", \
+ .addr = 0x6C4, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC14FCLKSEL] = { \
+ .name = "FC14FCLKSEL", \
+ .addr = 0x6C8, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG15CLKSEL] = { \
+ .name = "FRG15CLKSEL", \
+ .addr = 0x6E0, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG15CTL] = { \
+ .name = "FRG15CTL", \
+ .addr = 0x6E4, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC15FCLKSEL] = { \
+ .name = "FC15FCLKSEL", \
+ .addr = 0x6E8, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG16CLKSEL] = { \
+ .name = "FRG16CLKSEL", \
+ .addr = 0x700, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG16CTL] = { \
+ .name = "FRG16CTL", \
+ .addr = 0x704, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FC16FCLKSEL] = { \
+ .name = "FC16FCLKSEL", \
+ .addr = 0x708, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG17CLKSEL] = { \
+ .name = "FRG17CLKSEL", \
+ .addr = 0x720, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FRG17CTL] = { \
+ .name = "FRG17CTL", \
+ .addr = 0x724, \
+ .ro = 0xFFFF0000, \
+ .reset = 0xFF, \
+ }, \
+ [R_RT500_CLKCTL1_FLEXIOCLKSEL] = { \
+ .name = "FLEXIOCLKSEL", \
+ .addr = 0x728, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_FLEXIOCLKDIV] = { \
+ .name = "FLEXIOCLKDIV", \
+ .addr = 0x740, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL1_FRGPLLCLKDIV] = { \
+ .name = "FRGPLLCLKDIV", \
+ .addr = 0x760, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL1_DMIC0FCLKSEL] = { \
+ .name = "DMIC0FCLKSEL", \
+ .addr = 0x780, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_DMIC0FCLKDIV] = { \
+ .name = "DMIC0FCLKDIV", \
+ .addr = 0x784, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL1_CT32BITFCLKSEL0] = { \
+ .name = "CT32BITFCLKSEL0", \
+ .addr = 0x7A0, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_CT32BITFCLKSEL1] = { \
+ .name = "CT32BITFCLKSEL1", \
+ .addr = 0x7A4, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_CT32BITFCLKSEL2] = { \
+ .name = "CT32BITFCLKSEL2", \
+ .addr = 0x7A8, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_CT32BITFCLKSEL3] = { \
+ .name = "CT32BITFCLKSEL3", \
+ .addr = 0x7AC, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_CT32BITFCLKSEL4] = { \
+ .name = "CT32BITFCLKSEL4", \
+ .addr = 0x7B0, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_AUDIOMCLKSEL] = { \
+ .name = "AUDIOMCLKSEL", \
+ .addr = 0x7C0, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_AUDIOMCLKDIV] = { \
+ .name = "AUDIOMCLKDIV", \
+ .addr = 0x7C4, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL1_CLKOUTSEL0] = { \
+ .name = "CLKOUTSEL0", \
+ .addr = 0x7E0, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_CLKOUTSEL1] = { \
+ .name = "CLKOUTSEL1", \
+ .addr = 0x7E4, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_CLKOUTFCLKDIV] = { \
+ .name = "CLKOUTFCLKDIV", \
+ .addr = 0x7E8, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL1_I3C01FCLKSEL] = { \
+ .name = "I3C01FCLKSEL", \
+ .addr = 0x800, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_I3C01FCLKSTCSEL] = { \
+ .name = "I3C01FCLKSTCSEL", \
+ .addr = 0x804, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_I3C01FCLKSTCDIV] = { \
+ .name = "I3C01FCLKSTCDIV", \
+ .addr = 0x808, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL1_I3C01FCLKSDIV] = { \
+ .name = "I3C01FCLKSDIV", \
+ .addr = 0x80C, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL1_I3C01FCLKDIV] = { \
+ .name = "I3C01FCLKDIV", \
+ .addr = 0x810, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ [R_RT500_CLKCTL1_I3C01FCLKSTSTCLKSEL] = { \
+ .name = "I3C01FCLKSTSTCLKSEL", \
+ .addr = 0x814, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_WDT1FCLKSEL] = { \
+ .name = "WDT1FCLKSEL", \
+ .addr = 0x820, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_CLKCTL1_ACMP0FCLKSEL] = { \
+ .name = "ACMP0FCLKSEL", \
+ .addr = 0x830, \
+ .ro = 0xFFFFFFF8, \
+ .reset = 0x7, \
+ }, \
+ [R_RT500_CLKCTL1_ACMP0FCLKDIV] = { \
+ .name = "ACMP0FCLKDIV", \
+ .addr = 0x834, \
+ .ro = 0x1FFFFF00, \
+ .reset = 0x40000000, \
+ }, \
+ }
diff --git a/include/hw/misc/rt500_clk_freqs.h b/include/hw/misc/rt500_clk_freqs.h
new file mode 100644
index 0000000000..1e366d4967
--- /dev/null
+++ b/include/hw/misc/rt500_clk_freqs.h
@@ -0,0 +1,18 @@
+/*
+ * QEMU model for RT500 Clock Controller
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_MISC_RT500_CLK_FREQS_H
+#define HW_MISC_RT500_CLK_FREQS_H
+
+#define RTC32KHZ_CLK_HZ 32000
+#define LPOSC_CLK_HZ 1000000
+
+#endif /* HW_MISC_RT500_CLK_FREQS_H */
diff --git a/include/hw/misc/rt500_clkctl0.h b/include/hw/misc/rt500_clkctl0.h
new file mode 100644
index 0000000000..890743a2ce
--- /dev/null
+++ b/include/hw/misc/rt500_clkctl0.h
@@ -0,0 +1,35 @@
+/*
+ * QEMU model for RT500 Clock Controller
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_MISC_RT500_CLKCTL0_H
+#define HW_MISC_RT500_CLKCTL0_H
+
+#include "hw/arm/svd/rt500_clkctl0.h"
+#include "hw/sysbus.h"
+
+#define TYPE_RT500_CLKCTL0 "rt500-clkctl0"
+#define RT500_CLKCTL0(o) OBJECT_CHECK(RT500ClkCtl0State, o, TYPE_RT500_CLKCTL0)
+
+#define SYSTICKFCLKSEL_DIVOUT 0
+#define SYSTICKFCLKSEL_LPOSC 1
+#define SYSTICKFCLKSEL_32KHZRTC 2
+#define SYSTICKFCLKSEL_NONE 7
+
+typedef struct {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+ uint32_t regs[RT500_CLKCTL0_REGS_NO];
+ Clock *systick_clk;
+ Clock *sysclk;
+} RT500ClkCtl0State;
+
+#endif /* HW_MISC_RT500_CLKCTL0_H */
diff --git a/include/hw/misc/rt500_clkctl1.h b/include/hw/misc/rt500_clkctl1.h
new file mode 100644
index 0000000000..8b012b1357
--- /dev/null
+++ b/include/hw/misc/rt500_clkctl1.h
@@ -0,0 +1,36 @@
+/*
+ * QEMU model for RT500 Clock Controller
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+
+#ifndef HW_MISC_RT500_CLKCTL1_H
+#define HW_MISC_RT500_CLKCTL1_H
+
+#include "hw/arm/svd/rt500_clkctl1.h"
+#include "hw/sysbus.h"
+
+#define TYPE_RT500_CLKCTL1 "rt500-clkctl1"
+#define RT500_CLKCTL1(o) OBJECT_CHECK(RT500ClkCtl1State, o, TYPE_RT500_CLKCTL1)
+
+#define OSEVENTTFCLKSEL_LPOSC 0
+#define OSEVENTTFCLKSEL_32KHZRTC 1
+#define OSEVENTTFCLKSEL_HCLK 2
+#define OSEVENTTFCLKSEL_NONE 7
+
+typedef struct {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+ uint32_t regs[RT500_CLKCTL1_REGS_NO];
+ Clock *sysclk;
+ Clock *ostimer_clk;
+} RT500ClkCtl1State;
+
+#endif /* HW_MISC_RT500_CLKCTL1_H */
diff --git a/hw/misc/rt500_clkctl0.c b/hw/misc/rt500_clkctl0.c
new file mode 100644
index 0000000000..7e7b176719
--- /dev/null
+++ b/hw/misc/rt500_clkctl0.c
@@ -0,0 +1,253 @@
+/*
+ * QEMU model for RT500 Clock Controller
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/clock.h"
+#include "hw/irq.h"
+#include "hw/qdev-clock.h"
+#include "hw/qdev-properties.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+#include "hw/misc/rt500_clkctl0.h"
+#include "hw/misc/rt500_clk_freqs.h"
+
+#include "trace.h"
+
+#define REG(s, reg) (s->regs[R_RT500_CLKCTL0_##reg])
+#define RF_RD(s, reg, field) \
+ ARRAY_FIELD_EX32(s->regs, RT500_CLKCTL0_##reg, field)
+#define RF_WR(s, reg, field, val) \
+ ARRAY_FIELD_DP32(s->regs, RT500_CLKCTL0_##reg, field, val)
+
+static const RT500_CLKCTL0_REGISTER_ACCESS_INFO_ARRAY(reg_info);
+
+static MemTxResult rt500_clkctl0_read(void *opaque, hwaddr addr,
+ uint64_t *data, unsigned size,
+ MemTxAttrs attrs)
+{
+ RT500ClkCtl0State *s = opaque;
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+
+ switch (addr) {
+ case A_RT500_CLKCTL0_PSCCTL0_SET:
+ case A_RT500_CLKCTL0_PSCCTL1_SET:
+ case A_RT500_CLKCTL0_PSCCTL2_SET:
+ case A_RT500_CLKCTL0_PSCCTL0_CLR:
+ case A_RT500_CLKCTL0_PSCCTL1_CLR:
+ case A_RT500_CLKCTL0_PSCCTL2_CLR:
+ /* write only registers */
+ return MEMTX_ERROR;
+ default:
+ *data = s->regs[addr / 4];
+ break;
+ }
+
+ trace_rt500_clkctl0_reg_read(rai->name, addr, *data);
+ return MEMTX_OK;
+}
+
+static inline void set_systick_clk_from_div(RT500ClkCtl0State *s)
+{
+ uint32_t div = RF_RD(s, SYSTICKFCLKDIV, DIV) + 1;
+ uint32_t rate = clock_get_hz(s->sysclk);
+
+ clock_set_hz(s->systick_clk, rate / div);
+}
+
+static MemTxResult rt500_clkctl0_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size,
+ MemTxAttrs attrs)
+{
+ RT500ClkCtl0State *s = opaque;
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+ struct RegisterInfo ri = {
+ .data = &s->regs[addr / 4],
+ .data_size = 4,
+ .access = rai,
+ };
+
+ trace_rt500_clkctl0_reg_write(rai->name, addr, value);
+
+ switch (addr) {
+ case A_RT500_CLKCTL0_PSCCTL0:
+ case A_RT500_CLKCTL0_PSCCTL1:
+ case A_RT500_CLKCTL0_PSCCTL2:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+ break;
+ }
+ case A_RT500_CLKCTL0_PSCCTL0_SET:
+ case A_RT500_CLKCTL0_PSCCTL1_SET:
+ case A_RT500_CLKCTL0_PSCCTL2_SET:
+ {
+ uint32_t tmp;
+
+ tmp = A_RT500_CLKCTL0_PSCCTL0 + (addr - A_RT500_CLKCTL0_PSCCTL0_SET);
+ s->regs[tmp / 4] |= value;
+ break;
+ }
+ case A_RT500_CLKCTL0_PSCCTL0_CLR:
+ case A_RT500_CLKCTL0_PSCCTL1_CLR:
+ case A_RT500_CLKCTL0_PSCCTL2_CLR:
+ {
+ uint32_t tmp;
+
+ tmp = A_RT500_CLKCTL0_PSCCTL0 + (addr - A_RT500_CLKCTL0_PSCCTL0_CLR);
+ s->regs[tmp / 4] &= ~value;
+ break;
+ }
+ default:
+ register_write(&ri, value, ~0, NULL, false);
+ }
+
+ switch (addr) {
+ case A_RT500_CLKCTL0_SYSPLL0PFD:
+ {
+ if (!RF_RD(s, SYSPLL0PFD, PFD0_CLKGATE)) {
+ RF_WR(s, SYSPLL0PFD, PFD0_CLKRDY, 1);
+ } else {
+ RF_WR(s, SYSPLL0PFD, PFD0_CLKRDY, 0);
+ }
+ if (!RF_RD(s, SYSPLL0PFD, PFD1_CLKGATE)) {
+ RF_WR(s, SYSPLL0PFD, PFD1_CLKRDY, 1);
+ } else {
+ RF_WR(s, SYSPLL0PFD, PFD1_CLKRDY, 0);
+ }
+ if (!RF_RD(s, SYSPLL0PFD, PFD2_CLKGATE)) {
+ RF_WR(s, SYSPLL0PFD, PFD2_CLKRDY, 1);
+ } else {
+ RF_WR(s, SYSPLL0PFD, PFD2_CLKRDY, 0);
+ }
+ if (!RF_RD(s, SYSPLL0PFD, PFD3_CLKGATE)) {
+ RF_WR(s, SYSPLL0PFD, PFD3_CLKRDY, 1);
+ } else {
+ RF_WR(s, SYSPLL0PFD, PFD3_CLKRDY, 0);
+ }
+ break;
+ }
+ case A_RT500_CLKCTL0_SYSTICKFCLKSEL:
+ {
+ switch (RF_RD(s, SYSTICKFCLKSEL, SEL)) {
+ case SYSTICKFCLKSEL_DIVOUT:
+ {
+ set_systick_clk_from_div(s);
+ break;
+ }
+ case SYSTICKFCLKSEL_LPOSC:
+ {
+ clock_set_hz(s->systick_clk, LPOSC_CLK_HZ);
+ break;
+ }
+ case SYSTICKFCLKSEL_32KHZRTC:
+ {
+ clock_set_hz(s->systick_clk, RTC32KHZ_CLK_HZ);
+ break;
+ }
+ case SYSTICKFCLKSEL_NONE:
+ {
+ clock_set_hz(s->systick_clk, 0);
+ break;
+ }
+ }
+ clock_propagate(s->systick_clk);
+ break;
+ }
+ case A_RT500_CLKCTL0_SYSTICKFCLKDIV:
+ {
+ if (RF_RD(s, SYSTICKFCLKSEL, SEL) == SYSTICKFCLKSEL_DIVOUT) {
+ set_systick_clk_from_div(s);
+ clock_propagate(s->systick_clk);
+ }
+ break;
+ }
+ }
+
+ return MEMTX_OK;
+}
+
+static const MemoryRegionOps rt500_clkctl0_ops = {
+ .read_with_attrs = rt500_clkctl0_read,
+ .write_with_attrs = rt500_clkctl0_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ .unaligned = false,
+ },
+};
+
+static void rt500_clkctl0_reset_enter(Object *obj, ResetType type)
+{
+ RT500ClkCtl0State *s = RT500_CLKCTL0(obj);
+
+ for (int i = 0; i < RT500_CLKCTL0_REGS_NO; i++) {
+ hwaddr addr = reg_info[i].addr;
+
+ if (addr != -1) {
+ struct RegisterInfo ri = {
+ .data = &s->regs[addr / 4],
+ .data_size = 4,
+ .access = ®_info[i],
+ };
+
+ register_reset(&ri);
+ }
+ }
+
+ /* clock OK immediately after reset */
+ REG(s, FROCLKSTATUS) = 0x00000001;
+}
+
+static void rt500_clkctl0_init(Object *obj)
+{
+ RT500ClkCtl0State *s = RT500_CLKCTL0(obj);
+
+ memory_region_init_io(&s->mmio, obj, &rt500_clkctl0_ops, s,
+ TYPE_RT500_CLKCTL0, sizeof(s->regs));
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+ s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
+ s->systick_clk = qdev_init_clock_out(DEVICE(s), "systick_clk");
+}
+
+static const VMStateDescription vmstate_rt500_clkctl0 = {
+ .name = "rt500-clkctl0",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(regs, RT500ClkCtl0State, RT500_CLKCTL0_REGS_NO),
+ VMSTATE_CLOCK(systick_clk, RT500ClkCtl0State),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void rt500_clkctl0_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+
+ rc->phases.enter = rt500_clkctl0_reset_enter;
+ dc->vmsd = &vmstate_rt500_clkctl0;
+}
+
+static const TypeInfo rt500_clkctl0_types[] = {
+ {
+ .name = TYPE_RT500_CLKCTL0,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(RT500ClkCtl0State),
+ .instance_init = rt500_clkctl0_init,
+ .class_init = rt500_clkctl0_class_init,
+ },
+};
+
+DEFINE_TYPES(rt500_clkctl0_types);
+
diff --git a/hw/misc/rt500_clkctl1.c b/hw/misc/rt500_clkctl1.c
new file mode 100644
index 0000000000..ed234ce0f6
--- /dev/null
+++ b/hw/misc/rt500_clkctl1.c
@@ -0,0 +1,238 @@
+/*
+ * QEMU model for RT500 Clock Controller
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/clock.h"
+#include "hw/irq.h"
+#include "hw/qdev-clock.h"
+#include "hw/qdev-properties.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+#include "hw/misc/rt500_clkctl1.h"
+#include "hw/misc/rt500_clk_freqs.h"
+
+#include "trace.h"
+
+#define REG(s, reg) (s->regs[R_RT500_CLKCTL1_##reg])
+#define RF_RD(s, reg, field) \
+ ARRAY_FIELD_EX32(s->regs, RT500_CLKCTL1_##reg, field)
+#define RF_WR(s, reg, field, val) \
+ ARRAY_FIELD_DP32(s->regs, RT500_CLKCTL1_##reg, field, val)
+
+static RT500_CLKCTL1_REGISTER_ACCESS_INFO_ARRAY(reg_info);
+
+static MemTxResult rt500_clkctl1_read(void *opaque, hwaddr addr,
+ uint64_t *data, unsigned size,
+ MemTxAttrs attrs)
+{
+ RT500ClkCtl1State *s = opaque;
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+ MemTxResult ret = MEMTX_OK;
+
+ switch (addr) {
+ case A_RT500_CLKCTL1_PSCCTL0_SET:
+ case A_RT500_CLKCTL1_PSCCTL1_SET:
+ case A_RT500_CLKCTL1_PSCCTL2_SET:
+ case A_RT500_CLKCTL1_PSCCTL0_CLR:
+ case A_RT500_CLKCTL1_PSCCTL1_CLR:
+ case A_RT500_CLKCTL1_PSCCTL2_CLR:
+ /* write only registers */
+ ret = MEMTX_ERROR;
+ break;
+ default:
+ *data = s->regs[addr / 4];
+ break;
+ }
+
+ trace_rt500_clkctl1_reg_read(rai->name, addr, *data);
+ return ret;
+}
+
+static MemTxResult rt500_clkctl1_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size,
+ MemTxAttrs attrs)
+{
+ RT500ClkCtl1State *s = opaque;
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+ struct RegisterInfo ri = {
+ .data = &s->regs[addr / 4],
+ .data_size = 4,
+ .access = rai,
+ };
+
+ trace_rt500_clkctl1_reg_write(rai->name, addr, value);
+
+ switch (addr) {
+ case A_RT500_CLKCTL1_PSCCTL0:
+ case A_RT500_CLKCTL1_PSCCTL1:
+ case A_RT500_CLKCTL1_PSCCTL2:
+ {
+ s->regs[addr / 4] = value | s->regs[addr / 4];
+ break;
+ }
+ case A_RT500_CLKCTL1_PSCCTL0_SET:
+ case A_RT500_CLKCTL1_PSCCTL1_SET:
+ case A_RT500_CLKCTL1_PSCCTL2_SET:
+ {
+ uint32_t tmp;
+
+ tmp = A_RT500_CLKCTL1_PSCCTL0 + (addr - A_RT500_CLKCTL1_PSCCTL0_SET);
+ s->regs[tmp / 4] |= value;
+ break;
+ }
+ case A_RT500_CLKCTL1_PSCCTL0_CLR:
+ case A_RT500_CLKCTL1_PSCCTL1_CLR:
+ case A_RT500_CLKCTL1_PSCCTL2_CLR:
+ {
+ uint32_t tmp;
+
+ tmp = A_RT500_CLKCTL1_PSCCTL0 + (addr - A_RT500_CLKCTL1_PSCCTL0_CLR);
+ s->regs[tmp / 4] &= ~value;
+ break;
+ }
+ default:
+ register_write(&ri, value, ~0, NULL, false);
+ }
+
+ switch (addr) {
+ case A_RT500_CLKCTL1_AUDIOPLL0PFD:
+ {
+ if (!RF_RD(s, AUDIOPLL0PFD, PFD0_CLKGATE)) {
+ RF_WR(s, AUDIOPLL0PFD, PFD0_CLKRDY, 1);
+ } else {
+ RF_WR(s, AUDIOPLL0PFD, PFD0_CLKRDY, 0);
+ }
+ if (!RF_RD(s, AUDIOPLL0PFD, PFD1_CLKGATE)) {
+ RF_WR(s, AUDIOPLL0PFD, PFD1_CLKRDY, 1);
+ } else {
+ RF_WR(s, AUDIOPLL0PFD, PFD1_CLKRDY, 0);
+ }
+ if (!RF_RD(s, AUDIOPLL0PFD, PFD2_CLKGATE)) {
+ RF_WR(s, AUDIOPLL0PFD, PFD2_CLKRDY, 1);
+ } else {
+ RF_WR(s, AUDIOPLL0PFD, PFD2_CLKRDY, 0);
+ }
+ if (!RF_RD(s, AUDIOPLL0PFD, PFD3_CLKGATE)) {
+ RF_WR(s, AUDIOPLL0PFD, PFD3_CLKRDY, 1);
+ } else {
+ RF_WR(s, AUDIOPLL0PFD, PFD3_CLKRDY, 0);
+ }
+ break;
+ }
+ case A_RT500_CLKCTL1_OSEVENTTFCLKSEL:
+ {
+ switch (RF_RD(s, OSEVENTTFCLKSEL, SEL)) {
+ case OSEVENTTFCLKSEL_LPOSC:
+ {
+ clock_set_hz(s->ostimer_clk, LPOSC_CLK_HZ);
+ break;
+ }
+ case OSEVENTTFCLKSEL_32KHZRTC:
+ {
+ clock_set_hz(s->ostimer_clk, RTC32KHZ_CLK_HZ);
+ break;
+ }
+ case OSEVENTTFCLKSEL_HCLK:
+ {
+ clock_set_hz(s->ostimer_clk, clock_get_hz(s->sysclk));
+ break;
+ }
+ case OSEVENTTFCLKSEL_NONE:
+ {
+ clock_set_hz(s->ostimer_clk, 0);
+ break;
+ }
+ }
+
+ clock_propagate(s->ostimer_clk);
+ break;
+ }
+ }
+
+ return MEMTX_OK;
+}
+
+
+static const MemoryRegionOps rt500_clkctl1_ops = {
+ .read_with_attrs = rt500_clkctl1_read,
+ .write_with_attrs = rt500_clkctl1_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ .unaligned = false,
+ },
+};
+
+static void rt500_clkctl1_reset(Object *obj, ResetType type)
+{
+ RT500ClkCtl1State *s = RT500_CLKCTL1(obj);
+
+ for (int i = 0; i < RT500_CLKCTL1_REGS_NO; i++) {
+ hwaddr addr = reg_info[i].addr;
+
+ if (addr != -1) {
+ struct RegisterInfo ri = {
+ .data = &s->regs[addr / 4],
+ .data_size = 4,
+ .access = ®_info[i],
+ };
+
+ register_reset(&ri);
+ }
+ }
+}
+
+static void rt500_clkctl1_init(Object *obj)
+{
+ RT500ClkCtl1State *s = RT500_CLKCTL1(obj);
+
+ memory_region_init_io(&s->mmio, obj, &rt500_clkctl1_ops, s,
+ TYPE_RT500_CLKCTL1, sizeof(s->regs));
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+ s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
+ s->ostimer_clk = qdev_init_clock_out(DEVICE(s), "ostimer_clk");
+}
+
+static const VMStateDescription vmstate_rt500_clkctl1 = {
+ .name = "rt500-clkctl1",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(regs, RT500ClkCtl1State, RT500_CLKCTL1_REGS_NO),
+ VMSTATE_CLOCK(ostimer_clk, RT500ClkCtl1State),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void rt500_clkctl1_class_init(ObjectClass *klass, void *data)
+{
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ rc->phases.enter = rt500_clkctl1_reset;
+ dc->vmsd = &vmstate_rt500_clkctl1;
+
+}
+
+static const TypeInfo rt500_clkctl1_types[] = {
+ {
+ .name = TYPE_RT500_CLKCTL1,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(RT500ClkCtl1State),
+ .instance_init = rt500_clkctl1_init,
+ .class_init = rt500_clkctl1_class_init,
+ }
+};
+
+DEFINE_TYPES(rt500_clkctl1_types);
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 1ad60da7aa..668135bc85 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -712,3 +712,8 @@ config ARMSSE
select UNIMP
select SSE_COUNTER
select SSE_TIMER
+
+config RT500
+ bool
+ select FLEXCOMM
+ select RT500_CLKCTL
diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build
index 7f1c847caf..d017010b73 100644
--- a/hw/arm/svd/meson.build
+++ b/hw/arm/svd/meson.build
@@ -13,4 +13,10 @@ if get_option('mcux-soc-svd')
run_target('svd-flexcomm-spi', command: svd_gen_header +
[ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_spi.h',
'-p', 'SPI0', '-t', 'FLEXCOMM_SPI'])
+ run_target('svd-rt500-clkctl0', command: svd_gen_header +
+ [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/rt500_clkctl0.h',
+ '-p', 'CLKCTL0', '-t', 'RT500_CLKCTL0'])
+ run_target('svd-rt500-clkctl1', command: svd_gen_header +
+ [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/rt500_clkctl1.h',
+ '-p', 'CLKCTL1', '-t', 'RT500_CLKCTL1'])
endif
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index b373e651e1..02feb93840 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -218,4 +218,7 @@ config FLEXCOMM
select I2C
select SSI
+config RT500_CLKCTL
+ bool
+
source macio/Kconfig
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 749f688e84..e6d97b387c 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -159,3 +159,4 @@ system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c'))
system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c'))
system_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm.c'))
+system_ss.add(when: 'CONFIG_RT500_CLKCTL', if_true: files('rt500_clkctl0.c', 'rt500_clkctl1.c'))
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index dc245905dc..b19393dd36 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -368,3 +368,11 @@ flexcomm_irq(const char *id, uint8_t irq) "%s %d"
flexcomm_reg_read(const char *devname, const char *regname, uint32_t addr, uint32_t val) "%s: %s[0x%04x] -> 0x%08x"
flexcomm_reg_write(const char *dename, const char *regname, uint32_t addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x"
flexcomm_fifostat(const char *id, uint32_t fifostat, uint32_t fifoinstat) "%s: %08x %08x"
+
+# rt500_clkctl0.c
+rt500_clkctl0_reg_read(const char *regname, uint32_t addr, uint32_t val) "%s[0x%04x] -> 0x%08x"
+rt500_clkctl0_reg_write(const char *regname, uint32_t addr, uint32_t val) "%s[0x%04x] <- 0x%08x"
+
+# rt500_clkctl1.c
+rt500_clkctl1_reg_read(const char *regname, uint32_t addr, uint32_t val) "%s[0x%04x] -> 0x%08x"
+rt500_clkctl1_reg_write(const char *regname, uint32_t addr, uint32_t val) "%s[0x%04x] <- 0x%08x"
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 11/25] hw/ssi: add support for flexspi
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (9 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 10/25] hw/misc: add support for RT500's clock controller Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 12/25] hw/misc: add support for RT500's reset controller Octavian Purdila
` (13 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
This is mostly a stub which completes SPI transactions as noops
by masking out the error interrupts and never clearing the IPCMDDONE
interrupt.
Although incomplete, this allows software that uses NXP's mcuxpresso
SDK to run the SDK board initialization functions.
It also supports AHB memory access, aka XIP, for now as simple RAM
memory regions.
The patch includes an automatically generated header which contains
the register layout and helpers.
The header can be regenerated with the svd-flexspi target when the
build is configured with --enable-mcux-soc-svd.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
include/hw/arm/svd/flexspi.h | 2656 ++++++++++++++++++++++++++++++++++
include/hw/ssi/flexspi.h | 31 +
hw/ssi/flexspi.c | 181 +++
hw/arm/svd/meson.build | 3 +
hw/ssi/Kconfig | 4 +
hw/ssi/meson.build | 1 +
hw/ssi/trace-events | 4 +
7 files changed, 2880 insertions(+)
create mode 100644 include/hw/arm/svd/flexspi.h
create mode 100644 include/hw/ssi/flexspi.h
create mode 100644 hw/ssi/flexspi.c
diff --git a/include/hw/arm/svd/flexspi.h b/include/hw/arm/svd/flexspi.h
new file mode 100644
index 0000000000..828e2d6a7d
--- /dev/null
+++ b/include/hw/arm/svd/flexspi.h
@@ -0,0 +1,2656 @@
+/*
+ * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
+ */
+#pragma once
+
+#include "hw/register.h"
+
+/* FlexSPI */
+#define FLEXSPI_REGS_NO (267)
+
+/* Module Control Register 0 */
+REG32(FLEXSPI_MCR0, 0);
+/* Software Reset */
+FIELD(FLEXSPI_MCR0, SWRESET, 0, 1);
+/* Module Disable */
+FIELD(FLEXSPI_MCR0, MDIS, 1, 1);
+/* Sample Clock source selection for Flash Reading */
+FIELD(FLEXSPI_MCR0, RXCLKSRC, 4, 2);
+/* Serial root clock */
+FIELD(FLEXSPI_MCR0, SERCLKDIV, 8, 3);
+/* Half Speed Serial Flash Access Enable. */
+FIELD(FLEXSPI_MCR0, HSEN, 11, 1);
+/* Doze mode enable bit */
+FIELD(FLEXSPI_MCR0, DOZEEN, 12, 1);
+/*
+ * This bit is used to enable SCLK output free-running. For FPGA applications,
+ * the external device may use SCLK as reference clock to its internal PLL.
+ */
+FIELD(FLEXSPI_MCR0, SCKFREERUNEN, 14, 1);
+/* This bit is used to enable/disable the data learning feature. */
+FIELD(FLEXSPI_MCR0, LEARNEN, 15, 1);
+/* Timeout wait cycle for IP command grant. */
+FIELD(FLEXSPI_MCR0, IPGRANTWAIT, 16, 8);
+/* Timeout wait cycle for AHB command grant. */
+FIELD(FLEXSPI_MCR0, AHBGRANTWAIT, 24, 8);
+
+/* Module Control Register 1 */
+REG32(FLEXSPI_MCR1, 4);
+/* AHB Bus wait */
+FIELD(FLEXSPI_MCR1, AHBBUSWAIT, 0, 16);
+/*
+ * Command Sequence Execution will timeout and abort after SEQWAIT * 1024
+ * Serial Root Clock cycles. When sequence execution timeout occurs, there will
+ * be an interrupt generated (INTR[SEQTIMEOUT]) if this interrupt is enabled
+ * (INTEN[SEQTIMEOUTEN] is set 0x1) and AHB command is ignored by arbitrator.
+ */
+FIELD(FLEXSPI_MCR1, SEQWAIT, 16, 16);
+
+/* Module Control Register 2 */
+REG32(FLEXSPI_MCR2, 8);
+/* Clear AHB buffer */
+FIELD(FLEXSPI_MCR2, CLRAHBBUFOPT, 11, 1);
+/*
+ * The sampling clock phase selection will be reset to phase 0 when this bit is
+ * written with 0x1. This bit will be auto-cleared immediately.
+ */
+FIELD(FLEXSPI_MCR2, CLRLEARNPHASE, 14, 1);
+/*
+ * All external devices are same devices (both in type and size) for
+ * A1/A2/B1/B2.
+ */
+FIELD(FLEXSPI_MCR2, SAMEDEVICEEN, 15, 1);
+/*
+ * Wait cycle (in AHB clock cycle) for idle state before suspended command
+ * sequence resumed.
+ */
+FIELD(FLEXSPI_MCR2, RESUMEWAIT, 24, 8);
+
+/* AHB Bus Control Register */
+REG32(FLEXSPI_AHBCR, 12);
+/* Parallel mode enabled for AHB triggered Command (both read and write). */
+FIELD(FLEXSPI_AHBCR, APAREN, 0, 1);
+/* Clear the status/pointers of AHB TX Buffer. Auto-cleared. */
+FIELD(FLEXSPI_AHBCR, CLRAHBTXBUF, 2, 1);
+/* Enable AHB bus cachable read access support. */
+FIELD(FLEXSPI_AHBCR, CACHABLEEN, 3, 1);
+/* Enable AHB bus bufferable write access support. */
+FIELD(FLEXSPI_AHBCR, BUFFERABLEEN, 4, 1);
+/* AHB Read Prefetch Enable. */
+FIELD(FLEXSPI_AHBCR, PREFETCHEN, 5, 1);
+/*
+ * AHB Read Address option bit. This option bit is intended to remove AHB burst
+ * start address alignment limitation.
+ */
+FIELD(FLEXSPI_AHBCR, READADDROPT, 6, 1);
+/* AHB Read Resume Disable */
+FIELD(FLEXSPI_AHBCR, RESUMEDISABLE, 7, 1);
+/* AHB Read Size Alignment */
+FIELD(FLEXSPI_AHBCR, READSZALIGN, 10, 1);
+
+/* Interrupt Enable Register */
+REG32(FLEXSPI_INTEN, 16);
+/* IP triggered Command Sequences Execution finished interrupt enable. */
+FIELD(FLEXSPI_INTEN, IPCMDDONEEN, 0, 1);
+/* IP triggered Command Sequences Grant Timeout interrupt enable. */
+FIELD(FLEXSPI_INTEN, IPCMDGEEN, 1, 1);
+/* AHB triggered Command Sequences Grant Timeout interrupt enable. */
+FIELD(FLEXSPI_INTEN, AHBCMDGEEN, 2, 1);
+/* IP triggered Command Sequences Error Detected interrupt enable. */
+FIELD(FLEXSPI_INTEN, IPCMDERREN, 3, 1);
+/* AHB triggered Command Sequences Error Detected interrupt enable. */
+FIELD(FLEXSPI_INTEN, AHBCMDERREN, 4, 1);
+/* IP RX FIFO WaterMark available interrupt enable. */
+FIELD(FLEXSPI_INTEN, IPRXWAEN, 5, 1);
+/* IP TX FIFO WaterMark empty interrupt enable. */
+FIELD(FLEXSPI_INTEN, IPTXWEEN, 6, 1);
+/* Data Learning failed interrupt enable. */
+FIELD(FLEXSPI_INTEN, DATALEARNFAILEN, 7, 1);
+/*
+ * SCLK is stopped during command sequence because Async RX FIFO full interrupt
+ * enable.
+ */
+FIELD(FLEXSPI_INTEN, SCKSTOPBYRDEN, 8, 1);
+/*
+ * SCLK is stopped during command sequence because Async TX FIFO empty
+ * interrupt enable.
+ */
+FIELD(FLEXSPI_INTEN, SCKSTOPBYWREN, 9, 1);
+/* AHB Bus error interrupt enable. */
+FIELD(FLEXSPI_INTEN, AHBBUSERROREN, 10, 1);
+/* Sequence execution timeout interrupt enable. */
+FIELD(FLEXSPI_INTEN, SEQTIMEOUTEN, 11, 1);
+/* OTFAD key blob processing done interrupt enable. */
+FIELD(FLEXSPI_INTEN, KEYDONEEN, 12, 1);
+/* OTFAD key blob processing error interrupt enable. */
+FIELD(FLEXSPI_INTEN, KEYERROREN, 13, 1);
+
+/* Interrupt Register */
+REG32(FLEXSPI_INTR, 20);
+/*
+ * IP triggered Command Sequences Execution finished interrupt. This interrupt
+ * is also generated when there is IPCMDGE or IPCMDERR interrupt generated.
+ */
+FIELD(FLEXSPI_INTR, IPCMDDONE, 0, 1);
+/* IP triggered Command Sequences Grant Timeout interrupt. */
+FIELD(FLEXSPI_INTR, IPCMDGE, 1, 1);
+/* AHB triggered Command Sequences Grant Timeout interrupt. */
+FIELD(FLEXSPI_INTR, AHBCMDGE, 2, 1);
+/*
+ * IP triggered Command Sequences Error Detected interrupt. When an error
+ * detected for IP command, this command will be ignored and not executed at
+ * all.
+ */
+FIELD(FLEXSPI_INTR, IPCMDERR, 3, 1);
+/*
+ * AHB triggered Command Sequences Error Detected interrupt. When an error
+ * detected for AHB command, this command will be ignored and not executed at
+ * all.
+ */
+FIELD(FLEXSPI_INTR, AHBCMDERR, 4, 1);
+/* IP RX FIFO watermark available interrupt. */
+FIELD(FLEXSPI_INTR, IPRXWA, 5, 1);
+/* IP TX FIFO watermark empty interrupt. */
+FIELD(FLEXSPI_INTR, IPTXWE, 6, 1);
+/* Data Learning failed interrupt. */
+FIELD(FLEXSPI_INTR, DATALEARNFAIL, 7, 1);
+/*
+ * SCLK is stopped during command sequence because Async RX FIFO full
+ * interrupt.
+ */
+FIELD(FLEXSPI_INTR, SCKSTOPBYRD, 8, 1);
+/*
+ * SCLK is stopped during command sequence because Async TX FIFO empty
+ * interrupt.
+ */
+FIELD(FLEXSPI_INTR, SCKSTOPBYWR, 9, 1);
+/*
+ * AHB Bus timeout or AHB bus illegal access Flash during OTFAD key blob
+ * processing interrupt.
+ */
+FIELD(FLEXSPI_INTR, AHBBUSERROR, 10, 1);
+/* Sequence execution timeout interrupt. */
+FIELD(FLEXSPI_INTR, SEQTIMEOUT, 11, 1);
+/* OTFAD key blob processing done interrupt. */
+FIELD(FLEXSPI_INTR, KEYDONE, 12, 1);
+/* OTFAD key blob processing error interrupt. */
+FIELD(FLEXSPI_INTR, KEYERROR, 13, 1);
+
+/* LUT Key Register */
+REG32(FLEXSPI_LUTKEY, 24);
+/* The Key to lock or unlock LUT. */
+FIELD(FLEXSPI_LUTKEY, KEY, 0, 32);
+
+/* LUT Control Register */
+REG32(FLEXSPI_LUTCR, 28);
+/* Lock LUT */
+FIELD(FLEXSPI_LUTCR, LOCK, 0, 1);
+/* Unlock LUT */
+FIELD(FLEXSPI_LUTCR, UNLOCK, 1, 1);
+
+/* AHB RX Buffer 0 Control Register 0 */
+REG32(FLEXSPI_AHBRXBUF0CR0, 32);
+/* AHB RX Buffer Size in 64 bits. */
+FIELD(FLEXSPI_AHBRXBUF0CR0, BUFSZ, 0, 8);
+/* This AHB RX Buffer is assigned according to AHB Master with ID (MSTR_ID). */
+FIELD(FLEXSPI_AHBRXBUF0CR0, MSTRID, 16, 4);
+/*
+ * This priority for AHB Master Read which this AHB RX Buffer is assigned. 7 is
+ * the highest priority, 0 the lowest.
+ */
+FIELD(FLEXSPI_AHBRXBUF0CR0, PRIORITY, 24, 3);
+/* AHB Read Prefetch Enable for current AHB RX Buffer corresponding Master. */
+FIELD(FLEXSPI_AHBRXBUF0CR0, PREFETCHEN, 31, 1);
+
+/* AHB RX Buffer 1 Control Register 0 */
+REG32(FLEXSPI_AHBRXBUF1CR0, 36);
+/* AHB RX Buffer Size in 64 bits. */
+FIELD(FLEXSPI_AHBRXBUF1CR0, BUFSZ, 0, 8);
+/* This AHB RX Buffer is assigned according to AHB Master with ID (MSTR_ID). */
+FIELD(FLEXSPI_AHBRXBUF1CR0, MSTRID, 16, 4);
+/*
+ * This priority for AHB Master Read which this AHB RX Buffer is assigned. 7 is
+ * the highest priority, 0 the lowest.
+ */
+FIELD(FLEXSPI_AHBRXBUF1CR0, PRIORITY, 24, 3);
+/* AHB Read Prefetch Enable for current AHB RX Buffer corresponding Master. */
+FIELD(FLEXSPI_AHBRXBUF1CR0, PREFETCHEN, 31, 1);
+
+/* AHB RX Buffer 2 Control Register 0 */
+REG32(FLEXSPI_AHBRXBUF2CR0, 40);
+/* AHB RX Buffer Size in 64 bits. */
+FIELD(FLEXSPI_AHBRXBUF2CR0, BUFSZ, 0, 8);
+/* This AHB RX Buffer is assigned according to AHB Master with ID (MSTR_ID). */
+FIELD(FLEXSPI_AHBRXBUF2CR0, MSTRID, 16, 4);
+/*
+ * This priority for AHB Master Read which this AHB RX Buffer is assigned. 7 is
+ * the highest priority, 0 the lowest.
+ */
+FIELD(FLEXSPI_AHBRXBUF2CR0, PRIORITY, 24, 3);
+/* AHB Read Prefetch Enable for current AHB RX Buffer corresponding Master. */
+FIELD(FLEXSPI_AHBRXBUF2CR0, PREFETCHEN, 31, 1);
+
+/* AHB RX Buffer 3 Control Register 0 */
+REG32(FLEXSPI_AHBRXBUF3CR0, 44);
+/* AHB RX Buffer Size in 64 bits. */
+FIELD(FLEXSPI_AHBRXBUF3CR0, BUFSZ, 0, 8);
+/* This AHB RX Buffer is assigned according to AHB Master with ID (MSTR_ID). */
+FIELD(FLEXSPI_AHBRXBUF3CR0, MSTRID, 16, 4);
+/*
+ * This priority for AHB Master Read which this AHB RX Buffer is assigned. 7 is
+ * the highest priority, 0 the lowest.
+ */
+FIELD(FLEXSPI_AHBRXBUF3CR0, PRIORITY, 24, 3);
+/* AHB Read Prefetch Enable for current AHB RX Buffer corresponding Master. */
+FIELD(FLEXSPI_AHBRXBUF3CR0, PREFETCHEN, 31, 1);
+
+/* AHB RX Buffer 4 Control Register 0 */
+REG32(FLEXSPI_AHBRXBUF4CR0, 48);
+/* AHB RX Buffer Size in 64 bits. */
+FIELD(FLEXSPI_AHBRXBUF4CR0, BUFSZ, 0, 8);
+/* This AHB RX Buffer is assigned according to AHB Master with ID (MSTR_ID). */
+FIELD(FLEXSPI_AHBRXBUF4CR0, MSTRID, 16, 4);
+/*
+ * This priority for AHB Master Read which this AHB RX Buffer is assigned. 7 is
+ * the highest priority, 0 the lowest.
+ */
+FIELD(FLEXSPI_AHBRXBUF4CR0, PRIORITY, 24, 3);
+/* AHB Read Prefetch Enable for current AHB RX Buffer corresponding Master. */
+FIELD(FLEXSPI_AHBRXBUF4CR0, PREFETCHEN, 31, 1);
+
+/* AHB RX Buffer 5 Control Register 0 */
+REG32(FLEXSPI_AHBRXBUF5CR0, 52);
+/* AHB RX Buffer Size in 64 bits. */
+FIELD(FLEXSPI_AHBRXBUF5CR0, BUFSZ, 0, 8);
+/* This AHB RX Buffer is assigned according to AHB Master with ID (MSTR_ID). */
+FIELD(FLEXSPI_AHBRXBUF5CR0, MSTRID, 16, 4);
+/*
+ * This priority for AHB Master Read which this AHB RX Buffer is assigned. 7 is
+ * the highest priority, 0 the lowest.
+ */
+FIELD(FLEXSPI_AHBRXBUF5CR0, PRIORITY, 24, 3);
+/* AHB Read Prefetch Enable for current AHB RX Buffer corresponding Master. */
+FIELD(FLEXSPI_AHBRXBUF5CR0, PREFETCHEN, 31, 1);
+
+/* AHB RX Buffer 6 Control Register 0 */
+REG32(FLEXSPI_AHBRXBUF6CR0, 56);
+/* AHB RX Buffer Size in 64 bits. */
+FIELD(FLEXSPI_AHBRXBUF6CR0, BUFSZ, 0, 8);
+/* This AHB RX Buffer is assigned according to AHB Master with ID (MSTR_ID). */
+FIELD(FLEXSPI_AHBRXBUF6CR0, MSTRID, 16, 4);
+/*
+ * This priority for AHB Master Read which this AHB RX Buffer is assigned. 7 is
+ * the highest priority, 0 the lowest.
+ */
+FIELD(FLEXSPI_AHBRXBUF6CR0, PRIORITY, 24, 3);
+/* AHB Read Prefetch Enable for current AHB RX Buffer corresponding Master. */
+FIELD(FLEXSPI_AHBRXBUF6CR0, PREFETCHEN, 31, 1);
+
+/* AHB RX Buffer 7 Control Register 0 */
+REG32(FLEXSPI_AHBRXBUF7CR0, 60);
+/* AHB RX Buffer Size in 64 bits. */
+FIELD(FLEXSPI_AHBRXBUF7CR0, BUFSZ, 0, 8);
+/* This AHB RX Buffer is assigned according to AHB Master with ID (MSTR_ID). */
+FIELD(FLEXSPI_AHBRXBUF7CR0, MSTRID, 16, 4);
+/*
+ * This priority for AHB Master Read which this AHB RX Buffer is assigned. 7 is
+ * the highest priority, 0 the lowest.
+ */
+FIELD(FLEXSPI_AHBRXBUF7CR0, PRIORITY, 24, 3);
+/* AHB Read Prefetch Enable for current AHB RX Buffer corresponding Master. */
+FIELD(FLEXSPI_AHBRXBUF7CR0, PREFETCHEN, 31, 1);
+
+/* Flash Control Register 0 */
+REG32(FLEXSPI_FLSHA1CR0, 96);
+/* Flash Size in KByte. */
+FIELD(FLEXSPI_FLSHA1CR0, FLSHSZ, 0, 23);
+
+/* Flash Control Register 0 */
+REG32(FLEXSPI_FLSHA2CR0, 100);
+/* Flash Size in KByte. */
+FIELD(FLEXSPI_FLSHA2CR0, FLSHSZ, 0, 23);
+
+/* Flash Control Register 0 */
+REG32(FLEXSPI_FLSHB1CR0, 104);
+/* Flash Size in KByte. */
+FIELD(FLEXSPI_FLSHB1CR0, FLSHSZ, 0, 23);
+
+/* Flash Control Register 0 */
+REG32(FLEXSPI_FLSHB2CR0, 108);
+/* Flash Size in KByte. */
+FIELD(FLEXSPI_FLSHB2CR0, FLSHSZ, 0, 23);
+
+/* Flash Control Register 1 */
+REG32(FLEXSPI_FLSHCR1A1, 112);
+/* Serial Flash CS setup time. */
+FIELD(FLEXSPI_FLSHCR1A1, TCSS, 0, 5);
+/* Serial Flash CS Hold time. */
+FIELD(FLEXSPI_FLSHCR1A1, TCSH, 5, 5);
+/* Word Addressable. */
+FIELD(FLEXSPI_FLSHCR1A1, WA, 10, 1);
+/* Column Address Size. */
+FIELD(FLEXSPI_FLSHCR1A1, CAS, 11, 4);
+/* CS interval unit */
+FIELD(FLEXSPI_FLSHCR1A1, CSINTERVALUNIT, 15, 1);
+/*
+ * This field is used to set the minimum interval between flash device chip
+ * select deassertion and flash device chip select assertion. If external flash
+ * has a limitation on the interval between command sequences, this field
+ * should be set accordingly. If there is no limitation, set this field with
+ * value 0x0.
+ */
+FIELD(FLEXSPI_FLSHCR1A1, CSINTERVAL, 16, 16);
+
+/* Flash Control Register 1 */
+REG32(FLEXSPI_FLSHCR1A2, 116);
+/* Serial Flash CS setup time. */
+FIELD(FLEXSPI_FLSHCR1A2, TCSS, 0, 5);
+/* Serial Flash CS Hold time. */
+FIELD(FLEXSPI_FLSHCR1A2, TCSH, 5, 5);
+/* Word Addressable. */
+FIELD(FLEXSPI_FLSHCR1A2, WA, 10, 1);
+/* Column Address Size. */
+FIELD(FLEXSPI_FLSHCR1A2, CAS, 11, 4);
+/* CS interval unit */
+FIELD(FLEXSPI_FLSHCR1A2, CSINTERVALUNIT, 15, 1);
+/*
+ * This field is used to set the minimum interval between flash device chip
+ * select deassertion and flash device chip select assertion. If external flash
+ * has a limitation on the interval between command sequences, this field
+ * should be set accordingly. If there is no limitation, set this field with
+ * value 0x0.
+ */
+FIELD(FLEXSPI_FLSHCR1A2, CSINTERVAL, 16, 16);
+
+/* Flash Control Register 1 */
+REG32(FLEXSPI_FLSHCR1B1, 120);
+/* Serial Flash CS setup time. */
+FIELD(FLEXSPI_FLSHCR1B1, TCSS, 0, 5);
+/* Serial Flash CS Hold time. */
+FIELD(FLEXSPI_FLSHCR1B1, TCSH, 5, 5);
+/* Word Addressable. */
+FIELD(FLEXSPI_FLSHCR1B1, WA, 10, 1);
+/* Column Address Size. */
+FIELD(FLEXSPI_FLSHCR1B1, CAS, 11, 4);
+/* CS interval unit */
+FIELD(FLEXSPI_FLSHCR1B1, CSINTERVALUNIT, 15, 1);
+/*
+ * This field is used to set the minimum interval between flash device chip
+ * select deassertion and flash device chip select assertion. If external flash
+ * has a limitation on the interval between command sequences, this field
+ * should be set accordingly. If there is no limitation, set this field with
+ * value 0x0.
+ */
+FIELD(FLEXSPI_FLSHCR1B1, CSINTERVAL, 16, 16);
+
+/* Flash Control Register 1 */
+REG32(FLEXSPI_FLSHCR1B2, 124);
+/* Serial Flash CS setup time. */
+FIELD(FLEXSPI_FLSHCR1B2, TCSS, 0, 5);
+/* Serial Flash CS Hold time. */
+FIELD(FLEXSPI_FLSHCR1B2, TCSH, 5, 5);
+/* Word Addressable. */
+FIELD(FLEXSPI_FLSHCR1B2, WA, 10, 1);
+/* Column Address Size. */
+FIELD(FLEXSPI_FLSHCR1B2, CAS, 11, 4);
+/* CS interval unit */
+FIELD(FLEXSPI_FLSHCR1B2, CSINTERVALUNIT, 15, 1);
+/*
+ * This field is used to set the minimum interval between flash device chip
+ * select deassertion and flash device chip select assertion. If external flash
+ * has a limitation on the interval between command sequences, this field
+ * should be set accordingly. If there is no limitation, set this field with
+ * value 0x0.
+ */
+FIELD(FLEXSPI_FLSHCR1B2, CSINTERVAL, 16, 16);
+
+/* Flash Control Register 2 */
+REG32(FLEXSPI_FLSHCR2A1, 128);
+/* Sequence Index for AHB Read triggered Command in LUT. */
+FIELD(FLEXSPI_FLSHCR2A1, ARDSEQID, 0, 4);
+/* Sequence Number for AHB Read triggered Command in LUT. */
+FIELD(FLEXSPI_FLSHCR2A1, ARDSEQNUM, 5, 3);
+/* Sequence Index for AHB Write triggered Command. */
+FIELD(FLEXSPI_FLSHCR2A1, AWRSEQID, 8, 4);
+/* Sequence Number for AHB Write triggered Command. */
+FIELD(FLEXSPI_FLSHCR2A1, AWRSEQNUM, 13, 3);
+/*
+ * For certain devices (such as FPGA), it need some time to write data into
+ * internal memory after the command sequences finished on FlexSPI interface.
+ * If another Read command sequence comes before previous programming finished
+ * internally, the read data may be wrong. This field is used to hold AHB Bus
+ * ready for AHB write access to wait the programming finished in external
+ * device. Then there will be no AHB read command triggered before the
+ * programming finished in external device. The Wait cycle between AHB
+ * triggered command sequences finished on FlexSPI interface and AHB return Bus
+ * ready: AWRWAIT * AWRWAITUNIT
+ */
+FIELD(FLEXSPI_FLSHCR2A1, AWRWAIT, 16, 12);
+/* AWRWAIT unit */
+FIELD(FLEXSPI_FLSHCR2A1, AWRWAITUNIT, 28, 3);
+/*
+ * Clear the instruction pointer which is internally saved pointer by
+ * JMP_ON_CS.
+ */
+FIELD(FLEXSPI_FLSHCR2A1, CLRINSTRPTR, 31, 1);
+
+/* Flash Control Register 2 */
+REG32(FLEXSPI_FLSHCR2A2, 132);
+/* Sequence Index for AHB Read triggered Command in LUT. */
+FIELD(FLEXSPI_FLSHCR2A2, ARDSEQID, 0, 4);
+/* Sequence Number for AHB Read triggered Command in LUT. */
+FIELD(FLEXSPI_FLSHCR2A2, ARDSEQNUM, 5, 3);
+/* Sequence Index for AHB Write triggered Command. */
+FIELD(FLEXSPI_FLSHCR2A2, AWRSEQID, 8, 4);
+/* Sequence Number for AHB Write triggered Command. */
+FIELD(FLEXSPI_FLSHCR2A2, AWRSEQNUM, 13, 3);
+/*
+ * For certain devices (such as FPGA), it need some time to write data into
+ * internal memory after the command sequences finished on FlexSPI interface.
+ * If another Read command sequence comes before previous programming finished
+ * internally, the read data may be wrong. This field is used to hold AHB Bus
+ * ready for AHB write access to wait the programming finished in external
+ * device. Then there will be no AHB read command triggered before the
+ * programming finished in external device. The Wait cycle between AHB
+ * triggered command sequences finished on FlexSPI interface and AHB return Bus
+ * ready: AWRWAIT * AWRWAITUNIT
+ */
+FIELD(FLEXSPI_FLSHCR2A2, AWRWAIT, 16, 12);
+/* AWRWAIT unit */
+FIELD(FLEXSPI_FLSHCR2A2, AWRWAITUNIT, 28, 3);
+/*
+ * Clear the instruction pointer which is internally saved pointer by
+ * JMP_ON_CS.
+ */
+FIELD(FLEXSPI_FLSHCR2A2, CLRINSTRPTR, 31, 1);
+
+/* Flash Control Register 2 */
+REG32(FLEXSPI_FLSHCR2B1, 136);
+/* Sequence Index for AHB Read triggered Command in LUT. */
+FIELD(FLEXSPI_FLSHCR2B1, ARDSEQID, 0, 4);
+/* Sequence Number for AHB Read triggered Command in LUT. */
+FIELD(FLEXSPI_FLSHCR2B1, ARDSEQNUM, 5, 3);
+/* Sequence Index for AHB Write triggered Command. */
+FIELD(FLEXSPI_FLSHCR2B1, AWRSEQID, 8, 4);
+/* Sequence Number for AHB Write triggered Command. */
+FIELD(FLEXSPI_FLSHCR2B1, AWRSEQNUM, 13, 3);
+/*
+ * For certain devices (such as FPGA), it need some time to write data into
+ * internal memory after the command sequences finished on FlexSPI interface.
+ * If another Read command sequence comes before previous programming finished
+ * internally, the read data may be wrong. This field is used to hold AHB Bus
+ * ready for AHB write access to wait the programming finished in external
+ * device. Then there will be no AHB read command triggered before the
+ * programming finished in external device. The Wait cycle between AHB
+ * triggered command sequences finished on FlexSPI interface and AHB return Bus
+ * ready: AWRWAIT * AWRWAITUNIT
+ */
+FIELD(FLEXSPI_FLSHCR2B1, AWRWAIT, 16, 12);
+/* AWRWAIT unit */
+FIELD(FLEXSPI_FLSHCR2B1, AWRWAITUNIT, 28, 3);
+/*
+ * Clear the instruction pointer which is internally saved pointer by
+ * JMP_ON_CS.
+ */
+FIELD(FLEXSPI_FLSHCR2B1, CLRINSTRPTR, 31, 1);
+
+/* Flash Control Register 2 */
+REG32(FLEXSPI_FLSHCR2B2, 140);
+/* Sequence Index for AHB Read triggered Command in LUT. */
+FIELD(FLEXSPI_FLSHCR2B2, ARDSEQID, 0, 4);
+/* Sequence Number for AHB Read triggered Command in LUT. */
+FIELD(FLEXSPI_FLSHCR2B2, ARDSEQNUM, 5, 3);
+/* Sequence Index for AHB Write triggered Command. */
+FIELD(FLEXSPI_FLSHCR2B2, AWRSEQID, 8, 4);
+/* Sequence Number for AHB Write triggered Command. */
+FIELD(FLEXSPI_FLSHCR2B2, AWRSEQNUM, 13, 3);
+/*
+ * For certain devices (such as FPGA), it need some time to write data into
+ * internal memory after the command sequences finished on FlexSPI interface.
+ * If another Read command sequence comes before previous programming finished
+ * internally, the read data may be wrong. This field is used to hold AHB Bus
+ * ready for AHB write access to wait the programming finished in external
+ * device. Then there will be no AHB read command triggered before the
+ * programming finished in external device. The Wait cycle between AHB
+ * triggered command sequences finished on FlexSPI interface and AHB return Bus
+ * ready: AWRWAIT * AWRWAITUNIT
+ */
+FIELD(FLEXSPI_FLSHCR2B2, AWRWAIT, 16, 12);
+/* AWRWAIT unit */
+FIELD(FLEXSPI_FLSHCR2B2, AWRWAITUNIT, 28, 3);
+/*
+ * Clear the instruction pointer which is internally saved pointer by
+ * JMP_ON_CS.
+ */
+FIELD(FLEXSPI_FLSHCR2B2, CLRINSTRPTR, 31, 1);
+
+/* Flash Control Register 4 */
+REG32(FLEXSPI_FLSHCR4, 148);
+/*
+ * Write mask option bit 1. This option bit could be used to remove AHB and IP
+ * write burst start address alignment limitation.
+ */
+FIELD(FLEXSPI_FLSHCR4, WMOPT1, 0, 1);
+/*
+ * Write mask enable bit for flash device on port A. When write mask function
+ * is needed for memory device on port A, this bit must be set.
+ */
+FIELD(FLEXSPI_FLSHCR4, WMENA, 2, 1);
+
+/* IP Control Register 0 */
+REG32(FLEXSPI_IPCR0, 160);
+/* Serial Flash Address for IP command. */
+FIELD(FLEXSPI_IPCR0, SFAR, 0, 32);
+
+/* IP Control Register 1 */
+REG32(FLEXSPI_IPCR1, 164);
+/* Flash Read/Program Data Size (in Bytes) for IP command. */
+FIELD(FLEXSPI_IPCR1, IDATSZ, 0, 16);
+/* Sequence Index in LUT for IP command. */
+FIELD(FLEXSPI_IPCR1, ISEQID, 16, 4);
+/* Sequence Number for IP command: ISEQNUM+1. */
+FIELD(FLEXSPI_IPCR1, ISEQNUM, 24, 3);
+/* Parallel mode Enabled for IP command. */
+FIELD(FLEXSPI_IPCR1, IPAREN, 31, 1);
+
+/* IP Command Register */
+REG32(FLEXSPI_IPCMD, 176);
+/* Setting this bit will trigger an IP Command. */
+FIELD(FLEXSPI_IPCMD, TRG, 0, 1);
+
+/* Data Learn Pattern Register */
+REG32(FLEXSPI_DLPR, 180);
+/* Data Learning Pattern. */
+FIELD(FLEXSPI_DLPR, DLP, 0, 32);
+
+/* IP RX FIFO Control Register */
+REG32(FLEXSPI_IPRXFCR, 184);
+/* Clear all valid data entries in IP RX FIFO. */
+FIELD(FLEXSPI_IPRXFCR, CLRIPRXF, 0, 1);
+/* IP RX FIFO reading by DMA enabled. */
+FIELD(FLEXSPI_IPRXFCR, RXDMAEN, 1, 1);
+/* Watermark level is (RXWMRK+1)*64 bits. */
+FIELD(FLEXSPI_IPRXFCR, RXWMRK, 2, 7);
+
+/* IP TX FIFO Control Register */
+REG32(FLEXSPI_IPTXFCR, 188);
+/* Clear all valid data entries in IP TX FIFO. */
+FIELD(FLEXSPI_IPTXFCR, CLRIPTXF, 0, 1);
+/* IP TX FIFO filling by DMA enabled. */
+FIELD(FLEXSPI_IPTXFCR, TXDMAEN, 1, 1);
+/* Watermark level is (TXWMRK+1)*64 Bits. */
+FIELD(FLEXSPI_IPTXFCR, TXWMRK, 2, 7);
+
+/* DLL Control Register 0 */
+REG32(FLEXSPI_DLLCRA, 192);
+/* DLL calibration enable. */
+FIELD(FLEXSPI_DLLCRA, DLLEN, 0, 1);
+/* DLL reset */
+FIELD(FLEXSPI_DLLCRA, DLLRESET, 1, 1);
+/*
+ * The delay target for slave delay line is: ((SLVDLYTARGET+1) * 1/32 * clock
+ * cycle of reference clock (serial root clock). If serial root clock is >= 100
+ * MHz, DLLEN set to 0x1, OVRDEN set to =0x0, then SLVDLYTARGET setting of 0 is
+ * recommended.
+ */
+FIELD(FLEXSPI_DLLCRA, SLVDLYTARGET, 3, 4);
+/* Slave clock delay line delay cell number selection override enable. */
+FIELD(FLEXSPI_DLLCRA, OVRDEN, 8, 1);
+/* Slave clock delay line delay cell number selection override value. */
+FIELD(FLEXSPI_DLLCRA, OVRDVAL, 9, 6);
+
+/* DLL Control Register 0 */
+REG32(FLEXSPI_DLLCRB, 196);
+/* DLL calibration enable. */
+FIELD(FLEXSPI_DLLCRB, DLLEN, 0, 1);
+/* DLL reset */
+FIELD(FLEXSPI_DLLCRB, DLLRESET, 1, 1);
+/*
+ * The delay target for slave delay line is: ((SLVDLYTARGET+1) * 1/32 * clock
+ * cycle of reference clock (serial root clock). If serial root clock is >= 100
+ * MHz, DLLEN set to 0x1, OVRDEN set to =0x0, then SLVDLYTARGET setting of 0 is
+ * recommended.
+ */
+FIELD(FLEXSPI_DLLCRB, SLVDLYTARGET, 3, 4);
+/* Slave clock delay line delay cell number selection override enable. */
+FIELD(FLEXSPI_DLLCRB, OVRDEN, 8, 1);
+/* Slave clock delay line delay cell number selection override value. */
+FIELD(FLEXSPI_DLLCRB, OVRDVAL, 9, 6);
+
+/* Status Register 0 */
+REG32(FLEXSPI_STS0, 224);
+/*
+ * This status bit indicates the state machine in SEQ_CTL is idle and there is
+ * command sequence executing on FlexSPI interface.
+ */
+FIELD(FLEXSPI_STS0, SEQIDLE, 0, 1);
+/*
+ * This status bit indicates the state machine in ARB_CTL is busy and there is
+ * command sequence granted by arbitrator and not finished yet on FlexSPI
+ * interface. When ARB_CTL state (ARBIDLE=0x1) is idle, there will be no
+ * transaction on FlexSPI interface also (SEQIDLE=0x1). So this bit should be
+ * polled to wait for FlexSPI controller become idle instead of SEQIDLE.
+ */
+FIELD(FLEXSPI_STS0, ARBIDLE, 1, 1);
+/*
+ * This status field indicates the trigger source of current command sequence
+ * granted by arbitrator. This field value is meaningless when ARB_CTL is not
+ * busy (STS0[ARBIDLE]=0x1).
+ */
+FIELD(FLEXSPI_STS0, ARBCMDSRC, 2, 2);
+/* Indicate the sampling clock phase selection on Port A after Data Learning. */
+FIELD(FLEXSPI_STS0, DATALEARNPHASEA, 4, 4);
+
+/* Status Register 1 */
+REG32(FLEXSPI_STS1, 228);
+/*
+ * Indicates the sequence index when an AHB command error is detected. This
+ * field will be cleared when INTR[AHBCMDERR] is write-1-clear(w1c).
+ */
+FIELD(FLEXSPI_STS1, AHBCMDERRID, 0, 4);
+/*
+ * Indicates the Error Code when AHB command Error detected. This field will be
+ * cleared when INTR[AHBCMDERR] is write-1-clear(w1c).
+ */
+FIELD(FLEXSPI_STS1, AHBCMDERRCODE, 8, 4);
+/* Indicates the sequence Index when IP command error detected. */
+FIELD(FLEXSPI_STS1, IPCMDERRID, 16, 4);
+/*
+ * Indicates the Error Code when IP command Error detected. This field will be
+ * cleared when INTR[IPCMDERR] is write-1-clear(w1c).
+ */
+FIELD(FLEXSPI_STS1, IPCMDERRCODE, 24, 4);
+
+/* Status Register 2 */
+REG32(FLEXSPI_STS2, 232);
+/* Flash A sample clock slave delay line locked. */
+FIELD(FLEXSPI_STS2, ASLVLOCK, 0, 1);
+/* Flash A sample clock reference delay line locked. */
+FIELD(FLEXSPI_STS2, AREFLOCK, 1, 1);
+/* Flash A sample clock slave delay line delay cell number selection . */
+FIELD(FLEXSPI_STS2, ASLVSEL, 2, 6);
+/* Flash A sample clock reference delay line delay cell number selection. */
+FIELD(FLEXSPI_STS2, AREFSEL, 8, 6);
+/* Flash B sample clock slave delay line locked. */
+FIELD(FLEXSPI_STS2, BSLVLOCK, 16, 1);
+/* Flash B sample clock reference delay line locked. */
+FIELD(FLEXSPI_STS2, BREFLOCK, 17, 1);
+/* Flash B sample clock slave delay line delay cell number selection. */
+FIELD(FLEXSPI_STS2, BSLVSEL, 18, 6);
+/* Flash B sample clock reference delay line delay cell number selection. */
+FIELD(FLEXSPI_STS2, BREFSEL, 24, 6);
+
+/* AHB Suspend Status Register */
+REG32(FLEXSPI_AHBSPNDSTS, 236);
+/* Indicates if an AHB read prefetch command sequence has been suspended. */
+FIELD(FLEXSPI_AHBSPNDSTS, ACTIVE, 0, 1);
+/* AHB RX BUF ID for suspended command sequence. */
+FIELD(FLEXSPI_AHBSPNDSTS, BUFID, 1, 3);
+/* The Data size left for suspended command sequence (in byte). */
+FIELD(FLEXSPI_AHBSPNDSTS, DATLFT, 16, 16);
+
+/* IP RX FIFO Status Register */
+REG32(FLEXSPI_IPRXFSTS, 240);
+/* Fill level of IP RX FIFO. */
+FIELD(FLEXSPI_IPRXFSTS, FILL, 0, 8);
+/* Total Read Data Counter: RDCNTR * 64 Bits. */
+FIELD(FLEXSPI_IPRXFSTS, RDCNTR, 16, 16);
+
+/* IP TX FIFO Status Register */
+REG32(FLEXSPI_IPTXFSTS, 244);
+/* Fill level of IP TX FIFO. */
+FIELD(FLEXSPI_IPTXFSTS, FILL, 0, 8);
+/* Total Write Data Counter: WRCNTR * 64 Bits. */
+FIELD(FLEXSPI_IPTXFSTS, WRCNTR, 16, 16);
+
+/* IP RX FIFO Data Register x */
+REG32(FLEXSPI_RFDR0, 256);
+REG32(FLEXSPI_RFDR1, 260);
+REG32(FLEXSPI_RFDR2, 264);
+REG32(FLEXSPI_RFDR3, 268);
+REG32(FLEXSPI_RFDR4, 272);
+REG32(FLEXSPI_RFDR5, 276);
+REG32(FLEXSPI_RFDR6, 280);
+REG32(FLEXSPI_RFDR7, 284);
+REG32(FLEXSPI_RFDR8, 288);
+REG32(FLEXSPI_RFDR9, 292);
+REG32(FLEXSPI_RFDR10, 296);
+REG32(FLEXSPI_RFDR11, 300);
+REG32(FLEXSPI_RFDR12, 304);
+REG32(FLEXSPI_RFDR13, 308);
+REG32(FLEXSPI_RFDR14, 312);
+REG32(FLEXSPI_RFDR15, 316);
+REG32(FLEXSPI_RFDR16, 320);
+REG32(FLEXSPI_RFDR17, 324);
+REG32(FLEXSPI_RFDR18, 328);
+REG32(FLEXSPI_RFDR19, 332);
+REG32(FLEXSPI_RFDR20, 336);
+REG32(FLEXSPI_RFDR21, 340);
+REG32(FLEXSPI_RFDR22, 344);
+REG32(FLEXSPI_RFDR23, 348);
+REG32(FLEXSPI_RFDR24, 352);
+REG32(FLEXSPI_RFDR25, 356);
+REG32(FLEXSPI_RFDR26, 360);
+REG32(FLEXSPI_RFDR27, 364);
+REG32(FLEXSPI_RFDR28, 368);
+REG32(FLEXSPI_RFDR29, 372);
+REG32(FLEXSPI_RFDR30, 376);
+REG32(FLEXSPI_RFDR31, 380);
+/* RX Data. */
+SHARED_FIELD(FLEXSPI_RFDR_RXDATA, 0, 32);
+
+/* IP TX FIFO Data Register x */
+REG32(FLEXSPI_TFDR0, 384);
+REG32(FLEXSPI_TFDR1, 388);
+REG32(FLEXSPI_TFDR2, 392);
+REG32(FLEXSPI_TFDR3, 396);
+REG32(FLEXSPI_TFDR4, 400);
+REG32(FLEXSPI_TFDR5, 404);
+REG32(FLEXSPI_TFDR6, 408);
+REG32(FLEXSPI_TFDR7, 412);
+REG32(FLEXSPI_TFDR8, 416);
+REG32(FLEXSPI_TFDR9, 420);
+REG32(FLEXSPI_TFDR10, 424);
+REG32(FLEXSPI_TFDR11, 428);
+REG32(FLEXSPI_TFDR12, 432);
+REG32(FLEXSPI_TFDR13, 436);
+REG32(FLEXSPI_TFDR14, 440);
+REG32(FLEXSPI_TFDR15, 444);
+REG32(FLEXSPI_TFDR16, 448);
+REG32(FLEXSPI_TFDR17, 452);
+REG32(FLEXSPI_TFDR18, 456);
+REG32(FLEXSPI_TFDR19, 460);
+REG32(FLEXSPI_TFDR20, 464);
+REG32(FLEXSPI_TFDR21, 468);
+REG32(FLEXSPI_TFDR22, 472);
+REG32(FLEXSPI_TFDR23, 476);
+REG32(FLEXSPI_TFDR24, 480);
+REG32(FLEXSPI_TFDR25, 484);
+REG32(FLEXSPI_TFDR26, 488);
+REG32(FLEXSPI_TFDR27, 492);
+REG32(FLEXSPI_TFDR28, 496);
+REG32(FLEXSPI_TFDR29, 500);
+REG32(FLEXSPI_TFDR30, 504);
+REG32(FLEXSPI_TFDR31, 508);
+/* TX Data */
+SHARED_FIELD(FLEXSPI_TFDR_TXDATA, 0, 32);
+
+/* LUT x */
+REG32(FLEXSPI_LUT0, 512);
+REG32(FLEXSPI_LUT1, 516);
+REG32(FLEXSPI_LUT2, 520);
+REG32(FLEXSPI_LUT3, 524);
+REG32(FLEXSPI_LUT4, 528);
+REG32(FLEXSPI_LUT5, 532);
+REG32(FLEXSPI_LUT6, 536);
+REG32(FLEXSPI_LUT7, 540);
+REG32(FLEXSPI_LUT8, 544);
+REG32(FLEXSPI_LUT9, 548);
+REG32(FLEXSPI_LUT10, 552);
+REG32(FLEXSPI_LUT11, 556);
+REG32(FLEXSPI_LUT12, 560);
+REG32(FLEXSPI_LUT13, 564);
+REG32(FLEXSPI_LUT14, 568);
+REG32(FLEXSPI_LUT15, 572);
+REG32(FLEXSPI_LUT16, 576);
+REG32(FLEXSPI_LUT17, 580);
+REG32(FLEXSPI_LUT18, 584);
+REG32(FLEXSPI_LUT19, 588);
+REG32(FLEXSPI_LUT20, 592);
+REG32(FLEXSPI_LUT21, 596);
+REG32(FLEXSPI_LUT22, 600);
+REG32(FLEXSPI_LUT23, 604);
+REG32(FLEXSPI_LUT24, 608);
+REG32(FLEXSPI_LUT25, 612);
+REG32(FLEXSPI_LUT26, 616);
+REG32(FLEXSPI_LUT27, 620);
+REG32(FLEXSPI_LUT28, 624);
+REG32(FLEXSPI_LUT29, 628);
+REG32(FLEXSPI_LUT30, 632);
+REG32(FLEXSPI_LUT31, 636);
+REG32(FLEXSPI_LUT32, 640);
+REG32(FLEXSPI_LUT33, 644);
+REG32(FLEXSPI_LUT34, 648);
+REG32(FLEXSPI_LUT35, 652);
+REG32(FLEXSPI_LUT36, 656);
+REG32(FLEXSPI_LUT37, 660);
+REG32(FLEXSPI_LUT38, 664);
+REG32(FLEXSPI_LUT39, 668);
+REG32(FLEXSPI_LUT40, 672);
+REG32(FLEXSPI_LUT41, 676);
+REG32(FLEXSPI_LUT42, 680);
+REG32(FLEXSPI_LUT43, 684);
+REG32(FLEXSPI_LUT44, 688);
+REG32(FLEXSPI_LUT45, 692);
+REG32(FLEXSPI_LUT46, 696);
+REG32(FLEXSPI_LUT47, 700);
+REG32(FLEXSPI_LUT48, 704);
+REG32(FLEXSPI_LUT49, 708);
+REG32(FLEXSPI_LUT50, 712);
+REG32(FLEXSPI_LUT51, 716);
+REG32(FLEXSPI_LUT52, 720);
+REG32(FLEXSPI_LUT53, 724);
+REG32(FLEXSPI_LUT54, 728);
+REG32(FLEXSPI_LUT55, 732);
+REG32(FLEXSPI_LUT56, 736);
+REG32(FLEXSPI_LUT57, 740);
+REG32(FLEXSPI_LUT58, 744);
+REG32(FLEXSPI_LUT59, 748);
+REG32(FLEXSPI_LUT60, 752);
+REG32(FLEXSPI_LUT61, 756);
+REG32(FLEXSPI_LUT62, 760);
+REG32(FLEXSPI_LUT63, 764);
+/* OPERAND0 */
+SHARED_FIELD(FLEXSPI_LUT_OPERAND0, 0, 8);
+/* NUM_PADS0 */
+SHARED_FIELD(FLEXSPI_LUT_NUM_PADS0, 8, 2);
+/* OPCODE */
+SHARED_FIELD(FLEXSPI_LUT_OPCODE0, 10, 6);
+/* OPERAND1 */
+SHARED_FIELD(FLEXSPI_LUT_OPERAND1, 16, 8);
+/* NUM_PADS1 */
+SHARED_FIELD(FLEXSPI_LUT_NUM_PADS1, 24, 2);
+/* OPCODE1 */
+SHARED_FIELD(FLEXSPI_LUT_OPCODE1, 26, 6);
+
+/* HADDR REMAP START ADDR */
+REG32(FLEXSPI_HADDRSTART, 1056);
+/* AHB Bus address remap function enable */
+FIELD(FLEXSPI_HADDRSTART, REMAPEN, 0, 1);
+/* HADDR start address */
+FIELD(FLEXSPI_HADDRSTART, ADDRSTART, 12, 20);
+
+/* HADDR REMAP END ADDR */
+REG32(FLEXSPI_HADDREND, 1060);
+/* HADDR remap range's end address, 4K aligned */
+FIELD(FLEXSPI_HADDREND, ENDSTART, 12, 20);
+
+/* HADDR REMAP OFFSET */
+REG32(FLEXSPI_HADDROFFSET, 1064);
+/*
+ * HADDR offset field, remapped address will be
+ * ADDR[31:12]=ADDR_original[31:12]+ADDROFFSET
+ */
+FIELD(FLEXSPI_HADDROFFSET, ADDROFFSET, 12, 20);
+
+
+typedef enum {
+ /* No impact */
+ FLEXSPI_MCR0_SWRESET_val0 = 0,
+ /* Software reset */
+ FLEXSPI_MCR0_SWRESET_val1 = 1,
+} FLEXSPI_MCR0_SWRESET_Enum;
+
+typedef enum {
+ /* No impact */
+ FLEXSPI_MCR0_MDIS_val0 = 0,
+ /* Module disable */
+ FLEXSPI_MCR0_MDIS_val1 = 1,
+} FLEXSPI_MCR0_MDIS_Enum;
+
+typedef enum {
+ /*
+ * Dummy Read strobe generated by FlexSPI Controller and loopback
+ * internally.
+ */
+ FLEXSPI_MCR0_RXCLKSRC_val0 = 0,
+ /*
+ * Dummy Read strobe generated by FlexSPI Controller and loopback from DQS
+ * pad.
+ */
+ FLEXSPI_MCR0_RXCLKSRC_val1 = 1,
+ /* Flash provided Read strobe and input from DQS pad */
+ FLEXSPI_MCR0_RXCLKSRC_val3 = 3,
+} FLEXSPI_MCR0_RXCLKSRC_Enum;
+
+typedef enum {
+ /* Divided by 1 */
+ FLEXSPI_MCR0_SERCLKDIV_val0 = 0,
+ /* Divided by 2 */
+ FLEXSPI_MCR0_SERCLKDIV_val1 = 1,
+ /* Divided by 3 */
+ FLEXSPI_MCR0_SERCLKDIV_val2 = 2,
+ /* Divided by 4 */
+ FLEXSPI_MCR0_SERCLKDIV_val3 = 3,
+ /* Divided by 5 */
+ FLEXSPI_MCR0_SERCLKDIV_val4 = 4,
+ /* Divided by 6 */
+ FLEXSPI_MCR0_SERCLKDIV_val5 = 5,
+ /* Divided by 7 */
+ FLEXSPI_MCR0_SERCLKDIV_val6 = 6,
+ /* Divided by 8 */
+ FLEXSPI_MCR0_SERCLKDIV_val7 = 7,
+} FLEXSPI_MCR0_SERCLKDIV_Enum;
+
+typedef enum {
+ /* Disable divide by 2 of serial flash clock for half clock frequency. */
+ FLEXSPI_MCR0_HSEN_val0 = 0,
+ /* Enable divide by 2 of serial flash clock for half clock frequency. */
+ FLEXSPI_MCR0_HSEN_val1 = 1,
+} FLEXSPI_MCR0_HSEN_Enum;
+
+typedef enum {
+ /*
+ * Doze mode support disabled. AHB clock and serial clock will not be gated
+ * off when there is doze mode request from system.
+ */
+ FLEXSPI_MCR0_DOZEEN_val0 = 0,
+ /*
+ * Doze mode support enabled. AHB clock and serial clock will be gated off
+ * when there is doze mode request from system.
+ */
+ FLEXSPI_MCR0_DOZEEN_val1 = 1,
+} FLEXSPI_MCR0_DOZEEN_Enum;
+
+typedef enum {
+ /* Disable SCLK output free-running. */
+ FLEXSPI_MCR0_SCKFREERUNEN_DISABLE = 0,
+ /* Enable SCLK output free-running. */
+ FLEXSPI_MCR0_SCKFREERUNEN_ENABLE = 1,
+} FLEXSPI_MCR0_SCKFREERUNEN_Enum;
+
+typedef enum {
+ /* Disable the data learning feature. */
+ FLEXSPI_MCR0_LEARNEN_DISABLE = 0,
+ /* Enable the data learning feature. */
+ FLEXSPI_MCR0_LEARNEN_ENABLE = 1,
+} FLEXSPI_MCR0_LEARNEN_Enum;
+
+typedef enum {
+ /*
+ * AHB RX/TX Buffer will not be cleared automatically when FlexSPI returns
+ * Stop mode ACK.
+ */
+ FLEXSPI_MCR2_CLRAHBBUFOPT_val0 = 0,
+ /*
+ * AHB RX/TX Buffer will be cleared automatically when FlexSPI returns Stop
+ * mode ACK.
+ */
+ FLEXSPI_MCR2_CLRAHBBUFOPT_val1 = 1,
+} FLEXSPI_MCR2_CLRAHBBUFOPT_Enum;
+
+typedef enum {
+ /* No impact */
+ FLEXSPI_MCR2_CLRLEARNPHASE_val0 = 0,
+ /*
+ * The sampling clock phase selection will be reset to phase 0 when this
+ * bit is written with 0x1. This bit will be auto-cleared immediately.
+ */
+ FLEXSPI_MCR2_CLRLEARNPHASE_val1 = 1,
+} FLEXSPI_MCR2_CLRLEARNPHASE_Enum;
+
+typedef enum {
+ /*
+ * In Individual mode, FLSHA1CRx/FLSHA2CRx/FLSHB1CRx/FLSHB2CRx register
+ * setting will be applied to Flash A1/A2/B1/B2 separately. In Parallel
+ * mode, FLSHA1CRx register setting will be applied to Flash A1 and B1,
+ * FLSHA2CRx register setting will be applied to Flash A2 and B2.
+ * FLSHB1CRx/FLSHB2CRx register setting will be ignored.
+ */
+ FLEXSPI_MCR2_SAMEDEVICEEN_individual_parallel = 0,
+ /*
+ * FLSHA1CR0/FLSHA1CR1/FLSHA1CR2 register setting will be applied to Flash
+ * A1/A2/B1/B2. FLSHA2CRx/FLSHB1CRx/FLSHB2CRx will be ignored.
+ */
+ FLEXSPI_MCR2_SAMEDEVICEEN_ENABLE = 1,
+} FLEXSPI_MCR2_SAMEDEVICEEN_Enum;
+
+typedef enum {
+ /* Flash will be accessed in Individual mode. */
+ FLEXSPI_AHBCR_APAREN_individual = 0,
+ /* Flash will be accessed in Parallel mode. */
+ FLEXSPI_AHBCR_APAREN_ENABLE = 1,
+} FLEXSPI_AHBCR_APAREN_Enum;
+
+typedef enum {
+ /* No function. */
+ FLEXSPI_AHBCR_CLRAHBTXBUF_val0 = 0,
+ /* Clear operation enable. */
+ FLEXSPI_AHBCR_CLRAHBTXBUF_val1 = 1,
+} FLEXSPI_AHBCR_CLRAHBTXBUF_Enum;
+
+typedef enum {
+ /*
+ * Disabled. When there is AHB bus cachable read access, FlexSPI will not
+ * check whether it hit AHB TX Buffer.
+ */
+ FLEXSPI_AHBCR_CACHABLEEN_val0 = 0,
+ /*
+ * Enabled. When there is AHB bus cachable read access, FlexSPI will check
+ * whether it hit AHB TX Buffer first.
+ */
+ FLEXSPI_AHBCR_CACHABLEEN_val1 = 1,
+} FLEXSPI_AHBCR_CACHABLEEN_Enum;
+
+typedef enum {
+ /*
+ * Disabled. For all AHB write accesses (bufferable or non-bufferable),
+ * FlexSPI will return AHB Bus ready after all data is transmitted to
+ * external device and AHB command finished.
+ */
+ FLEXSPI_AHBCR_BUFFERABLEEN_val0 = 0,
+ /*
+ * Enabled. For AHB bufferable write access, FlexSPI will return AHB Bus
+ * ready when the AHB command is granted by arbitrator and will not wait
+ * for AHB command finished.
+ */
+ FLEXSPI_AHBCR_BUFFERABLEEN_val1 = 1,
+} FLEXSPI_AHBCR_BUFFERABLEEN_Enum;
+
+typedef enum {
+ /*
+ * There is AHB read burst start address alignment limitation when flash is
+ * accessed in parallel mode or flash is word-addressable.
+ */
+ FLEXSPI_AHBCR_READADDROPT_val0 = 0,
+ /*
+ * There is no AHB read burst start address alignment limitation. FlexSPI
+ * will fetch more data than AHB burst required to meet the alignment
+ * requirement.
+ */
+ FLEXSPI_AHBCR_READADDROPT_val1 = 1,
+} FLEXSPI_AHBCR_READADDROPT_Enum;
+
+typedef enum {
+ /* Suspended AHB read prefetch will start to resume when AHB is IDLE */
+ FLEXSPI_AHBCR_RESUMEDISABLE_val0 = 0,
+ /* Suspended AHB read prefetch will not resume once it is aborted */
+ FLEXSPI_AHBCR_RESUMEDISABLE_val1 = 1,
+} FLEXSPI_AHBCR_RESUMEDISABLE_Enum;
+
+typedef enum {
+ /*
+ * AHB read size will be decided by other register setting like
+ * PREFETCH_EN,OTFAD_EN...
+ */
+ FLEXSPI_AHBCR_READSZALIGN_val0 = 0,
+ /* AHB read size to up size to 8 bytes aligned, no prefetching */
+ FLEXSPI_AHBCR_READSZALIGN_val1 = 1,
+} FLEXSPI_AHBCR_READSZALIGN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_IPCMDDONEEN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_IPCMDDONEEN_value1 = 1,
+} FLEXSPI_INTEN_IPCMDDONEEN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_IPCMDGEEN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_IPCMDGEEN_value1 = 1,
+} FLEXSPI_INTEN_IPCMDGEEN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_AHBCMDGEEN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_AHBCMDGEEN_value1 = 1,
+} FLEXSPI_INTEN_AHBCMDGEEN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_IPCMDERREN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_IPCMDERREN_value1 = 1,
+} FLEXSPI_INTEN_IPCMDERREN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_AHBCMDERREN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_AHBCMDERREN_value1 = 1,
+} FLEXSPI_INTEN_AHBCMDERREN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_IPRXWAEN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_IPRXWAEN_value1 = 1,
+} FLEXSPI_INTEN_IPRXWAEN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_IPTXWEEN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_IPTXWEEN_value1 = 1,
+} FLEXSPI_INTEN_IPTXWEEN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_DATALEARNFAILEN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_DATALEARNFAILEN_value1 = 1,
+} FLEXSPI_INTEN_DATALEARNFAILEN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_SCKSTOPBYRDEN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_SCKSTOPBYRDEN_value1 = 1,
+} FLEXSPI_INTEN_SCKSTOPBYRDEN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_SCKSTOPBYWREN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_SCKSTOPBYWREN_value1 = 1,
+} FLEXSPI_INTEN_SCKSTOPBYWREN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_AHBBUSERROREN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_AHBBUSERROREN_value1 = 1,
+} FLEXSPI_INTEN_AHBBUSERROREN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_SEQTIMEOUTEN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_SEQTIMEOUTEN_value1 = 1,
+} FLEXSPI_INTEN_SEQTIMEOUTEN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_KEYDONEEN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_KEYDONEEN_value1 = 1,
+} FLEXSPI_INTEN_KEYDONEEN_Enum;
+
+typedef enum {
+ /* Disable interrupt or no impact */
+ FLEXSPI_INTEN_KEYERROREN_value0 = 0,
+ /* Enable interrupt */
+ FLEXSPI_INTEN_KEYERROREN_value1 = 1,
+} FLEXSPI_INTEN_KEYERROREN_Enum;
+
+typedef enum {
+ /* No impact */
+ FLEXSPI_LUTCR_LOCK_value0 = 0,
+ /* Lock LUT, LUT will be locked and can't be written */
+ FLEXSPI_LUTCR_LOCK_value1 = 1,
+} FLEXSPI_LUTCR_LOCK_Enum;
+
+typedef enum {
+ /* No impact */
+ FLEXSPI_LUTCR_UNLOCK_value0 = 0,
+ /* Unlock LUT, the LUT can be written */
+ FLEXSPI_LUTCR_UNLOCK_value1 = 1,
+} FLEXSPI_LUTCR_UNLOCK_Enum;
+
+typedef enum {
+ /* No prefetch */
+ FLEXSPI_AHBRXBUF0CR0_PREFETCHEN_value0 = 0,
+ /* Prefetch enable */
+ FLEXSPI_AHBRXBUF0CR0_PREFETCHEN_value1 = 1,
+} FLEXSPI_AHBRXBUF0CR0_PREFETCHEN_Enum;
+
+typedef enum {
+ /* No prefetch */
+ FLEXSPI_AHBRXBUF1CR0_PREFETCHEN_value0 = 0,
+ /* Prefetch enable */
+ FLEXSPI_AHBRXBUF1CR0_PREFETCHEN_value1 = 1,
+} FLEXSPI_AHBRXBUF1CR0_PREFETCHEN_Enum;
+
+typedef enum {
+ /* No prefetch */
+ FLEXSPI_AHBRXBUF2CR0_PREFETCHEN_value0 = 0,
+ /* Prefetch enable */
+ FLEXSPI_AHBRXBUF2CR0_PREFETCHEN_value1 = 1,
+} FLEXSPI_AHBRXBUF2CR0_PREFETCHEN_Enum;
+
+typedef enum {
+ /* No prefetch */
+ FLEXSPI_AHBRXBUF3CR0_PREFETCHEN_value0 = 0,
+ /* Prefetch enable */
+ FLEXSPI_AHBRXBUF3CR0_PREFETCHEN_value1 = 1,
+} FLEXSPI_AHBRXBUF3CR0_PREFETCHEN_Enum;
+
+typedef enum {
+ /* No prefetch */
+ FLEXSPI_AHBRXBUF4CR0_PREFETCHEN_value0 = 0,
+ /* Prefetch enable */
+ FLEXSPI_AHBRXBUF4CR0_PREFETCHEN_value1 = 1,
+} FLEXSPI_AHBRXBUF4CR0_PREFETCHEN_Enum;
+
+typedef enum {
+ /* No prefetch */
+ FLEXSPI_AHBRXBUF5CR0_PREFETCHEN_value0 = 0,
+ /* Prefetch enable */
+ FLEXSPI_AHBRXBUF5CR0_PREFETCHEN_value1 = 1,
+} FLEXSPI_AHBRXBUF5CR0_PREFETCHEN_Enum;
+
+typedef enum {
+ /* No prefetch */
+ FLEXSPI_AHBRXBUF6CR0_PREFETCHEN_value0 = 0,
+ /* Prefetch enable */
+ FLEXSPI_AHBRXBUF6CR0_PREFETCHEN_value1 = 1,
+} FLEXSPI_AHBRXBUF6CR0_PREFETCHEN_Enum;
+
+typedef enum {
+ /* No prefetch */
+ FLEXSPI_AHBRXBUF7CR0_PREFETCHEN_value0 = 0,
+ /* Prefetch enable */
+ FLEXSPI_AHBRXBUF7CR0_PREFETCHEN_value1 = 1,
+} FLEXSPI_AHBRXBUF7CR0_PREFETCHEN_Enum;
+
+typedef enum {
+ /* This bit should be set as 0 when external Flash is byte addressable. */
+ FLEXSPI_FLSHCR1A1_WA_value0 = 0,
+ /*
+ * This bit should be set as 1 when external Flash is word addressable. If
+ * Flash is word addressable, it should be accessed in terms of 16 bits. At
+ * this time, FlexSPI will not transmit Flash address bit 0 to external
+ * Flash.
+ */
+ FLEXSPI_FLSHCR1A1_WA_value1 = 1,
+} FLEXSPI_FLSHCR1A1_WA_Enum;
+
+typedef enum {
+ /* The CS interval unit is 1 serial clock cycle */
+ FLEXSPI_FLSHCR1A1_CSINTERVALUNIT_val0 = 0,
+ /* The CS interval unit is 256 serial clock cycle */
+ FLEXSPI_FLSHCR1A1_CSINTERVALUNIT_val1 = 1,
+} FLEXSPI_FLSHCR1A1_CSINTERVALUNIT_Enum;
+
+typedef enum {
+ /* This bit should be set as 0 when external Flash is byte addressable. */
+ FLEXSPI_FLSHCR1A2_WA_value0 = 0,
+ /*
+ * This bit should be set as 1 when external Flash is word addressable. If
+ * Flash is word addressable, it should be accessed in terms of 16 bits. At
+ * this time, FlexSPI will not transmit Flash address bit 0 to external
+ * Flash.
+ */
+ FLEXSPI_FLSHCR1A2_WA_value1 = 1,
+} FLEXSPI_FLSHCR1A2_WA_Enum;
+
+typedef enum {
+ /* The CS interval unit is 1 serial clock cycle */
+ FLEXSPI_FLSHCR1A2_CSINTERVALUNIT_val0 = 0,
+ /* The CS interval unit is 256 serial clock cycle */
+ FLEXSPI_FLSHCR1A2_CSINTERVALUNIT_val1 = 1,
+} FLEXSPI_FLSHCR1A2_CSINTERVALUNIT_Enum;
+
+typedef enum {
+ /* This bit should be set as 0 when external Flash is byte addressable. */
+ FLEXSPI_FLSHCR1B1_WA_value0 = 0,
+ /*
+ * This bit should be set as 1 when external Flash is word addressable. If
+ * Flash is word addressable, it should be accessed in terms of 16 bits. At
+ * this time, FlexSPI will not transmit Flash address bit 0 to external
+ * Flash.
+ */
+ FLEXSPI_FLSHCR1B1_WA_value1 = 1,
+} FLEXSPI_FLSHCR1B1_WA_Enum;
+
+typedef enum {
+ /* The CS interval unit is 1 serial clock cycle */
+ FLEXSPI_FLSHCR1B1_CSINTERVALUNIT_val0 = 0,
+ /* The CS interval unit is 256 serial clock cycle */
+ FLEXSPI_FLSHCR1B1_CSINTERVALUNIT_val1 = 1,
+} FLEXSPI_FLSHCR1B1_CSINTERVALUNIT_Enum;
+
+typedef enum {
+ /* This bit should be set as 0 when external Flash is byte addressable. */
+ FLEXSPI_FLSHCR1B2_WA_value0 = 0,
+ /*
+ * This bit should be set as 1 when external Flash is word addressable. If
+ * Flash is word addressable, it should be accessed in terms of 16 bits. At
+ * this time, FlexSPI will not transmit Flash address bit 0 to external
+ * Flash.
+ */
+ FLEXSPI_FLSHCR1B2_WA_value1 = 1,
+} FLEXSPI_FLSHCR1B2_WA_Enum;
+
+typedef enum {
+ /* The CS interval unit is 1 serial clock cycle */
+ FLEXSPI_FLSHCR1B2_CSINTERVALUNIT_val0 = 0,
+ /* The CS interval unit is 256 serial clock cycle */
+ FLEXSPI_FLSHCR1B2_CSINTERVALUNIT_val1 = 1,
+} FLEXSPI_FLSHCR1B2_CSINTERVALUNIT_Enum;
+
+typedef enum {
+ /* The AWRWAIT unit is 2 AHB clock cycle */
+ FLEXSPI_FLSHCR2A1_AWRWAITUNIT_val0 = 0,
+ /* The AWRWAIT unit is 8 AHB clock cycle */
+ FLEXSPI_FLSHCR2A1_AWRWAITUNIT_val1 = 1,
+ /* The AWRWAIT unit is 32 AHB clock cycle */
+ FLEXSPI_FLSHCR2A1_AWRWAITUNIT_val2 = 2,
+ /* The AWRWAIT unit is 128 AHB clock cycle */
+ FLEXSPI_FLSHCR2A1_AWRWAITUNIT_val3 = 3,
+ /* The AWRWAIT unit is 512 AHB clock cycle */
+ FLEXSPI_FLSHCR2A1_AWRWAITUNIT_val4 = 4,
+ /* The AWRWAIT unit is 2048 AHB clock cycle */
+ FLEXSPI_FLSHCR2A1_AWRWAITUNIT_val5 = 5,
+ /* The AWRWAIT unit is 8192 AHB clock cycle */
+ FLEXSPI_FLSHCR2A1_AWRWAITUNIT_val6 = 6,
+ /* The AWRWAIT unit is 32768 AHB clock cycle */
+ FLEXSPI_FLSHCR2A1_AWRWAITUNIT_val7 = 7,
+} FLEXSPI_FLSHCR2A1_AWRWAITUNIT_Enum;
+
+typedef enum {
+ /* The AWRWAIT unit is 2 AHB clock cycle */
+ FLEXSPI_FLSHCR2A2_AWRWAITUNIT_val0 = 0,
+ /* The AWRWAIT unit is 8 AHB clock cycle */
+ FLEXSPI_FLSHCR2A2_AWRWAITUNIT_val1 = 1,
+ /* The AWRWAIT unit is 32 AHB clock cycle */
+ FLEXSPI_FLSHCR2A2_AWRWAITUNIT_val2 = 2,
+ /* The AWRWAIT unit is 128 AHB clock cycle */
+ FLEXSPI_FLSHCR2A2_AWRWAITUNIT_val3 = 3,
+ /* The AWRWAIT unit is 512 AHB clock cycle */
+ FLEXSPI_FLSHCR2A2_AWRWAITUNIT_val4 = 4,
+ /* The AWRWAIT unit is 2048 AHB clock cycle */
+ FLEXSPI_FLSHCR2A2_AWRWAITUNIT_val5 = 5,
+ /* The AWRWAIT unit is 8192 AHB clock cycle */
+ FLEXSPI_FLSHCR2A2_AWRWAITUNIT_val6 = 6,
+ /* The AWRWAIT unit is 32768 AHB clock cycle */
+ FLEXSPI_FLSHCR2A2_AWRWAITUNIT_val7 = 7,
+} FLEXSPI_FLSHCR2A2_AWRWAITUNIT_Enum;
+
+typedef enum {
+ /* The AWRWAIT unit is 2 AHB clock cycle */
+ FLEXSPI_FLSHCR2B1_AWRWAITUNIT_val0 = 0,
+ /* The AWRWAIT unit is 8 AHB clock cycle */
+ FLEXSPI_FLSHCR2B1_AWRWAITUNIT_val1 = 1,
+ /* The AWRWAIT unit is 32 AHB clock cycle */
+ FLEXSPI_FLSHCR2B1_AWRWAITUNIT_val2 = 2,
+ /* The AWRWAIT unit is 128 AHB clock cycle */
+ FLEXSPI_FLSHCR2B1_AWRWAITUNIT_val3 = 3,
+ /* The AWRWAIT unit is 512 AHB clock cycle */
+ FLEXSPI_FLSHCR2B1_AWRWAITUNIT_val4 = 4,
+ /* The AWRWAIT unit is 2048 AHB clock cycle */
+ FLEXSPI_FLSHCR2B1_AWRWAITUNIT_val5 = 5,
+ /* The AWRWAIT unit is 8192 AHB clock cycle */
+ FLEXSPI_FLSHCR2B1_AWRWAITUNIT_val6 = 6,
+ /* The AWRWAIT unit is 32768 AHB clock cycle */
+ FLEXSPI_FLSHCR2B1_AWRWAITUNIT_val7 = 7,
+} FLEXSPI_FLSHCR2B1_AWRWAITUNIT_Enum;
+
+typedef enum {
+ /* The AWRWAIT unit is 2 AHB clock cycle */
+ FLEXSPI_FLSHCR2B2_AWRWAITUNIT_val0 = 0,
+ /* The AWRWAIT unit is 8 AHB clock cycle */
+ FLEXSPI_FLSHCR2B2_AWRWAITUNIT_val1 = 1,
+ /* The AWRWAIT unit is 32 AHB clock cycle */
+ FLEXSPI_FLSHCR2B2_AWRWAITUNIT_val2 = 2,
+ /* The AWRWAIT unit is 128 AHB clock cycle */
+ FLEXSPI_FLSHCR2B2_AWRWAITUNIT_val3 = 3,
+ /* The AWRWAIT unit is 512 AHB clock cycle */
+ FLEXSPI_FLSHCR2B2_AWRWAITUNIT_val4 = 4,
+ /* The AWRWAIT unit is 2048 AHB clock cycle */
+ FLEXSPI_FLSHCR2B2_AWRWAITUNIT_val5 = 5,
+ /* The AWRWAIT unit is 8192 AHB clock cycle */
+ FLEXSPI_FLSHCR2B2_AWRWAITUNIT_val6 = 6,
+ /* The AWRWAIT unit is 32768 AHB clock cycle */
+ FLEXSPI_FLSHCR2B2_AWRWAITUNIT_val7 = 7,
+} FLEXSPI_FLSHCR2B2_AWRWAITUNIT_Enum;
+
+typedef enum {
+ /*
+ * DQS pin will be used as Write Mask when writing to external device.
+ * There is no limitation on AHB/IP write burst start address alignment
+ * when flash is accessed in individual mode.
+ */
+ FLEXSPI_FLSHCR4_WMOPT1_DISABLE = 0,
+ /*
+ * DQS pin will not be used as Write Mask when writing to external device.
+ * There is limitation on AHB/IP write burst start address alignment when
+ * flash is accessed in individual mode.
+ */
+ FLEXSPI_FLSHCR4_WMOPT1_ENABLE = 1,
+} FLEXSPI_FLSHCR4_WMOPT1_Enum;
+
+typedef enum {
+ /*
+ * Write mask is disabled, DQS(RWDS) pin will not be driven when writing to
+ * external device.
+ */
+ FLEXSPI_FLSHCR4_WMENA_val0 = 0,
+ /*
+ * Write mask is enabled, DQS(RWDS) pin will be driven by FlexSPI as write
+ * mask output when writing to external device.
+ */
+ FLEXSPI_FLSHCR4_WMENA_val1 = 1,
+} FLEXSPI_FLSHCR4_WMENA_Enum;
+
+typedef enum {
+ /* Flash will be accessed in Individual mode. */
+ FLEXSPI_IPCR1_IPAREN_DISABLE = 0,
+ /* Flash will be accessed in Parallel mode. */
+ FLEXSPI_IPCR1_IPAREN_ENABLE = 1,
+} FLEXSPI_IPCR1_IPAREN_Enum;
+
+typedef enum {
+ /* No function. */
+ FLEXSPI_IPRXFCR_CLRIPRXF_value0 = 0,
+ /* A clock cycle pulse to clear all valid data entries in IP RX FIFO. */
+ FLEXSPI_IPRXFCR_CLRIPRXF_value1 = 1,
+} FLEXSPI_IPRXFCR_CLRIPRXF_Enum;
+
+typedef enum {
+ /* IP RX FIFO would be read by processor. */
+ FLEXSPI_IPRXFCR_RXDMAEN_val0 = 0,
+ /* IP RX FIFO would be read by DMA. */
+ FLEXSPI_IPRXFCR_RXDMAEN_val1 = 1,
+} FLEXSPI_IPRXFCR_RXDMAEN_Enum;
+
+typedef enum {
+ /* No function. */
+ FLEXSPI_IPTXFCR_CLRIPTXF_value0 = 0,
+ /* A clock cycle pulse to clear all valid data entries in IP TX FIFO. */
+ FLEXSPI_IPTXFCR_CLRIPTXF_value1 = 1,
+} FLEXSPI_IPTXFCR_CLRIPTXF_Enum;
+
+typedef enum {
+ /* IP TX FIFO would be filled by processor. */
+ FLEXSPI_IPTXFCR_TXDMAEN_val0 = 0,
+ /* IP TX FIFO would be filled by DMA. */
+ FLEXSPI_IPTXFCR_TXDMAEN_val1 = 1,
+} FLEXSPI_IPTXFCR_TXDMAEN_Enum;
+
+typedef enum {
+ /* DLL calibration is disabled */
+ FLEXSPI_DLLCRA_DLLEN_value0 = 0,
+ /* DLL calibration is enabled */
+ FLEXSPI_DLLCRA_DLLEN_value1 = 1,
+} FLEXSPI_DLLCRA_DLLEN_Enum;
+
+typedef enum {
+ /* No function. */
+ FLEXSPI_DLLCRA_DLLRESET_value0 = 0,
+ /* Software could force a reset on DLL by setting this field to 0x1. */
+ FLEXSPI_DLLCRA_DLLRESET_value1 = 1,
+} FLEXSPI_DLLCRA_DLLRESET_Enum;
+
+typedef enum {
+ /*
+ * Slave clock delay line delay cell number selection override is disabled.
+ */
+ FLEXSPI_DLLCRA_OVRDEN_value0 = 0,
+ /*
+ * Slave clock delay line delay cell number selection override is enabled.
+ */
+ FLEXSPI_DLLCRA_OVRDEN_value1 = 1,
+} FLEXSPI_DLLCRA_OVRDEN_Enum;
+
+typedef enum {
+ /* DLL calibration is disabled */
+ FLEXSPI_DLLCRB_DLLEN_value0 = 0,
+ /* DLL calibration is enabled */
+ FLEXSPI_DLLCRB_DLLEN_value1 = 1,
+} FLEXSPI_DLLCRB_DLLEN_Enum;
+
+typedef enum {
+ /* No function. */
+ FLEXSPI_DLLCRB_DLLRESET_value0 = 0,
+ /* Software could force a reset on DLL by setting this field to 0x1. */
+ FLEXSPI_DLLCRB_DLLRESET_value1 = 1,
+} FLEXSPI_DLLCRB_DLLRESET_Enum;
+
+typedef enum {
+ /*
+ * Slave clock delay line delay cell number selection override is disabled.
+ */
+ FLEXSPI_DLLCRB_OVRDEN_value0 = 0,
+ /*
+ * Slave clock delay line delay cell number selection override is enabled.
+ */
+ FLEXSPI_DLLCRB_OVRDEN_value1 = 1,
+} FLEXSPI_DLLCRB_OVRDEN_Enum;
+
+typedef enum {
+ /* State machine in SEQ_CTL is not idle. */
+ FLEXSPI_STS0_SEQIDLE_value0 = 0,
+ /* State machine in SEQ_CTL is idle. */
+ FLEXSPI_STS0_SEQIDLE_value1 = 1,
+} FLEXSPI_STS0_SEQIDLE_Enum;
+
+typedef enum {
+ /* Triggered by AHB read command. */
+ FLEXSPI_STS0_ARBCMDSRC_val0 = 0,
+ /* Triggered by AHB write command. */
+ FLEXSPI_STS0_ARBCMDSRC_val1 = 1,
+ /*
+ * Triggered by IP command (triggered by setting register bit IPCMD[TRG]).
+ */
+ FLEXSPI_STS0_ARBCMDSRC_val2 = 2,
+ /* Triggered by suspended command (resumed). */
+ FLEXSPI_STS0_ARBCMDSRC_val3 = 3,
+} FLEXSPI_STS0_ARBCMDSRC_Enum;
+
+typedef enum {
+ /* No error. */
+ FLEXSPI_STS1_AHBCMDERRCODE_val0 = 0,
+ /* AHB Write command with JMP_ON_CS instruction used in the sequence. */
+ FLEXSPI_STS1_AHBCMDERRCODE_val2 = 2,
+ /* There is unknown instruction opcode in the sequence. */
+ FLEXSPI_STS1_AHBCMDERRCODE_val3 = 3,
+ /* Instruction DUMMY_SDR/DUMMY_RWDS_SDR used in DDR sequence. */
+ FLEXSPI_STS1_AHBCMDERRCODE_val4 = 4,
+ /* Instruction DUMMY_DDR/DUMMY_RWDS_DDR used in SDR sequence. */
+ FLEXSPI_STS1_AHBCMDERRCODE_val5 = 5,
+ /* Sequence execution timeout. */
+ FLEXSPI_STS1_AHBCMDERRCODE_val6 = 14,
+} FLEXSPI_STS1_AHBCMDERRCODE_Enum;
+
+typedef enum {
+ /* No error. */
+ FLEXSPI_STS1_IPCMDERRCODE_val0 = 0,
+ /* IP command with JMP_ON_CS instruction used in the sequence. */
+ FLEXSPI_STS1_IPCMDERRCODE_val2 = 2,
+ /* There is unknown instruction opcode in the sequence. */
+ FLEXSPI_STS1_IPCMDERRCODE_val3 = 3,
+ /* Instruction DUMMY_SDR/DUMMY_RWDS_SDR used in DDR sequence. */
+ FLEXSPI_STS1_IPCMDERRCODE_val4 = 4,
+ /* Instruction DUMMY_DDR/DUMMY_RWDS_DDR used in SDR sequence. */
+ FLEXSPI_STS1_IPCMDERRCODE_val5 = 5,
+ /*
+ * Flash access start address exceed the whole flash address range
+ * (A1/A2/B1/B2).
+ */
+ FLEXSPI_STS1_IPCMDERRCODE_val6 = 6,
+ /* Sequence execution timeout. */
+ FLEXSPI_STS1_IPCMDERRCODE_val7 = 14,
+ /* Flash boundary crossed. */
+ FLEXSPI_STS1_IPCMDERRCODE_val8 = 15,
+} FLEXSPI_STS1_IPCMDERRCODE_Enum;
+
+typedef enum {
+ /* Flash A sample clock slave delay line is not locked */
+ FLEXSPI_STS2_ASLVLOCK_val0 = 0,
+ /* Flash A sample clock slave delay line is locked */
+ FLEXSPI_STS2_ASLVLOCK_val1 = 1,
+} FLEXSPI_STS2_ASLVLOCK_Enum;
+
+typedef enum {
+ /* Flash A sample clock reference delay line is not locked */
+ FLEXSPI_STS2_AREFLOCK_val0 = 0,
+ /* Flash A sample clock reference delay line is locked */
+ FLEXSPI_STS2_AREFLOCK_val1 = 1,
+} FLEXSPI_STS2_AREFLOCK_Enum;
+
+typedef enum {
+ /* Flash B sample clock slave delay line is not locked. */
+ FLEXSPI_STS2_BSLVLOCK_val0 = 0,
+ /* Flash B sample clock slave delay line is locked. */
+ FLEXSPI_STS2_BSLVLOCK_val1 = 1,
+} FLEXSPI_STS2_BSLVLOCK_Enum;
+
+typedef enum {
+ /* Flash B sample clock reference delay line is not locked. */
+ FLEXSPI_STS2_BREFLOCK_val0 = 0,
+ /* Flash B sample clock reference delay line is locked. */
+ FLEXSPI_STS2_BREFLOCK_val1 = 1,
+} FLEXSPI_STS2_BREFLOCK_Enum;
+
+typedef enum {
+ /* No suspended AHB read prefetch command. */
+ FLEXSPI_AHBSPNDSTS_ACTIVE_val0 = 0,
+ /* An AHB read prefetch command sequence has been suspended. */
+ FLEXSPI_AHBSPNDSTS_ACTIVE_val1 = 1,
+} FLEXSPI_AHBSPNDSTS_ACTIVE_Enum;
+
+typedef enum {
+ /* HADDR REMAP Disabled */
+ FLEXSPI_HADDRSTART_REMAPEN_val0 = 0,
+ /* HADDR REMAP Enabled */
+ FLEXSPI_HADDRSTART_REMAPEN_val1 = 1,
+} FLEXSPI_HADDRSTART_REMAPEN_Enum;
+
+
+#define FLEXSPI_REGISTER_ACCESS_INFO_ARRAY(_name) \
+ struct RegisterAccessInfo _name[FLEXSPI_REGS_NO] = { \
+ [0 ... FLEXSPI_REGS_NO - 1] = { \
+ .name = "", \
+ .addr = -1, \
+ }, \
+ [R_FLEXSPI_MCR0] = { \
+ .name = "MCR0", \
+ .addr = 0x0, \
+ .ro = 0x20CC, \
+ .reset = 0xFFFF80C2, \
+ }, \
+ [R_FLEXSPI_MCR1] = { \
+ .name = "MCR1", \
+ .addr = 0x4, \
+ .ro = 0x0, \
+ .reset = 0xFFFFFFFF, \
+ }, \
+ [R_FLEXSPI_MCR2] = { \
+ .name = "MCR2", \
+ .addr = 0x8, \
+ .ro = 0xFF37FF, \
+ .reset = 0x200081F7, \
+ }, \
+ [R_FLEXSPI_AHBCR] = { \
+ .name = "AHBCR", \
+ .addr = 0xC, \
+ .ro = 0xFFFFFB02, \
+ .reset = 0x18, \
+ }, \
+ [R_FLEXSPI_INTEN] = { \
+ .name = "INTEN", \
+ .addr = 0x10, \
+ .ro = 0xFFFFC000, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_INTR] = { \
+ .name = "INTR", \
+ .addr = 0x14, \
+ .ro = 0xFFFFE000, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUTKEY] = { \
+ .name = "LUTKEY", \
+ .addr = 0x18, \
+ .ro = 0x0, \
+ .reset = 0x5AF05AF0, \
+ }, \
+ [R_FLEXSPI_LUTCR] = { \
+ .name = "LUTCR", \
+ .addr = 0x1C, \
+ .ro = 0xFFFFFFFC, \
+ .reset = 0x2, \
+ }, \
+ [R_FLEXSPI_AHBRXBUF0CR0] = { \
+ .name = "AHBRXBUF0CR0", \
+ .addr = 0x20, \
+ .ro = 0x78F0FF00, \
+ .reset = 0x80000010, \
+ }, \
+ [R_FLEXSPI_AHBRXBUF1CR0] = { \
+ .name = "AHBRXBUF1CR0", \
+ .addr = 0x24, \
+ .ro = 0x78F0FF00, \
+ .reset = 0x80010010, \
+ }, \
+ [R_FLEXSPI_AHBRXBUF2CR0] = { \
+ .name = "AHBRXBUF2CR0", \
+ .addr = 0x28, \
+ .ro = 0x78F0FF00, \
+ .reset = 0x80020010, \
+ }, \
+ [R_FLEXSPI_AHBRXBUF3CR0] = { \
+ .name = "AHBRXBUF3CR0", \
+ .addr = 0x2C, \
+ .ro = 0x78F0FF00, \
+ .reset = 0x80030010, \
+ }, \
+ [R_FLEXSPI_AHBRXBUF4CR0] = { \
+ .name = "AHBRXBUF4CR0", \
+ .addr = 0x30, \
+ .ro = 0x78F0FF00, \
+ .reset = 0x80040010, \
+ }, \
+ [R_FLEXSPI_AHBRXBUF5CR0] = { \
+ .name = "AHBRXBUF5CR0", \
+ .addr = 0x34, \
+ .ro = 0x78F0FF00, \
+ .reset = 0x80050010, \
+ }, \
+ [R_FLEXSPI_AHBRXBUF6CR0] = { \
+ .name = "AHBRXBUF6CR0", \
+ .addr = 0x38, \
+ .ro = 0x78F0FF00, \
+ .reset = 0x80060010, \
+ }, \
+ [R_FLEXSPI_AHBRXBUF7CR0] = { \
+ .name = "AHBRXBUF7CR0", \
+ .addr = 0x3C, \
+ .ro = 0x78F0FF00, \
+ .reset = 0x80070010, \
+ }, \
+ [R_FLEXSPI_FLSHA1CR0] = { \
+ .name = "FLSHA1CR0", \
+ .addr = 0x60, \
+ .ro = 0xFF800000, \
+ .reset = 0x10000, \
+ }, \
+ [R_FLEXSPI_FLSHA2CR0] = { \
+ .name = "FLSHA2CR0", \
+ .addr = 0x64, \
+ .ro = 0xFF800000, \
+ .reset = 0x10000, \
+ }, \
+ [R_FLEXSPI_FLSHB1CR0] = { \
+ .name = "FLSHB1CR0", \
+ .addr = 0x68, \
+ .ro = 0xFF800000, \
+ .reset = 0x10000, \
+ }, \
+ [R_FLEXSPI_FLSHB2CR0] = { \
+ .name = "FLSHB2CR0", \
+ .addr = 0x6C, \
+ .ro = 0xFF800000, \
+ .reset = 0x10000, \
+ }, \
+ [R_FLEXSPI_FLSHCR1A1] = { \
+ .name = "FLSHCR1A1", \
+ .addr = 0x70, \
+ .ro = 0x0, \
+ .reset = 0x63, \
+ }, \
+ [R_FLEXSPI_FLSHCR1A2] = { \
+ .name = "FLSHCR1A2", \
+ .addr = 0x74, \
+ .ro = 0x0, \
+ .reset = 0x63, \
+ }, \
+ [R_FLEXSPI_FLSHCR1B1] = { \
+ .name = "FLSHCR1B1", \
+ .addr = 0x78, \
+ .ro = 0x0, \
+ .reset = 0x63, \
+ }, \
+ [R_FLEXSPI_FLSHCR1B2] = { \
+ .name = "FLSHCR1B2", \
+ .addr = 0x7C, \
+ .ro = 0x0, \
+ .reset = 0x63, \
+ }, \
+ [R_FLEXSPI_FLSHCR2A1] = { \
+ .name = "FLSHCR2A1", \
+ .addr = 0x80, \
+ .ro = 0x1010, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_FLSHCR2A2] = { \
+ .name = "FLSHCR2A2", \
+ .addr = 0x84, \
+ .ro = 0x1010, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_FLSHCR2B1] = { \
+ .name = "FLSHCR2B1", \
+ .addr = 0x88, \
+ .ro = 0x1010, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_FLSHCR2B2] = { \
+ .name = "FLSHCR2B2", \
+ .addr = 0x8C, \
+ .ro = 0x1010, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_FLSHCR4] = { \
+ .name = "FLSHCR4", \
+ .addr = 0x94, \
+ .ro = 0xFFFFFFFA, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_IPCR0] = { \
+ .name = "IPCR0", \
+ .addr = 0xA0, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_IPCR1] = { \
+ .name = "IPCR1", \
+ .addr = 0xA4, \
+ .ro = 0x78F00000, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_IPCMD] = { \
+ .name = "IPCMD", \
+ .addr = 0xB0, \
+ .ro = 0xFFFFFFFE, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_DLPR] = { \
+ .name = "DLPR", \
+ .addr = 0xB4, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_IPRXFCR] = { \
+ .name = "IPRXFCR", \
+ .addr = 0xB8, \
+ .ro = 0xFFFFFE00, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_IPTXFCR] = { \
+ .name = "IPTXFCR", \
+ .addr = 0xBC, \
+ .ro = 0xFFFFFE00, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_DLLCRA] = { \
+ .name = "DLLCRA", \
+ .addr = 0xC0, \
+ .ro = 0xFFFF8084, \
+ .reset = 0x100, \
+ }, \
+ [R_FLEXSPI_DLLCRB] = { \
+ .name = "DLLCRB", \
+ .addr = 0xC4, \
+ .ro = 0xFFFF8084, \
+ .reset = 0x100, \
+ }, \
+ [R_FLEXSPI_STS0] = { \
+ .name = "STS0", \
+ .addr = 0xE0, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x2, \
+ }, \
+ [R_FLEXSPI_STS1] = { \
+ .name = "STS1", \
+ .addr = 0xE4, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_STS2] = { \
+ .name = "STS2", \
+ .addr = 0xE8, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x1000100, \
+ }, \
+ [R_FLEXSPI_AHBSPNDSTS] = { \
+ .name = "AHBSPNDSTS", \
+ .addr = 0xEC, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_IPRXFSTS] = { \
+ .name = "IPRXFSTS", \
+ .addr = 0xF0, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_IPTXFSTS] = { \
+ .name = "IPTXFSTS", \
+ .addr = 0xF4, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR0] = { \
+ .name = "RFDR0", \
+ .addr = 0x100, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR1] = { \
+ .name = "RFDR1", \
+ .addr = 0x104, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR2] = { \
+ .name = "RFDR2", \
+ .addr = 0x108, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR3] = { \
+ .name = "RFDR3", \
+ .addr = 0x10C, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR4] = { \
+ .name = "RFDR4", \
+ .addr = 0x110, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR5] = { \
+ .name = "RFDR5", \
+ .addr = 0x114, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR6] = { \
+ .name = "RFDR6", \
+ .addr = 0x118, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR7] = { \
+ .name = "RFDR7", \
+ .addr = 0x11C, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR8] = { \
+ .name = "RFDR8", \
+ .addr = 0x120, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR9] = { \
+ .name = "RFDR9", \
+ .addr = 0x124, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR10] = { \
+ .name = "RFDR10", \
+ .addr = 0x128, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR11] = { \
+ .name = "RFDR11", \
+ .addr = 0x12C, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR12] = { \
+ .name = "RFDR12", \
+ .addr = 0x130, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR13] = { \
+ .name = "RFDR13", \
+ .addr = 0x134, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR14] = { \
+ .name = "RFDR14", \
+ .addr = 0x138, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR15] = { \
+ .name = "RFDR15", \
+ .addr = 0x13C, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR16] = { \
+ .name = "RFDR16", \
+ .addr = 0x140, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR17] = { \
+ .name = "RFDR17", \
+ .addr = 0x144, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR18] = { \
+ .name = "RFDR18", \
+ .addr = 0x148, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR19] = { \
+ .name = "RFDR19", \
+ .addr = 0x14C, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR20] = { \
+ .name = "RFDR20", \
+ .addr = 0x150, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR21] = { \
+ .name = "RFDR21", \
+ .addr = 0x154, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR22] = { \
+ .name = "RFDR22", \
+ .addr = 0x158, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR23] = { \
+ .name = "RFDR23", \
+ .addr = 0x15C, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR24] = { \
+ .name = "RFDR24", \
+ .addr = 0x160, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR25] = { \
+ .name = "RFDR25", \
+ .addr = 0x164, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR26] = { \
+ .name = "RFDR26", \
+ .addr = 0x168, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR27] = { \
+ .name = "RFDR27", \
+ .addr = 0x16C, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR28] = { \
+ .name = "RFDR28", \
+ .addr = 0x170, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR29] = { \
+ .name = "RFDR29", \
+ .addr = 0x174, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR30] = { \
+ .name = "RFDR30", \
+ .addr = 0x178, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_RFDR31] = { \
+ .name = "RFDR31", \
+ .addr = 0x17C, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR0] = { \
+ .name = "TFDR0", \
+ .addr = 0x180, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR1] = { \
+ .name = "TFDR1", \
+ .addr = 0x184, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR2] = { \
+ .name = "TFDR2", \
+ .addr = 0x188, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR3] = { \
+ .name = "TFDR3", \
+ .addr = 0x18C, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR4] = { \
+ .name = "TFDR4", \
+ .addr = 0x190, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR5] = { \
+ .name = "TFDR5", \
+ .addr = 0x194, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR6] = { \
+ .name = "TFDR6", \
+ .addr = 0x198, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR7] = { \
+ .name = "TFDR7", \
+ .addr = 0x19C, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR8] = { \
+ .name = "TFDR8", \
+ .addr = 0x1A0, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR9] = { \
+ .name = "TFDR9", \
+ .addr = 0x1A4, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR10] = { \
+ .name = "TFDR10", \
+ .addr = 0x1A8, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR11] = { \
+ .name = "TFDR11", \
+ .addr = 0x1AC, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR12] = { \
+ .name = "TFDR12", \
+ .addr = 0x1B0, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR13] = { \
+ .name = "TFDR13", \
+ .addr = 0x1B4, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR14] = { \
+ .name = "TFDR14", \
+ .addr = 0x1B8, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR15] = { \
+ .name = "TFDR15", \
+ .addr = 0x1BC, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR16] = { \
+ .name = "TFDR16", \
+ .addr = 0x1C0, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR17] = { \
+ .name = "TFDR17", \
+ .addr = 0x1C4, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR18] = { \
+ .name = "TFDR18", \
+ .addr = 0x1C8, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR19] = { \
+ .name = "TFDR19", \
+ .addr = 0x1CC, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR20] = { \
+ .name = "TFDR20", \
+ .addr = 0x1D0, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR21] = { \
+ .name = "TFDR21", \
+ .addr = 0x1D4, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR22] = { \
+ .name = "TFDR22", \
+ .addr = 0x1D8, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR23] = { \
+ .name = "TFDR23", \
+ .addr = 0x1DC, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR24] = { \
+ .name = "TFDR24", \
+ .addr = 0x1E0, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR25] = { \
+ .name = "TFDR25", \
+ .addr = 0x1E4, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR26] = { \
+ .name = "TFDR26", \
+ .addr = 0x1E8, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR27] = { \
+ .name = "TFDR27", \
+ .addr = 0x1EC, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR28] = { \
+ .name = "TFDR28", \
+ .addr = 0x1F0, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR29] = { \
+ .name = "TFDR29", \
+ .addr = 0x1F4, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR30] = { \
+ .name = "TFDR30", \
+ .addr = 0x1F8, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_TFDR31] = { \
+ .name = "TFDR31", \
+ .addr = 0x1FC, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT0] = { \
+ .name = "LUT0", \
+ .addr = 0x200, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT1] = { \
+ .name = "LUT1", \
+ .addr = 0x204, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT2] = { \
+ .name = "LUT2", \
+ .addr = 0x208, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT3] = { \
+ .name = "LUT3", \
+ .addr = 0x20C, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT4] = { \
+ .name = "LUT4", \
+ .addr = 0x210, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT5] = { \
+ .name = "LUT5", \
+ .addr = 0x214, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT6] = { \
+ .name = "LUT6", \
+ .addr = 0x218, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT7] = { \
+ .name = "LUT7", \
+ .addr = 0x21C, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT8] = { \
+ .name = "LUT8", \
+ .addr = 0x220, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT9] = { \
+ .name = "LUT9", \
+ .addr = 0x224, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT10] = { \
+ .name = "LUT10", \
+ .addr = 0x228, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT11] = { \
+ .name = "LUT11", \
+ .addr = 0x22C, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT12] = { \
+ .name = "LUT12", \
+ .addr = 0x230, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT13] = { \
+ .name = "LUT13", \
+ .addr = 0x234, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT14] = { \
+ .name = "LUT14", \
+ .addr = 0x238, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT15] = { \
+ .name = "LUT15", \
+ .addr = 0x23C, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT16] = { \
+ .name = "LUT16", \
+ .addr = 0x240, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT17] = { \
+ .name = "LUT17", \
+ .addr = 0x244, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT18] = { \
+ .name = "LUT18", \
+ .addr = 0x248, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT19] = { \
+ .name = "LUT19", \
+ .addr = 0x24C, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT20] = { \
+ .name = "LUT20", \
+ .addr = 0x250, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT21] = { \
+ .name = "LUT21", \
+ .addr = 0x254, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT22] = { \
+ .name = "LUT22", \
+ .addr = 0x258, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT23] = { \
+ .name = "LUT23", \
+ .addr = 0x25C, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT24] = { \
+ .name = "LUT24", \
+ .addr = 0x260, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT25] = { \
+ .name = "LUT25", \
+ .addr = 0x264, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT26] = { \
+ .name = "LUT26", \
+ .addr = 0x268, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT27] = { \
+ .name = "LUT27", \
+ .addr = 0x26C, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT28] = { \
+ .name = "LUT28", \
+ .addr = 0x270, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT29] = { \
+ .name = "LUT29", \
+ .addr = 0x274, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT30] = { \
+ .name = "LUT30", \
+ .addr = 0x278, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT31] = { \
+ .name = "LUT31", \
+ .addr = 0x27C, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT32] = { \
+ .name = "LUT32", \
+ .addr = 0x280, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT33] = { \
+ .name = "LUT33", \
+ .addr = 0x284, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT34] = { \
+ .name = "LUT34", \
+ .addr = 0x288, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT35] = { \
+ .name = "LUT35", \
+ .addr = 0x28C, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT36] = { \
+ .name = "LUT36", \
+ .addr = 0x290, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT37] = { \
+ .name = "LUT37", \
+ .addr = 0x294, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT38] = { \
+ .name = "LUT38", \
+ .addr = 0x298, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT39] = { \
+ .name = "LUT39", \
+ .addr = 0x29C, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT40] = { \
+ .name = "LUT40", \
+ .addr = 0x2A0, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT41] = { \
+ .name = "LUT41", \
+ .addr = 0x2A4, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT42] = { \
+ .name = "LUT42", \
+ .addr = 0x2A8, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT43] = { \
+ .name = "LUT43", \
+ .addr = 0x2AC, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT44] = { \
+ .name = "LUT44", \
+ .addr = 0x2B0, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT45] = { \
+ .name = "LUT45", \
+ .addr = 0x2B4, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT46] = { \
+ .name = "LUT46", \
+ .addr = 0x2B8, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT47] = { \
+ .name = "LUT47", \
+ .addr = 0x2BC, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT48] = { \
+ .name = "LUT48", \
+ .addr = 0x2C0, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT49] = { \
+ .name = "LUT49", \
+ .addr = 0x2C4, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT50] = { \
+ .name = "LUT50", \
+ .addr = 0x2C8, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT51] = { \
+ .name = "LUT51", \
+ .addr = 0x2CC, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT52] = { \
+ .name = "LUT52", \
+ .addr = 0x2D0, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT53] = { \
+ .name = "LUT53", \
+ .addr = 0x2D4, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT54] = { \
+ .name = "LUT54", \
+ .addr = 0x2D8, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT55] = { \
+ .name = "LUT55", \
+ .addr = 0x2DC, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT56] = { \
+ .name = "LUT56", \
+ .addr = 0x2E0, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT57] = { \
+ .name = "LUT57", \
+ .addr = 0x2E4, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT58] = { \
+ .name = "LUT58", \
+ .addr = 0x2E8, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT59] = { \
+ .name = "LUT59", \
+ .addr = 0x2EC, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT60] = { \
+ .name = "LUT60", \
+ .addr = 0x2F0, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT61] = { \
+ .name = "LUT61", \
+ .addr = 0x2F4, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT62] = { \
+ .name = "LUT62", \
+ .addr = 0x2F8, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_LUT63] = { \
+ .name = "LUT63", \
+ .addr = 0x2FC, \
+ .ro = 0x0, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_HADDRSTART] = { \
+ .name = "HADDRSTART", \
+ .addr = 0x420, \
+ .ro = 0xFFE, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_HADDREND] = { \
+ .name = "HADDREND", \
+ .addr = 0x424, \
+ .ro = 0xFFF, \
+ .reset = 0x0, \
+ }, \
+ [R_FLEXSPI_HADDROFFSET] = { \
+ .name = "HADDROFFSET", \
+ .addr = 0x428, \
+ .ro = 0xFFF, \
+ .reset = 0x0, \
+ }, \
+ }
diff --git a/include/hw/ssi/flexspi.h b/include/hw/ssi/flexspi.h
new file mode 100644
index 0000000000..51699e1ceb
--- /dev/null
+++ b/include/hw/ssi/flexspi.h
@@ -0,0 +1,31 @@
+/*
+ * QEMU model for FLEXSPI
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_RT500_FLEXSPI_H
+#define HW_RT500_FLEXSPI_H
+
+#include "hw/sysbus.h"
+#include "hw/ssi/ssi.h"
+#include "hw/arm/svd/flexspi.h"
+
+#define TYPE_FLEXSPI "flexspi"
+#define FLEXSPI(obj) OBJECT_CHECK(FlexSpiState, (obj), TYPE_FLEXSPI)
+
+typedef struct {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+ uint32_t regs[FLEXSPI_REGS_NO];
+ MemoryRegion mem;
+ uint64_t mmap_size;
+} FlexSpiState;
+
+#endif /* HW_RT500_FLEXSPI_H */
diff --git a/hw/ssi/flexspi.c b/hw/ssi/flexspi.c
new file mode 100644
index 0000000000..d5d9e4f098
--- /dev/null
+++ b/hw/ssi/flexspi.c
@@ -0,0 +1,181 @@
+/*
+ * QEMU model for FLEXSPI
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/mmap-alloc.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
+#include "migration/vmstate.h"
+#include "exec/address-spaces.h"
+#include "hw/ssi/flexspi.h"
+#include "hw/arm/svd/flexspi.h"
+
+#include "trace.h"
+
+#define REG(s, reg) (s->regs[R_FLEXSPI_##reg])
+#define RF_WR(s, reg, field, val) \
+ ARRAY_FIELD_DP32(s->regs, FLEXSPI_##reg, field, val)
+#define RF_RD(s, reg, field) \
+ ARRAY_FIELD_EX32(s->regs, FLEXSPI_##reg, field)
+
+static FLEXSPI_REGISTER_ACCESS_INFO_ARRAY(reg_info);
+
+static void flexspi_reset_enter(Object *obj, ResetType type)
+{
+ FlexSpiState *s = FLEXSPI(obj);
+
+ for (int i = 0; i < FLEXSPI_REGS_NO; i++) {
+ hwaddr addr = reg_info[i].addr;
+
+ if (addr != -1) {
+ struct RegisterInfo ri = {
+ .data = &s->regs[addr / 4],
+ .data_size = 4,
+ .access = ®_info[i],
+ };
+
+ register_reset(&ri);
+ }
+ }
+
+ /* idle immediately after reset */
+ RF_WR(s, STS0, SEQIDLE, 1);
+}
+
+static MemTxResult flexspi_read(void *opaque, hwaddr addr,
+ uint64_t *data, unsigned size,
+ MemTxAttrs attrs)
+{
+ FlexSpiState *s = opaque;
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+ MemTxResult ret = MEMTX_OK;
+
+ switch (addr) {
+ default:
+ *data = s->regs[addr / 4];
+ break;
+ }
+
+ trace_flexspi_reg_read(DEVICE(s)->id, rai->name, addr, *data);
+ return ret;
+}
+
+
+static MemTxResult flexspi_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size,
+ MemTxAttrs attrs)
+{
+ FlexSpiState *s = opaque;
+ const struct RegisterAccessInfo *rai = ®_info[addr / 4];
+ struct RegisterInfo ri = {
+ .data = &s->regs[addr / 4],
+ .data_size = 4,
+ .access = rai,
+ };
+
+ trace_flexspi_reg_write(DEVICE(s)->id, rai->name, addr, value);
+
+ switch (addr) {
+ case A_FLEXSPI_MCR0:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+
+ if (RF_RD(s, MCR0, SWRESET)) {
+ RF_WR(s, MCR0, SWRESET, 0);
+ }
+ break;
+ }
+ case A_FLEXSPI_INTR:
+ {
+ /* fake SPI transfer completion */
+ RF_WR(s, INTR, IPCMDDONE, 1);
+ break;
+ }
+ default:
+ register_write(&ri, value, ~0, NULL, false);
+ break;
+ }
+
+ return MEMTX_OK;
+}
+
+static const MemoryRegionOps flexspi_ops = {
+ .read_with_attrs = flexspi_read,
+ .write_with_attrs = flexspi_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ .unaligned = false,
+ },
+};
+
+static Property flexspi_properties[] = {
+ DEFINE_PROP_UINT64("mmap_size", FlexSpiState, mmap_size, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void flexspi_init(Object *obj)
+{
+ FlexSpiState *s = FLEXSPI(obj);
+
+ memory_region_init_io(&s->mmio, obj, &flexspi_ops, s, TYPE_FLEXSPI,
+ sizeof(s->regs));
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+}
+
+static void flexspi_realize(DeviceState *dev, Error **errp)
+{
+ FlexSpiState *s = FLEXSPI(dev);
+
+ if (s->mmap_size) {
+ memory_region_init_ram(&s->mem, OBJECT(s), DEVICE(s)->id, s->mmap_size,
+ NULL);
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->mem);
+ }
+}
+
+static const VMStateDescription vmstate_flexspi = {
+ .name = "flexspi",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(regs, FlexSpiState, FLEXSPI_REGS_NO),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void flexspi_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+
+ rc->phases.enter = flexspi_reset_enter;
+ dc->realize = flexspi_realize;
+ dc->vmsd = &vmstate_flexspi;
+ device_class_set_props(dc, flexspi_properties);
+}
+
+static const TypeInfo flexspi_types[] = {
+ {
+ .name = TYPE_FLEXSPI,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(FlexSpiState),
+ .instance_init = flexspi_init,
+ .class_init = flexspi_class_init,
+ },
+};
+
+DEFINE_TYPES(flexspi_types);
diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build
index d017010b73..7e59eda0d3 100644
--- a/hw/arm/svd/meson.build
+++ b/hw/arm/svd/meson.build
@@ -19,4 +19,7 @@ if get_option('mcux-soc-svd')
run_target('svd-rt500-clkctl1', command: svd_gen_header +
[ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/rt500_clkctl1.h',
'-p', 'CLKCTL1', '-t', 'RT500_CLKCTL1'])
+ run_target('svd-flexspi', command: svd_gen_header +
+ [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexspi.h',
+ '-p', 'FLEXSPI0', '-t', 'FLEXSPI'])
endif
diff --git a/hw/ssi/Kconfig b/hw/ssi/Kconfig
index 8d180de7cf..e3de40e6b6 100644
--- a/hw/ssi/Kconfig
+++ b/hw/ssi/Kconfig
@@ -28,3 +28,7 @@ config BCM2835_SPI
config PNV_SPI
bool
select SSI
+
+config FLEXSPI
+ bool
+ select SSI
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
index 4039e6d18d..1822c5e6c7 100644
--- a/hw/ssi/meson.build
+++ b/hw/ssi/meson.build
@@ -14,3 +14,4 @@ system_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_spi_host.c'))
system_ss.add(when: 'CONFIG_BCM2835_SPI', if_true: files('bcm2835_spi.c'))
system_ss.add(when: 'CONFIG_PNV_SPI', if_true: files('pnv_spi.c'))
system_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm_spi.c'))
+system_ss.add(when: 'CONFIG_FLEXSPI', if_true: files('flexspi.c'))
diff --git a/hw/ssi/trace-events b/hw/ssi/trace-events
index f849f1f8be..dd2f04cb22 100644
--- a/hw/ssi/trace-events
+++ b/hw/ssi/trace-events
@@ -58,3 +58,7 @@ pnv_spi_RDR_match(const char* result) "%s"
flexcomm_spi_reg_read(const char *id, const char *reg_name, uint32_t addr, uint32_t val) " %s: %s[0x%04x] -> 0x%08x"
flexcomm_spi_reg_write(const char *id, const char *reg_name, uint32_t addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x"
flexcomm_spi_irq(const char *id, bool irq, bool fifoirqs, bool perirqs, bool enabled) "%s: %d %d %d %d"
+
+# flexspi.c
+flexspi_reg_read(const char *id, const char *reg_name, uint32_t addr, uint32_t val) " %s: %s[0x%04x] -> 0x%08x"
+flexspi_reg_write(const char *id, const char *reg_name, uint32_t addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x"
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 12/25] hw/misc: add support for RT500's reset controller
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (10 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 11/25] hw/ssi: add support for flexspi Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 13/25] hw/arm: add basic support for the RT500 SoC Octavian Purdila
` (12 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
The RT500 reset controller has two instances that have the same
register layout but with different fields for some registers.
The model only provides set and clear functionality for the various
reset lines which is common for both instances. Because of that only
one type is implemented for both controllers.
The patch includes automatically generated headers which contains the
register layout and helpers.
The header can be regenerated with the svd-rstctl0 and svd-rstctl1
targets when the build is configured with --enable-mcux-soc-svd.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
include/hw/arm/svd/rt500_rstctl0.h | 858 +++++++++++++++++
include/hw/arm/svd/rt500_rstctl1.h | 1371 ++++++++++++++++++++++++++++
include/hw/misc/rt500_rstctl.h | 32 +
hw/misc/rt500_rstctl.c | 258 ++++++
hw/arm/svd/meson.build | 6 +
hw/misc/Kconfig | 3 +
hw/misc/meson.build | 1 +
hw/misc/trace-events | 4 +
8 files changed, 2533 insertions(+)
create mode 100644 include/hw/arm/svd/rt500_rstctl0.h
create mode 100644 include/hw/arm/svd/rt500_rstctl1.h
create mode 100644 include/hw/misc/rt500_rstctl.h
create mode 100644 hw/misc/rt500_rstctl.c
diff --git a/include/hw/arm/svd/rt500_rstctl0.h b/include/hw/arm/svd/rt500_rstctl0.h
new file mode 100644
index 0000000000..63d7c986dd
--- /dev/null
+++ b/include/hw/arm/svd/rt500_rstctl0.h
@@ -0,0 +1,858 @@
+/*
+ * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
+ */
+#pragma once
+
+#include "hw/register.h"
+
+/* Reset Controller 0 */
+#define RT500_RSTCTL0_REGS_NO (31)
+
+/* System Reset Status Register */
+REG32(RT500_RSTCTL0_SYSRSTSTAT, 0);
+/* VDD CORE Power-On Reset (POR) was detected */
+FIELD(RT500_RSTCTL0_SYSRSTSTAT, VDD_POR, 0, 1);
+/* RESETN pin reset was detected */
+FIELD(RT500_RSTCTL0_SYSRSTSTAT, PAD_RESET, 4, 1);
+/* ARM reset was detected */
+FIELD(RT500_RSTCTL0_SYSRSTSTAT, ARM_RESET, 5, 1);
+/* WatchDog Timer 0 reset was detected */
+FIELD(RT500_RSTCTL0_SYSRSTSTAT, WDT0_RESET, 6, 1);
+/* WatchDog Timer 1 reset was detected */
+FIELD(RT500_RSTCTL0_SYSRSTSTAT, WDT1_RESET, 7, 1);
+
+/* Peripheral Reset Control Register 0 */
+REG32(RT500_RSTCTL0_PRSTCTL0, 16);
+/* Fusion F1 DSP reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, DSP, 1, 1);
+/* AXI Switch reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, AXI_SWITCH, 3, 1);
+/* POWERQUAD reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, POWERQUAD, 8, 1);
+/* CASPER reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, CASPER, 9, 1);
+/* Hash-Crypt reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, HASHCRYPT, 10, 1);
+/* PUF reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, PUF, 11, 1);
+/* RNG reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, RNG, 12, 1);
+/* FLEXSPI0 and OTFAD reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, FLEXSPI0_OTFAD, 16, 1);
+/* FLEXSPI1 reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, FLEXSPI1, 18, 1);
+/* USB PHY reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, USBHS_PHY, 20, 1);
+/* USB HS Device reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, USBHS_DEVICE, 21, 1);
+/* USB HOST reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, USBHS_HOST, 22, 1);
+/* USB RAM reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, USBHS_SRAM, 23, 1);
+/* SCTimer reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, SCT, 24, 1);
+/* GPU reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, GPU, 26, 1);
+/* LCDIF Display Controller reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, DISPLAY_CONTROLLER, 27, 1);
+/* MIPI Digital serial Interface controller reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, MIPI_DSI_CONTROLLER, 28, 1);
+/* MIPI DSI PHY reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, MIPI_DSI_PHY, 29, 1);
+/* SMARTDMA Event/Algorithm handler reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL0, SMARTDMA, 30, 1);
+
+/* Peripheral Reset Control Register 1 */
+REG32(RT500_RSTCTL0_PRSTCTL1, 20);
+/* SDIO0 reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL1, SDIO0, 2, 1);
+/* SDIO1 reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL1, SDIO1, 3, 1);
+/* Analog comparator reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL1, ACMP0, 15, 1);
+/* Analog-to-Digital converter reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL1, ADC0, 16, 1);
+/* Secure GPIO 0 reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL1, SHSGPIO0, 24, 1);
+
+/* Peripheral Reset Control Register 2 */
+REG32(RT500_RSTCTL0_PRSTCTL2, 24);
+/* Micro-tick timer reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL2, UTICK0, 0, 1);
+/* Watchdog timer reset control */
+FIELD(RT500_RSTCTL0_PRSTCTL2, WWDT0, 1, 1);
+
+/* Peripheral Reset Control Register 0 SET */
+REG32(RT500_RSTCTL0_PRSTCTL0_SET, 64);
+/* Fusion_ DSP reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, DSP, 1, 1);
+/* AXI SWITCH reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, AXI_SWITCH, 3, 1);
+/* POWERQUAD reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, POWERQUAD, 8, 1);
+/* CASPER reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, CASPER, 9, 1);
+/* HASHCRYPT reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, HASHCRYPT, 10, 1);
+/* PUF reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, PUF, 11, 1);
+/* RNG reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, RNG, 12, 1);
+/* FLEXSPI0 and OTFAD reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, FLEXSPI0_OTFAD, 16, 1);
+/* FLEXSPI1 reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, FLEXSPI1, 18, 1);
+/* USB PHY reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, USBHS_PHY, 20, 1);
+/* USB Device reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, USBHS_DEVICE, 21, 1);
+/* USB HOST reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, USBHS_HOST, 22, 1);
+/* USBHS SRAM reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, USBHS_SRAM, 23, 1);
+/* SCTimer reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, SCT, 24, 1);
+/* GPU reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, GPU, 26, 1);
+/* LCDIF DISPLAY CONTROLLER reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, DISPLAY_CONTROLLER, 27, 1);
+/* MIPI DSI controller reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, MIPI_DSI_CONTROLLER, 28, 1);
+/* MIPI DSI PHY reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, MIPI_DSI_PHY, 29, 1);
+/* SMARTDMA Event/Algorithm handler reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL0_SET, SMARTDMA, 30, 1);
+
+/* Peripheral Reset Control Register 1 SET */
+REG32(RT500_RSTCTL0_PRSTCTL1_SET, 68);
+/* SDIO0 reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL1_SET, SDIO0, 2, 1);
+/* SDIO1 reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL1_SET, SDIO1, 3, 1);
+/* ACMP0 reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL1_SET, ACMP0, 15, 1);
+/* ADC0 reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL1_SET, ADC0, 16, 1);
+/* SHSGPIO0 reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL1_SET, SHSGPIO0, 24, 1);
+
+/* Peripheral Reset Control Register 2 SET */
+REG32(RT500_RSTCTL0_PRSTCTL2_SET, 72);
+/* Micro-tick timer 0 reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL2_SET, UTICK0, 0, 1);
+/* WWDT0 reset set */
+FIELD(RT500_RSTCTL0_PRSTCTL2_SET, WWDT0, 1, 1);
+
+/* Peripheral Reset Control Register 0 CLR */
+REG32(RT500_RSTCTL0_PRSTCTL0_CLR, 112);
+/* Fusion_ F1 DSP reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, DSP, 1, 1);
+/* AXI SWITCH reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, AXI_SWITCH, 3, 1);
+/* POWERQUAD reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, POWERQUAD, 8, 1);
+/* CASPER reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, CASPER, 9, 1);
+/* HASHCRYPT reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, HASHCRYPT, 10, 1);
+/* PUF reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, PUF, 11, 1);
+/* RNG reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, RNG, 12, 1);
+/* FLEXSPI0 and OTFAD reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, FLEXSPI0_OTFAD, 16, 1);
+/* FLEXSPI1 reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, FLEXSPI1, 18, 1);
+/* USB PHY reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, USBHS_PHY, 20, 1);
+/* USB DEVICE reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, USBHS_DEVICE, 21, 1);
+/* USB HOST reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, USBHS_HOST, 22, 1);
+/* USBHS SRAM reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, USBHS_SRAM, 23, 1);
+/* SCT reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, SCT, 24, 1);
+/* GPU reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, GPU, 26, 1);
+/* LCDIF DISPLAY CONTROLLER reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, DISPLAY_CONTROLLER, 27, 1);
+/* MIPI DSI controller reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, MIPI_DSI_CONTROLLER, 28, 1);
+/* MIPI DSI PHY reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, MIPI_DSI_PHY, 29, 1);
+/* SMARTDMA Event/Algorithm handler reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL0_CLR, SMARTDMA, 30, 1);
+
+/* Peripheral Reset Control Register 1 CLR */
+REG32(RT500_RSTCTL0_PRSTCTL1_CLR, 116);
+/* SDIO0 reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL1_CLR, SDIO0, 2, 1);
+/* SDIO1 reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL1_CLR, SDIO1, 3, 1);
+/* ACMP0 reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL1_CLR, ACMP0, 15, 1);
+/* ADC0 reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL1_CLR, ADC0, 16, 1);
+/* Secure HSGPIO0 reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL1_CLR, SHSGPIO0, 24, 1);
+
+/* Peripheral Reset Control Register 2 CLR */
+REG32(RT500_RSTCTL0_PRSTCTL2_CLR, 120);
+/* Micro-tick timer 0 reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL2_CLR, UTICK0, 0, 1);
+/* WWDT0 reset clear */
+FIELD(RT500_RSTCTL0_PRSTCTL2_CLR, WWDT0, 1, 1);
+
+
+typedef enum {
+ /* No VDD CORE POR event is detected */
+ RT500_RSTCTL0_SYSRSTSTAT_VDD_POR_VDD_POR_EVENT_IS_NOT_DETECTED = 0,
+ /* VDD CORE POR event was detected */
+ RT500_RSTCTL0_SYSRSTSTAT_VDD_POR_VDD_POR_EVENT_WAS_DETECTED = 1,
+} RT500_RSTCTL0_SYSRSTSTAT_VDD_POR_Enum;
+
+typedef enum {
+ /* No RESETN pin event is detected */
+ RT500_RSTCTL0_SYSRSTSTAT_PAD_RESET_PAD_RESET_IS_NOT_DETECTED = 0,
+ /* RESETN pin event was detected. Write '1' to clear this bit */
+ RT500_RSTCTL0_SYSRSTSTAT_PAD_RESET_PAD_RESET_WAS_DETECTED = 1,
+} RT500_RSTCTL0_SYSRSTSTAT_PAD_RESET_Enum;
+
+typedef enum {
+ /* No ARM reset event is detected */
+ RT500_RSTCTL0_SYSRSTSTAT_ARM_RESET_ARM_RESET_IS_NOT_DETECTED = 0,
+ /* ARM reset was detected. Write '1' to clear this bit */
+ RT500_RSTCTL0_SYSRSTSTAT_ARM_RESET_ARM_RESET_WAS_DETECTED = 1,
+} RT500_RSTCTL0_SYSRSTSTAT_ARM_RESET_Enum;
+
+typedef enum {
+ /* No WDT0 reset event detected */
+ RT500_RSTCTL0_SYSRSTSTAT_WDT0_RESET_WDT0_RESET_IS_NOT_DETECTED = 0,
+ /* WDT0 reset event detected. Write '1' to clear this bit */
+ RT500_RSTCTL0_SYSRSTSTAT_WDT0_RESET_WDT0_RESET_WAS_DETECTED = 1,
+} RT500_RSTCTL0_SYSRSTSTAT_WDT0_RESET_Enum;
+
+typedef enum {
+ /* No WDT1 reset event detected */
+ RT500_RSTCTL0_SYSRSTSTAT_WDT1_RESET_WDT1_RESET_IS_NOT_DETECTED = 0,
+ /* WDT1 reset event detected. Write '1' to clear this bit */
+ RT500_RSTCTL0_SYSRSTSTAT_WDT1_RESET_WDT1_RESET_WAS_DETECTED = 1,
+} RT500_RSTCTL0_SYSRSTSTAT_WDT1_RESET_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_DSP_DSP_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_DSP_DSP_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_DSP_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_AXI_SWITCH_AXI_SWITCH_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_AXI_SWITCH_AXI_SWITCH_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_AXI_SWITCH_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_POWERQUAD_POWERQUAD_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_POWERQUAD_POWERQUAD_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_POWERQUAD_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_CASPER_CASPER_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_CASPER_CASPER_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CASPER_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_HASHCRYPT_HASHCRYPT_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_HASHCRYPT_HASHCRYPT_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_HASHCRYPT_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_PUF_PUF_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_PUF_PUF_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_PUF_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_RNG_RNG_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_RNG_RNG_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_RNG_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_FLEXSPI0_OTFAD_FLEXSPI0_OTFAD_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_FLEXSPI0_OTFAD_FLEXSPI0_OTFAD_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_FLEXSPI0_OTFAD_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_FLEXSPI1_FLEXSPI1_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_FLEXSPI1_FLEXSPI1_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_FLEXSPI1_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_USBHS_PHY_USBHS_PHY_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_USBHS_PHY_USBHS_PHY_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_USBHS_PHY_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_USBHS_DEVICE_USBHS_DEVICE_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_USBHS_DEVICE_USBHS_DEVICE_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_USBHS_DEVICE_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_USBHS_HOST_USBHS_HOST_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_USBHS_HOST_USBHS_HOST_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_USBHS_HOST_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_USBHS_SRAM_USBHS_SRAM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_USBHS_SRAM_USBHS_SRAM_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_USBHS_SRAM_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_SCT_SCT_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_SCT_SCT_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SCT_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_GPU_GPU_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_GPU_GPU_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_GPU_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_DISPLAY_CONTROLLER_DISPLAY_CONTROLLER_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_DISPLAY_CONTROLLER_DISPLAY_CONTROLLER_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_DISPLAY_CONTROLLER_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_MIPI_DSI_CONTROLLER_MIPI_DSI_CONTROLLER_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_MIPI_DSI_CONTROLLER_MIPI_DSI_CONTROLLER_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_MIPI_DSI_CONTROLLER_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_MIPI_DSI_PHY_MIPI_DSI_PHY_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_MIPI_DSI_PHY_MIPI_DSI_PHY_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_MIPI_DSI_PHY_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL0_SMARTDMA_SMARTDMA_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL0_SMARTDMA_SMARTDMA_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SMARTDMA_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL1_SDIO0_SDIO0_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL1_SDIO0_SDIO0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_SDIO0_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL1_SDIO1_SDIO1_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL1_SDIO1_SDIO1_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_SDIO1_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL1_ACMP0_ACMP0_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL1_ACMP0_ACMP0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_ACMP0_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL1_ADC0_ADC0_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL1_ADC0_ADC0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_ADC0_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL1_SHSGPIO0_SHSGPIO0_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL1_SHSGPIO0_SHSGPIO0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_SHSGPIO0_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL2_UTICK0_UTICK0_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL2_UTICK0_UTICK0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL2_UTICK0_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL0_PRSTCTL2_WWDT0_WWDT0_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL0_PRSTCTL2_WWDT0_WWDT0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL2_WWDT0_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_DSP_DSP_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_DSP_DSP_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_DSP_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_AXI_SWITCH_AXI_SWITCH_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_AXI_SWITCH_AXI_SWITCH_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_AXI_SWITCH_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_POWERQUAD_POWERQUAD_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_POWERQUAD_POWERQUAD_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_POWERQUAD_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_CASPER_CASPER_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_CASPER_CASPER_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_CASPER_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_HASHCRYPT_HASHCRYPT_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_HASHCRYPT_HASHCRYPT_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_HASHCRYPT_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_PUF_PUF_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_PUF_PUF_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_PUF_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_RNG_RNG_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_RNG_RNG_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_RNG_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_FLEXSPI0_OTFAD_FLEXSPI0_OTFAD_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_FLEXSPI0_OTFAD_FLEXSPI0_OTFAD_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_FLEXSPI0_OTFAD_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_FLEXSPI1_FLEXSPI1_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_FLEXSPI1_FLEXSPI1_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_FLEXSPI1_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_USBHS_PHY_USBHS_PHY_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_USBHS_PHY_USBHS_PHY_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_USBHS_PHY_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_USBHS_DEVICE_USBHS_DEVICE_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_USBHS_DEVICE_USBHS_DEVICE_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_USBHS_DEVICE_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_USBHS_HOST_USBHS_HOST_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_USBHS_HOST_USBHS_HOST_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_USBHS_HOST_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_USBHS_SRAM_USBHS_SRAM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_USBHS_SRAM_USBHS_SRAM_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_USBHS_SRAM_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_SCT_SCT_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_SCT_SCT_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_SCT_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_GPU_GPU_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_GPU_GPU_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_GPU_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_DISPLAY_CONTROLLER_DISPLAY_CONTROLLER_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_DISPLAY_CONTROLLER_DISPLAY_CONTROLLER_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_DISPLAY_CONTROLLER_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_MIPI_DSI_CONTROLLER_MIPI_DSI_CONTROLLER_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_MIPI_DSI_CONTROLLER_MIPI_DSI_CONTROLLER_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_MIPI_DSI_CONTROLLER_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_MIPI_DSI_PHY_MIPI_DSI_PHY_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_MIPI_DSI_PHY_MIPI_DSI_PHY_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_MIPI_DSI_PHY_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL0_PRSTCTL0_SET_SMARTDMA_SMARTDMA_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_SET_SMARTDMA_SMARTDMA_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_SET_SMARTDMA_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL1_SET_SDIO0_SDIO0_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL0_PRSTCTL1_SET_SDIO0_SDIO0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_SET_SDIO0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL1_SET_SDIO1_SDIO1_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL0_PRSTCTL1_SET_SDIO1_SDIO1_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_SET_SDIO1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL1_SET_ACMP0_ACMP0_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL0_PRSTCTL1_SET_ACMP0_ACMP0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_SET_ACMP0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL1_SET_ADC0_ADC0_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL0_PRSTCTL1_SET_ADC0_ADC0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_SET_ADC0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL1_SET_SHSGPIO0_SHSGPIO0_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL0_PRSTCTL1_SET_SHSGPIO0_SHSGPIO0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_SET_SHSGPIO0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL2_SET_UTICK0_UTICK0_CLR = 0,
+ /* Sets the PRSTCTL2 Bit */
+ RT500_RSTCTL0_PRSTCTL2_SET_UTICK0_UTICK0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL2_SET_UTICK0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL2_SET_WWDT0_WWDT0_CLR = 0,
+ /* Sets the PRSTCTL2 Bit */
+ RT500_RSTCTL0_PRSTCTL2_SET_WWDT0_WWDT0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL2_SET_WWDT0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_DSP_DSP_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_DSP_DSP_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_DSP_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_AXI_SWITCH_AXI_SWITCH_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_AXI_SWITCH_AXI_SWITCH_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_AXI_SWITCH_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_POWERQUAD_POWERQUAD_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_POWERQUAD_POWERQUAD_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_POWERQUAD_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_CASPER_CASPER_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_CASPER_CASPER_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_CASPER_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_HASHCRYPT_HASHCRYPT_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_HASHCRYPT_HASHCRYPT_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_HASHCRYPT_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_PUF_PUF_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_PUF_PUF_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_PUF_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_RNG_RNG_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_RNG_RNG_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_RNG_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_FLEXSPI0_OTFAD_FLEXSPI0_OTFAD_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_FLEXSPI0_OTFAD_FLEXSPI0_OTFAD_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_FLEXSPI0_OTFAD_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_FLEXSPI1_FLEXSPI1_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_FLEXSPI1_FLEXSPI1_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_FLEXSPI1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_USBHS_PHY_USBHS_PHY_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_USBHS_PHY_USBHS_PHY_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_USBHS_PHY_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_USBHS_DEVICE_USBHS_DEVICE_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_USBHS_DEVICE_USBHS_DEVICE_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_USBHS_DEVICE_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_USBHS_HOST_USBHS_HOST_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_USBHS_HOST_USBHS_HOST_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_USBHS_HOST_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_USBHS_SRAM_USBHS_SRAM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_USBHS_SRAM_USBHS_SRAM_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_USBHS_SRAM_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_SCT_SCT_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_SCT_SCT_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_SCT_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_GPU_GPU_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_GPU_GPU_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_GPU_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_DISPLAY_CONTROLLER_DISPLAY_CONTROLLER_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_DISPLAY_CONTROLLER_DISPLAY_CONTROLLER_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_DISPLAY_CONTROLLER_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_MIPI_DSI_CONTROLLER_MIPI_DSI_CONTROLLER_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_MIPI_DSI_CONTROLLER_MIPI_DSI_CONTROLLER_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_MIPI_DSI_CONTROLLER_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_MIPI_DSI_PHY_MIPI_DSI_PHY_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_MIPI_DSI_PHY_MIPI_DSI_PHY_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_MIPI_DSI_PHY_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL0_CLR_SMARTDMA_SMARTDMA_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL0_PRSTCTL0_CLR_SMARTDMA_SMARTDMA_SET = 1,
+} RT500_RSTCTL0_PRSTCTL0_CLR_SMARTDMA_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL1_CLR_SDIO0_SDIO0_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL0_PRSTCTL1_CLR_SDIO0_SDIO0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_CLR_SDIO0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL1_CLR_SDIO1_SDIO1_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL0_PRSTCTL1_CLR_SDIO1_SDIO1_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_CLR_SDIO1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL1_CLR_ACMP0_ACMP0_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL0_PRSTCTL1_CLR_ACMP0_ACMP0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_CLR_ACMP0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL1_CLR_ADC0_ADC0_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL0_PRSTCTL1_CLR_ADC0_ADC0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_CLR_ADC0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL1_CLR_SHSGPIO0_SHSGPIO0_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL0_PRSTCTL1_CLR_SHSGPIO0_SHSGPIO0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL1_CLR_SHSGPIO0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL2_CLR_UTICK0_UTICK0_CLR = 0,
+ /* Clears the PRSTCTL2 Bit */
+ RT500_RSTCTL0_PRSTCTL2_CLR_UTICK0_UTICK0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL2_CLR_UTICK0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL0_PRSTCTL2_CLR_WWDT0_WWDT0_CLR = 0,
+ /* Clears the PRSTCTL2 Bit */
+ RT500_RSTCTL0_PRSTCTL2_CLR_WWDT0_WWDT0_SET = 1,
+} RT500_RSTCTL0_PRSTCTL2_CLR_WWDT0_Enum;
+
+
+#define RT500_RSTCTL0_REGISTER_ACCESS_INFO_ARRAY(_name) \
+ struct RegisterAccessInfo _name[RT500_RSTCTL0_REGS_NO] = { \
+ [0 ... RT500_RSTCTL0_REGS_NO - 1] = { \
+ .name = "", \
+ .addr = -1, \
+ }, \
+ [R_RT500_RSTCTL0_SYSRSTSTAT] = { \
+ .name = "SYSRSTSTAT", \
+ .addr = 0x0, \
+ .ro = 0xFFFFFF0E, \
+ .reset = 0x1, \
+ }, \
+ [R_RT500_RSTCTL0_PRSTCTL0] = { \
+ .name = "PRSTCTL0", \
+ .addr = 0x10, \
+ .ro = 0x820AE0F5, \
+ .reset = 0x7DF51F0A, \
+ }, \
+ [R_RT500_RSTCTL0_PRSTCTL1] = { \
+ .name = "PRSTCTL1", \
+ .addr = 0x14, \
+ .ro = 0xFEFE7FF3, \
+ .reset = 0x101800C, \
+ }, \
+ [R_RT500_RSTCTL0_PRSTCTL2] = { \
+ .name = "PRSTCTL2", \
+ .addr = 0x18, \
+ .ro = 0xFFFFFFFC, \
+ .reset = 0x1C000001, \
+ }, \
+ [R_RT500_RSTCTL0_PRSTCTL0_SET] = { \
+ .name = "PRSTCTL0_SET", \
+ .addr = 0x40, \
+ .ro = 0x820AE0F5, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_RSTCTL0_PRSTCTL1_SET] = { \
+ .name = "PRSTCTL1_SET", \
+ .addr = 0x44, \
+ .ro = 0xFEFE7FF3, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_RSTCTL0_PRSTCTL2_SET] = { \
+ .name = "PRSTCTL2_SET", \
+ .addr = 0x48, \
+ .ro = 0xFFFFFFFC, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_RSTCTL0_PRSTCTL0_CLR] = { \
+ .name = "PRSTCTL0_CLR", \
+ .addr = 0x70, \
+ .ro = 0x820AE0F5, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_RSTCTL0_PRSTCTL1_CLR] = { \
+ .name = "PRSTCTL1_CLR", \
+ .addr = 0x74, \
+ .ro = 0xFEFE7FF3, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_RSTCTL0_PRSTCTL2_CLR] = { \
+ .name = "PRSTCTL2_CLR", \
+ .addr = 0x78, \
+ .ro = 0xFFFFFFFC, \
+ .reset = 0x0, \
+ }, \
+ }
diff --git a/include/hw/arm/svd/rt500_rstctl1.h b/include/hw/arm/svd/rt500_rstctl1.h
new file mode 100644
index 0000000000..6b331c653f
--- /dev/null
+++ b/include/hw/arm/svd/rt500_rstctl1.h
@@ -0,0 +1,1371 @@
+/*
+ * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
+ */
+#pragma once
+
+#include "hw/register.h"
+
+/* Reset Controller 1 */
+#define RT500_RSTCTL1_REGS_NO (31)
+
+/* System Reset Status Register */
+REG32(RT500_RSTCTL1_SYSRSTSTAT, 0);
+/* VDD Power-On Reset (POR) was detected */
+FIELD(RT500_RSTCTL1_SYSRSTSTAT, VDD_POR, 0, 1);
+/* RESETN pin reset was detected */
+FIELD(RT500_RSTCTL1_SYSRSTSTAT, PAD_RESET, 4, 1);
+/* ARM reset was detected */
+FIELD(RT500_RSTCTL1_SYSRSTSTAT, ARM_RESET, 5, 1);
+/* WDT0 reset was detected */
+FIELD(RT500_RSTCTL1_SYSRSTSTAT, WDT0_RESET, 6, 1);
+/* WDT1 reset was detected */
+FIELD(RT500_RSTCTL1_SYSRSTSTAT, WDT1_RESET, 7, 1);
+
+/* Peripheral Reset Control Register 0 */
+REG32(RT500_RSTCTL1_PRSTCTL0, 16);
+/* Flexcomm0 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM0, 8, 1);
+/* Flexcomm1 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM1, 9, 1);
+/* Flexcomm2 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM2, 10, 1);
+/* Flexcomm3 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM3, 11, 1);
+/* Flexcomm4 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM4, 12, 1);
+/* Flexcomm5 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM5, 13, 1);
+/* Flexcomm6 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM6, 14, 1);
+/* Flexcomm7 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM7, 15, 1);
+/* Flexcomm8 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM8, 16, 1);
+/* Flexcomm9 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM9, 17, 1);
+/* Flexcomm10 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM10, 18, 1);
+/* Flexcomm11 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM11, 19, 1);
+/* Flexcomm12 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM12, 20, 1);
+/* Flexcomm13 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM13, 21, 1);
+/* Flexcomm14 SPI0 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM14, 22, 1);
+/* Flexcomm15 I2C reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM15_I2C, 23, 1);
+/* DMIC0 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, DMIC0, 24, 1);
+/* Flexcomm SPI reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXCOMM16, 25, 1);
+/* OSEVENT Timer reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, OSEVENT_TIMER, 27, 1);
+/* FLEXIO reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL0, FLEXIO, 29, 1);
+
+/* Peripheral Reset Control Register 1 */
+REG32(RT500_RSTCTL1_PRSTCTL1, 20);
+/* HSGPIO[7:0] reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, HSGPIO0, 0, 1);
+/* HSGPIO[7:0] reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, HSGPIO1, 1, 1);
+/* HSGPIO[7:0] reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, HSGPIO2, 2, 1);
+/* HSGPIO[7:0] reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, HSGPIO3, 3, 1);
+/* HSGPIO[7:0] reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, HSGPIO4, 4, 1);
+/* HSGPIO[7:0] reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, HSGPIO5, 5, 1);
+/* HSGPIO[7:0] reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, HSGPIO6, 6, 1);
+/* HSGPIO[7:0] reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, HSGPIO7, 7, 1);
+/* CRC reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, CRC, 16, 1);
+/* DMAC reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, DMAC0, 23, 1);
+/* DMAC reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, DMAC1, 24, 1);
+/* MU reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, MU, 28, 1);
+/* SEMA reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, SEMA, 29, 1);
+/* FREQME reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL1, FREQME, 31, 1);
+
+/* Peripheral Reset Control Register 2 */
+REG32(RT500_RSTCTL1_PRSTCTL2, 24);
+/* CT32BIT[4:0] reset */
+FIELD(RT500_RSTCTL1_PRSTCTL2, CT32BIT0, 0, 1);
+/* CT32BIT[4:0] reset */
+FIELD(RT500_RSTCTL1_PRSTCTL2, CT32BIT1, 1, 1);
+/* CT32BIT[4:0] reset */
+FIELD(RT500_RSTCTL1_PRSTCTL2, CT32BIT2, 2, 1);
+/* CT32BIT[4:0] reset */
+FIELD(RT500_RSTCTL1_PRSTCTL2, CT32BIT3, 3, 1);
+/* CT32BIT[4:0] reset */
+FIELD(RT500_RSTCTL1_PRSTCTL2, CT32BIT4, 4, 1);
+/* MRT0 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL2, MRT0, 8, 1);
+/* WWDT1 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL2, WWDT1, 10, 1);
+/* I3C0 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL2, I3C0, 16, 1);
+/* I3C1 reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL2, I3C1, 17, 1);
+/* GPIOINTCTL reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL2, GPIOINTCTL, 30, 1);
+/* INPUTMUX reset control */
+FIELD(RT500_RSTCTL1_PRSTCTL2, PIMCTL, 31, 1);
+
+/* Peripheral Reset Control Register 0 SET */
+REG32(RT500_RSTCTL1_PRSTCTL0_SET, 64);
+/* Flexcomm0 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM0, 8, 1);
+/* Flexcomm1 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM1, 9, 1);
+/* Flexcomm2 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM2, 10, 1);
+/* Flexcomm3 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM3, 11, 1);
+/* Flexcomm4 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM4, 12, 1);
+/* Flexcomm5 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM5, 13, 1);
+/* Flexcomm6 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM6, 14, 1);
+/* Flexcomm7 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM7, 15, 1);
+/* Flexcomm8 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM8, 16, 1);
+/* Flexcomm9 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM9, 17, 1);
+/* Flexcomm10 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM10, 18, 1);
+/* Flexcomm11 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM11, 19, 1);
+/* Flexcomm12 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM12, 20, 1);
+/* Flexcomm13 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM13, 21, 1);
+/* Flexcomm14 SPI0 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM14, 22, 1);
+/* Flexcomm15 I2C reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM15_I2C, 23, 1);
+/* DMIC0 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, DMIC0, 24, 1);
+/* Flexcomm16 SPI1 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXCOMM16, 25, 1);
+/* OSEVENT Timer reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, OSEVENT_TIMER, 27, 1);
+/* FEXIO reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL0_SET, FLEXIO, 29, 1);
+
+/* Peripheral Reset Control Register 1 SET */
+REG32(RT500_RSTCTL1_PRSTCTL1_SET, 68);
+/* HSGPIO0 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, HSGPIO0, 0, 1);
+/* HSGPIO1 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, HSGPIO1, 1, 1);
+/* HSGPIO2 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, HSGPIO2, 2, 1);
+/* HSGPIO3 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, HSGPIO3, 3, 1);
+/* HSGPIO4 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, HSGPIO4, 4, 1);
+/* HSGPIO5 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, HSGPIO5, 5, 1);
+/* HSGPIO6 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, HSGPIO6, 6, 1);
+/* HSGPIO7 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, HSGPIO7, 7, 1);
+/* CRC reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, CRC, 16, 1);
+/* DMAC0 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, DMAC0, 23, 1);
+/* DMAC1 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, DMAC1, 24, 1);
+/* MU reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, MU, 28, 1);
+/* SEMA reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, SEMA, 29, 1);
+/* FREQME reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL1_SET, FREQME, 31, 1);
+
+/* Peripheral Reset Control Register 2 SET */
+REG32(RT500_RSTCTL1_PRSTCTL2_SET, 72);
+/* CT32BIT0 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL2_SET, CT32BIT0, 0, 1);
+/* CT32BIT1 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL2_SET, CT32BIT1, 1, 1);
+/* CT32BIT2 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL2_SET, CT32BIT2, 2, 1);
+/* CT32BIT3 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL2_SET, CT32BIT3, 3, 1);
+/* CT32BIT4 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL2_SET, CT32BIT4, 4, 1);
+/* MRT0 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL2_SET, MRT0, 8, 1);
+/* WWDT1 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL2_SET, WWDT1, 10, 1);
+/* I3C0 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL2_SET, I3C0, 16, 1);
+/* I3C1 reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL2_SET, I3C1, 17, 1);
+/* GPIOINTCTL reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL2_SET, GPIOINTCTL, 30, 1);
+/* PIMCTL reset set */
+FIELD(RT500_RSTCTL1_PRSTCTL2_SET, PIMCTL, 31, 1);
+
+/* Peripheral Reset Control Register 0 CLR */
+REG32(RT500_RSTCTL1_PRSTCTL0_CLR, 112);
+/* Flexcomm0 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM0, 8, 1);
+/* Flexcomm1 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM1, 9, 1);
+/* Flexcomm2 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM2, 10, 1);
+/* Flexcomm3 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM3, 11, 1);
+/* Flexcomm4 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM4, 12, 1);
+/* Flexcomm5 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM5, 13, 1);
+/* Flexcomm6 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM6, 14, 1);
+/* Flexcomm7 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM7, 15, 1);
+/* Flexcomm8 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM8, 16, 1);
+/* Flexcomm9 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM9, 17, 1);
+/* Flexcomm10 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM10, 18, 1);
+/* Flexcomm11 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM11, 19, 1);
+/* Flexcomm12 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM12, 20, 1);
+/* Flexcomm13 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM13, 21, 1);
+/* FLexcomm SPI0 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM14, 22, 1);
+/* Flexcomm I2C reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM15_I2C, 23, 1);
+/* DMIC0 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, DMIC0, 24, 1);
+/* Flexcomm SPI1 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXCOMM16, 25, 1);
+/* OSEVENT Timer reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, OSEVENT_TIMER, 27, 1);
+/* FLEXIO reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL0_CLR, FLEXIO, 29, 1);
+
+/* Peripheral Reset Control Register 1 CLR */
+REG32(RT500_RSTCTL1_PRSTCTL1_CLR, 116);
+/* HSGPIO0 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, HSGPIO0, 0, 1);
+/* HSGPIO1 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, HSGPIO1, 1, 1);
+/* HSGPIO2 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, HSGPIO2, 2, 1);
+/* HSGPIO3 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, HSGPIO3, 3, 1);
+/* HSGPIO4 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, HSGPIO4, 4, 1);
+/* HSGPIO5 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, HSGPIO5, 5, 1);
+/* HSGPIO6 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, HSGPIO6, 6, 1);
+/* HSGPIO7 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, HSGPIO7, 7, 1);
+/* CRC reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, CRC, 16, 1);
+/* DMAC0 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, DMAC0, 23, 1);
+/* DMAC1 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, DMAC1, 24, 1);
+/* MU reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, MU, 28, 1);
+/* SMEA reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, SEMA, 29, 1);
+/* FREQME reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL1_CLR, FREQME, 31, 1);
+
+/* Peripheral Reset Control Register 2 CLR */
+REG32(RT500_RSTCTL1_PRSTCTL2_CLR, 120);
+/* CT32BIT0 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL2_CLR, CT32BIT0, 0, 1);
+/* CT32BIT1 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL2_CLR, CT32BIT1, 1, 1);
+/* CT32BIT2 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL2_CLR, CT32BIT2, 2, 1);
+/* CT32BIT3 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL2_CLR, CT32BIT3, 3, 1);
+/* CT32BIT4 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL2_CLR, CT32BIT4, 4, 1);
+/* MRT0 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL2_CLR, MRT0, 8, 1);
+/* WWDT1 reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL2_CLR, WWDT1, 10, 1);
+/* I3C[1:0] reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL2_CLR, I3C0, 16, 1);
+/* I3C[1:0] reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL2_CLR, I3C1, 17, 1);
+/* GPIOINTCTL reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL2_CLR, GPIOINTCTL, 30, 1);
+/* PIMCTL reset clear */
+FIELD(RT500_RSTCTL1_PRSTCTL2_CLR, PIMCTL, 31, 1);
+
+
+typedef enum {
+ /* No VDD POR event is detected */
+ RT500_RSTCTL1_SYSRSTSTAT_VDD_POR_VDD_POR_EVENT_IS_NOT_DETECTED = 0,
+ /* VDD POR event was detected */
+ RT500_RSTCTL1_SYSRSTSTAT_VDD_POR_VDD_POR_EVENT_WAS_DETECTED = 1,
+} RT500_RSTCTL1_SYSRSTSTAT_VDD_POR_Enum;
+
+typedef enum {
+ /* No RESETN pin event is detected */
+ RT500_RSTCTL1_SYSRSTSTAT_PAD_RESET_PAD_RESET_IS_NOT_DETECTED = 0,
+ /* RESETN pin reset event was detected */
+ RT500_RSTCTL1_SYSRSTSTAT_PAD_RESET_PAD_RESET_WAS_DETECTED = 1,
+} RT500_RSTCTL1_SYSRSTSTAT_PAD_RESET_Enum;
+
+typedef enum {
+ /* No ARM reset event is detected */
+ RT500_RSTCTL1_SYSRSTSTAT_ARM_RESET_ARM_RESET_IS_NOT_DETECTED = 0,
+ /* ARM reset was detected */
+ RT500_RSTCTL1_SYSRSTSTAT_ARM_RESET_ARM_RESET_WAS_DETECTED = 1,
+} RT500_RSTCTL1_SYSRSTSTAT_ARM_RESET_Enum;
+
+typedef enum {
+ /* No WDT0 reset event is detected */
+ RT500_RSTCTL1_SYSRSTSTAT_WDT0_RESET_WDT0_RESET_IS_NOT_DETECTED = 0,
+ /* WDT0 reset was detected */
+ RT500_RSTCTL1_SYSRSTSTAT_WDT0_RESET_WDT0_RESET_WAS_DETECTED = 1,
+} RT500_RSTCTL1_SYSRSTSTAT_WDT0_RESET_Enum;
+
+typedef enum {
+ /* No WDT1 reset event is detected */
+ RT500_RSTCTL1_SYSRSTSTAT_WDT1_RESET_WDT1_RESET_IS_NOT_DETECTED = 0,
+ /* WDT1 reset was detected */
+ RT500_RSTCTL1_SYSRSTSTAT_WDT1_RESET_WDT1_RESET_WAS_DETECTED = 1,
+} RT500_RSTCTL1_SYSRSTSTAT_WDT1_RESET_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM0_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM0_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM0_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM1_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM1_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM1_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM2_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM2_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM2_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM3_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM3_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM3_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM4_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM4_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM4_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM5_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM5_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM5_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM6_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM6_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM6_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM7_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM7_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM7_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM8_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM8_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM8_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM9_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM9_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM9_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM10_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM10_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM10_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM11_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM11_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM11_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM12_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM12_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM12_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM13_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM13_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM13_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM14_FLEXCOMM_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM14_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM14_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM15_I2C_FLEXCOMM15_I2C_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM15_I2C_FLEXCOMM15_I2C_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM15_I2C_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_DMIC0_DMIC0_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_DMIC0_DMIC0_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_DMIC0_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM16_FLEXCOMM16_SPI1_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXCOMM16_FLEXCOMM16_SPI1_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXCOMM16_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_OSEVENT_TIMER_OSEVENT_TIMER_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_OSEVENT_TIMER_OSEVENT_TIMER_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_OSEVENT_TIMER_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXIO_FLEXIO_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL0_FLEXIO_FLEXIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_FLEXIO_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO0_HSGPIO_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO0_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_HSGPIO0_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO1_HSGPIO_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO1_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_HSGPIO1_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO2_HSGPIO_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO2_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_HSGPIO2_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO3_HSGPIO_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO3_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_HSGPIO3_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO4_HSGPIO_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO4_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_HSGPIO4_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO5_HSGPIO_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO5_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_HSGPIO5_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO6_HSGPIO_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO6_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_HSGPIO6_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO7_HSGPIO_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_HSGPIO7_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_HSGPIO7_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_CRC_CRC_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_CRC_CRC_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CRC_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_DMAC0_DMAC_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_DMAC0_DMAC_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_DMAC0_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_DMAC1_DMAC_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_DMAC1_DMAC_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_DMAC1_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_MU_MU_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_MU_MU_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_MU_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_SEMA_SEMA_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_SEMA_SEMA_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SEMA_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL1_FREQME_FREQME_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL1_FREQME_FREQME_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_FREQME_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL2_CT32BIT0_CT32BIT_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL2_CT32BIT0_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CT32BIT0_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL2_CT32BIT1_CT32BIT_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL2_CT32BIT1_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CT32BIT1_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL2_CT32BIT2_CT32BIT_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL2_CT32BIT2_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CT32BIT2_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL2_CT32BIT3_CT32BIT_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL2_CT32BIT3_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CT32BIT3_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL2_CT32BIT4_CT32BIT_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL2_CT32BIT4_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CT32BIT4_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL2_MRT0_MRT0_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL2_MRT0_MRT0_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_MRT0_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL2_WWDT1_WWDT1_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL2_WWDT1_WWDT1_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_WWDT1_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL2_I3C0_I3C_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL2_I3C0_I3C_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_I3C0_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL2_I3C1_I3C_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL2_I3C1_I3C_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_I3C1_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL2_GPIOINTCTL_GPIOINTCTL_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL2_GPIOINTCTL_GPIOINTCTL_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_GPIOINTCTL_Enum;
+
+typedef enum {
+ /* Clear Reset */
+ RT500_RSTCTL1_PRSTCTL2_PIMCTL_PIMCTL_CLR = 0,
+ /* Set Reset */
+ RT500_RSTCTL1_PRSTCTL2_PIMCTL_PIMCTL_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_PIMCTL_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM0_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM0_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM0_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM1_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM1_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM1_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM2_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM2_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM2_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM3_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM3_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM3_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM4_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM4_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM4_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM5_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM5_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM5_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM6_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM6_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM6_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM7_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM7_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM7_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM8_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM8_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM8_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM9_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM9_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM9_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM10_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM10_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM10_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM11_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM11_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM11_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM12_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM12_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM12_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM13_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM13_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM13_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM14_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM14_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM14_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM15_I2C_FLEXCOMM15_I2C_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM15_I2C_FLEXCOMM15_I2C_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM15_I2C_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_DMIC0_FLEXCOMM_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_DMIC0_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_DMIC0_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM16_FLEXCOMM16_SPI1_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM16_FLEXCOMM16_SPI1_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXCOMM16_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_OSEVENT_TIMER_OSEVENT_TIMER_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_OSEVENT_TIMER_OSEVENT_TIMER_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_OSEVENT_TIMER_Enum;
+
+typedef enum {
+ /* No Effect */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXIO_FLEXIO_CLR = 0,
+ /* Sets the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_SET_FLEXIO_FLEXIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_SET_FLEXIO_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO0_HSGPIO_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO0_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO1_HSGPIO_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO1_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO2_HSGPIO_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO2_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO2_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO3_HSGPIO_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO3_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO3_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO4_HSGPIO_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO4_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO4_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO5_HSGPIO_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO5_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO5_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO6_HSGPIO_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO6_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO6_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO7_HSGPIO_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO7_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_HSGPIO7_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_CRC_CRC_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_CRC_CRC_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_CRC_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_DMAC0_DMAC_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_DMAC0_DMAC_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_DMAC0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_DMAC1_DMAC_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_DMAC1_DMAC_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_DMAC1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_MU_MU_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_MU_MU_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_MU_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_SEMA_SEMA_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_SEMA_SEMA_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_SEMA_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_SET_FREQME_FREQME_CLR = 0,
+ /* Sets the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_SET_FREQME_FREQME_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_SET_FREQME_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT0_CT32BIT_CLR = 0,
+ /* Sets the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT0_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT1_CT32BIT_CLR = 0,
+ /* Sets the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT1_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT2_CT32BIT_CLR = 0,
+ /* Sets the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT2_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT2_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT3_CT32BIT_CLR = 0,
+ /* Sets the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT3_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT3_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT4_CT32BIT_CLR = 0,
+ /* Sets the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT4_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_SET_CT32BIT4_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_SET_MRT0_MRT0_CLR = 0,
+ /* Sets the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_SET_MRT0_MRT0_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_SET_MRT0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_SET_WWDT1_WWDT1_CLR = 0,
+ /* Sets the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_SET_WWDT1_WWDT1_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_SET_WWDT1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_SET_I3C0_I3C_CLR = 0,
+ /* Sets the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_SET_I3C0_I3C_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_SET_I3C0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_SET_I3C1_I3C_CLR = 0,
+ /* Sets the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_SET_I3C1_I3C_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_SET_I3C1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_SET_GPIOINTCTL_GPIOINTCTL_CLR = 0,
+ /* Sets the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_SET_GPIOINTCTL_GPIOINTCTL_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_SET_GPIOINTCTL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_SET_PIMCTL_PIMCTL_CLR = 0,
+ /* Sets the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_SET_PIMCTL_PIMCTL_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_SET_PIMCTL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM0_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM0_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM1_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM1_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM2_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM2_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM2_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM3_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM3_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM3_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM4_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM4_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM4_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM5_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM5_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM5_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM6_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM6_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM6_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM7_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM7_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM7_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM8_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM8_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM8_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM9_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM9_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM9_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM10_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM10_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM10_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM11_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM11_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM11_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM12_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM12_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM12_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM13_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM13_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM13_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM14_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM14_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM14_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM15_I2C_FLEXCOMM15_I2C_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM15_I2C_FLEXCOMM15_I2C_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM15_I2C_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_DMIC0_FLEXCOMM_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_DMIC0_FLEXCOMM_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_DMIC0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM16_FLEXCOMM16_SPI1_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM16_FLEXCOMM16_SPI1_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXCOMM16_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_OSEVENT_TIMER_OSEVENT_TIMER_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_OSEVENT_TIMER_OSEVENT_TIMER_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_OSEVENT_TIMER_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXIO_FLEXIO_CLR = 0,
+ /* Clears the PRSTCTL0 Bit */
+ RT500_RSTCTL1_PRSTCTL0_CLR_FLEXIO_FLEXIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL0_CLR_FLEXIO_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO0_HSGPIO_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO0_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO1_HSGPIO_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO1_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO2_HSGPIO_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO2_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO2_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO3_HSGPIO_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO3_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO3_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO4_HSGPIO_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO4_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO4_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO5_HSGPIO_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO5_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO5_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO6_HSGPIO_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO6_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO6_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO7_HSGPIO_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO7_HSGPIO_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_HSGPIO7_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_CRC_CRC_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_CRC_CRC_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_CRC_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_DMAC0_DMAC_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_DMAC0_DMAC_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_DMAC0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_DMAC1_DMAC_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_DMAC1_DMAC_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_DMAC1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_MU_MU_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_MU_MU_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_MU_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_SEMA_SEMA_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_SEMA_SEMA_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_SEMA_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL1_CLR_FREQME_FREQME_CLR = 0,
+ /* Clears the PRSTCTL1 Bit */
+ RT500_RSTCTL1_PRSTCTL1_CLR_FREQME_FREQME_SET = 1,
+} RT500_RSTCTL1_PRSTCTL1_CLR_FREQME_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT0_CT32BIT_CLR = 0,
+ /* Clears the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT0_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT1_CT32BIT_CLR = 0,
+ /* Clears the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT1_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT2_CT32BIT_CLR = 0,
+ /* Clears the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT2_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT2_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT3_CT32BIT_CLR = 0,
+ /* Clears the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT3_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT3_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT4_CT32BIT_CLR = 0,
+ /* Clears the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT4_CT32BIT_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CLR_CT32BIT4_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_CLR_MRT0_MRT0_CLR = 0,
+ /* Clears the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_CLR_MRT0_MRT0_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CLR_MRT0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_CLR_WWDT1_WWDT1_CLR = 0,
+ /* Clears the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_CLR_WWDT1_WWDT1_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CLR_WWDT1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_CLR_I3C0_I3C_CLR = 0,
+ /* Clears the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_CLR_I3C0_I3C_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CLR_I3C0_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_CLR_I3C1_I3C_CLR = 0,
+ /* Clears the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_CLR_I3C1_I3C_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CLR_I3C1_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_CLR_GPIOINTCTL_GPIOINTCTL_CLR = 0,
+ /* Clears the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_CLR_GPIOINTCTL_GPIOINTCTL_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CLR_GPIOINTCTL_Enum;
+
+typedef enum {
+ /* No effect */
+ RT500_RSTCTL1_PRSTCTL2_CLR_PIMCTL_PIMCTL_CLR = 0,
+ /* Clears the PRSTCTL2 Bit */
+ RT500_RSTCTL1_PRSTCTL2_CLR_PIMCTL_PIMCTL_SET = 1,
+} RT500_RSTCTL1_PRSTCTL2_CLR_PIMCTL_Enum;
+
+
+#define RT500_RSTCTL1_REGISTER_ACCESS_INFO_ARRAY(_name) \
+ struct RegisterAccessInfo _name[RT500_RSTCTL1_REGS_NO] = { \
+ [0 ... RT500_RSTCTL1_REGS_NO - 1] = { \
+ .name = "", \
+ .addr = -1, \
+ }, \
+ [R_RT500_RSTCTL1_SYSRSTSTAT] = { \
+ .name = "SYSRSTSTAT", \
+ .addr = 0x0, \
+ .ro = 0xFFFFFFFF, \
+ .reset = 0x1, \
+ }, \
+ [R_RT500_RSTCTL1_PRSTCTL0] = { \
+ .name = "PRSTCTL0", \
+ .addr = 0x10, \
+ .ro = 0xD40000FF, \
+ .reset = 0x1C0FF00, \
+ }, \
+ [R_RT500_RSTCTL1_PRSTCTL1] = { \
+ .name = "PRSTCTL1", \
+ .addr = 0x14, \
+ .ro = 0x4E7EFF00, \
+ .reset = 0xB18100FF, \
+ }, \
+ [R_RT500_RSTCTL1_PRSTCTL2] = { \
+ .name = "PRSTCTL2", \
+ .addr = 0x18, \
+ .ro = 0x3FFCFAE0, \
+ .reset = 0xC001011F, \
+ }, \
+ [R_RT500_RSTCTL1_PRSTCTL0_SET] = { \
+ .name = "PRSTCTL0_SET", \
+ .addr = 0x40, \
+ .ro = 0xD40000FF, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_RSTCTL1_PRSTCTL1_SET] = { \
+ .name = "PRSTCTL1_SET", \
+ .addr = 0x44, \
+ .ro = 0x4E7EFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_RSTCTL1_PRSTCTL2_SET] = { \
+ .name = "PRSTCTL2_SET", \
+ .addr = 0x48, \
+ .ro = 0x3FFCFAE0, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_RSTCTL1_PRSTCTL0_CLR] = { \
+ .name = "PRSTCTL0_CLR", \
+ .addr = 0x70, \
+ .ro = 0xD40000FF, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_RSTCTL1_PRSTCTL1_CLR] = { \
+ .name = "PRSTCTL1_CLR", \
+ .addr = 0x74, \
+ .ro = 0x4E7EFF00, \
+ .reset = 0x0, \
+ }, \
+ [R_RT500_RSTCTL1_PRSTCTL2_CLR] = { \
+ .name = "PRSTCTL2_CLR", \
+ .addr = 0x78, \
+ .ro = 0x3FFCFAE0, \
+ .reset = 0x0, \
+ }, \
+ }
diff --git a/include/hw/misc/rt500_rstctl.h b/include/hw/misc/rt500_rstctl.h
new file mode 100644
index 0000000000..ae7e304b2e
--- /dev/null
+++ b/include/hw/misc/rt500_rstctl.h
@@ -0,0 +1,32 @@
+/*
+ * QEMU model for RT500 Reset Controller
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_MISC_RT500_RSTCTL_H
+#define HW_MISC_RT500_RSTCTL_H
+
+#include "hw/arm/svd/rt500_rstctl0.h"
+#include "hw/arm/svd/rt500_rstctl1.h"
+#include "hw/sysbus.h"
+
+#define TYPE_RT500_RSTCTL "rt500-rstctl"
+#define RT500_RSTCTL(o) OBJECT_CHECK(RT500RstCtlState, o, TYPE_RT500_RSTCTL)
+
+#define TYPE_RT500_RSTCTL0 "rt500-rstctl0"
+#define TYPE_RT500_RSTCTL1 "rt500-rstctl1"
+
+typedef struct {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+ uint32_t regs[RT500_RSTCTL1_REGS_NO];
+} RT500RstCtlState;
+
+#endif /* HW_MISC_RT500_RSTCTL_H */
diff --git a/hw/misc/rt500_rstctl.c b/hw/misc/rt500_rstctl.c
new file mode 100644
index 0000000000..a6e818c0a0
--- /dev/null
+++ b/hw/misc/rt500_rstctl.c
@@ -0,0 +1,258 @@
+/*
+ * QEMU model for RT500 Reset Controller
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+#include "hw/misc/rt500_rstctl.h"
+
+#include "trace.h"
+
+/*
+ * There are two intances for RSTCTL with the same register names and layout but
+ * with different fields.
+ */
+#define BUILD_BUG_REG_ADDR(reg) \
+ QEMU_BUILD_BUG_ON((int)A_RT500_RSTCTL0_##reg != (int)A_RT500_RSTCTL1_##reg)
+
+#define REG(s, reg) (s->regs[R_RT500_RSTCTL0_##reg])
+#define RF_WR(s, reg, field, val) \
+ ARRAY_FIELD_DP32(s->regs, RT500_RSTCTL0_##reg, field, val)
+#define RF_RD(s, reg, field) \
+ ARRAY_FIELD_EX32(s->regs, RT500_RSTCTL0_##reg, field)
+
+#define RSTCTL_SYSRSTSTAT_WMASK (BITS(7, 4) | BIT(0))
+#define RSTCL0_PRSCTL0_WMASK (BITS(30, 26) | BITS(24, 20) | BIT(18) | \
+ BIT(16) | BITS(12, 8) | BIT(3) | BIT(1))
+#define RSTCL0_PRSCTL1_WMASK (BIT(24) | BITS(16, 15) | BITS(3, 2))
+#define RSTCL0_PRSCTL2_WMASK (BITS(1, 0))
+#define RSTCL1_PRSCTL0_WMASK (BIT(29) | BIT(27) | BITS(25, 8))
+#define RSTCL1_PRSCTL1_WMASK (BIT(31) | BITS(29, 28) | BITS(24, 23) | \
+ BIT(16) | BITS(7, 0))
+#define RSTCL1_PRSCTL2_WMASK (BITS(31, 30) | BITS(17, 16) | BIT(10) | \
+ BIT(8) | BITS(4, 0))
+
+
+/*
+ * The two RSTCLK modules have different write register masks.
+ */
+typedef struct {
+ SysBusDeviceClass parent;
+ const struct RegisterAccessInfo *reg_info;
+ int reg_info_num;
+} RT500RstCtlClass;
+
+#define RT500_RSTCTL_CLASS(klass) \
+ OBJECT_CLASS_CHECK(RT500RstCtlClass, (klass), TYPE_RT500_RSTCTL)
+#define RT500_RSTCTL_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(RT500RstCtlClass, (obj), TYPE_RT500_RSTCTL)
+
+BUILD_BUG_REG_ADDR(SYSRSTSTAT);
+BUILD_BUG_REG_ADDR(PRSTCTL0);
+BUILD_BUG_REG_ADDR(PRSTCTL1);
+BUILD_BUG_REG_ADDR(PRSTCTL2);
+BUILD_BUG_REG_ADDR(PRSTCTL0_SET);
+BUILD_BUG_REG_ADDR(PRSTCTL1_SET);
+BUILD_BUG_REG_ADDR(PRSTCTL2_SET);
+BUILD_BUG_REG_ADDR(PRSTCTL0_CLR);
+BUILD_BUG_REG_ADDR(PRSTCTL1_CLR);
+BUILD_BUG_REG_ADDR(PRSTCTL2_CLR);
+
+static MemTxResult rt500_rstctl_read(void *opaque, hwaddr addr,
+ uint64_t *data, unsigned size,
+ MemTxAttrs attrs)
+{
+ RT500RstCtlState *s = opaque;
+ RT500RstCtlClass *c = RT500_RSTCTL_GET_CLASS(s);
+ const struct RegisterAccessInfo *rai = &c->reg_info[addr / 4];
+ MemTxResult ret = MEMTX_OK;
+
+ switch (addr) {
+ case A_RT500_RSTCTL0_SYSRSTSTAT:
+ case A_RT500_RSTCTL0_PRSTCTL0:
+ case A_RT500_RSTCTL0_PRSTCTL1:
+ case A_RT500_RSTCTL0_PRSTCTL2:
+ *data = s->regs[addr / 4];
+ break;
+ default:
+ ret = MEMTX_ERROR;
+ }
+
+ trace_rt500_rstctl_reg_read(DEVICE(s)->id, rai->name, addr, *data);
+ return ret;
+}
+
+static MemTxResult rt500_rstctl_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size,
+ MemTxAttrs attrs)
+{
+ RT500RstCtlState *s = opaque;
+ RT500RstCtlClass *c = RT500_RSTCTL_GET_CLASS(s);
+ const struct RegisterAccessInfo *rai = &c->reg_info[addr / 4];
+ struct RegisterInfo ri = {
+ .data = &s->regs[addr / 4],
+ .data_size = 4,
+ .access = rai,
+ };
+
+ trace_rt500_rstctl_reg_write(DEVICE(s)->id, rai->name, addr, value);
+
+ switch (addr) {
+ case A_RT500_RSTCTL0_SYSRSTSTAT:
+ {
+ /* write 1 to clear bits */
+ REG(s, SYSRSTSTAT) &= ~value;
+ break;
+ }
+ case A_RT500_RSTCTL0_PRSTCTL0:
+ case A_RT500_RSTCTL0_PRSTCTL1:
+ case A_RT500_RSTCTL0_PRSTCTL2:
+ {
+ register_write(&ri, value, ~0, NULL, false);
+ break;
+ }
+ case A_RT500_RSTCTL0_PRSTCTL0_SET:
+ case A_RT500_RSTCTL0_PRSTCTL1_SET:
+ case A_RT500_RSTCTL0_PRSTCTL2_SET:
+ {
+ uint32_t tmp;
+
+ tmp = A_RT500_RSTCTL0_PRSTCTL0 + (addr - A_RT500_RSTCTL0_PRSTCTL0_SET);
+ s->regs[tmp / 4] |= value;
+ break;
+ }
+ case A_RT500_RSTCTL0_PRSTCTL0_CLR:
+ case A_RT500_RSTCTL0_PRSTCTL1_CLR:
+ case A_RT500_RSTCTL0_PRSTCTL2_CLR:
+ {
+ uint32_t tmp;
+
+ tmp = A_RT500_RSTCTL0_PRSTCTL0 + (addr - A_RT500_RSTCTL0_PRSTCTL0_CLR);
+ s->regs[tmp / 4] &= ~value;
+ break;
+ }
+ }
+
+ return MEMTX_OK;
+}
+
+static const MemoryRegionOps rt500_rstctl_ops = {
+ .read_with_attrs = rt500_rstctl_read,
+ .write_with_attrs = rt500_rstctl_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ .unaligned = false,
+ },
+};
+
+static void rt500_rstctl_reset_enter(Object *obj, ResetType type)
+{
+ RT500RstCtlState *s = RT500_RSTCTL(obj);
+ RT500RstCtlClass *c = RT500_RSTCTL_GET_CLASS(s);
+
+ for (int i = 0; i < c->reg_info_num; i++) {
+ hwaddr addr = c->reg_info[i].addr;
+
+ if (addr != -1) {
+ struct RegisterInfo ri = {
+ .data = &s->regs[addr / 4],
+ .data_size = 4,
+ .access = &c->reg_info[i],
+ };
+
+ register_reset(&ri);
+ }
+ }
+}
+
+static void rt500_rstctl_init(Object *obj)
+{
+ RT500RstCtlState *s = RT500_RSTCTL(obj);
+
+ memory_region_init_io(&s->mmio, obj, &rt500_rstctl_ops, s,
+ TYPE_RT500_RSTCTL, sizeof(s->regs));
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+}
+
+static const VMStateDescription vmstate_rt500_rstcl0 = {
+ .name = "rt500-rstctl0",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(regs, RT500RstCtlState, RT500_RSTCTL0_REGS_NO),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_rt500_rstcl1 = {
+ .name = "rt500-rstctl1",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(regs, RT500RstCtlState, RT500_RSTCTL1_REGS_NO),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void rt500_rstctl0_class_init(ObjectClass *klass, void *data)
+{
+ RT500RstCtlClass *rc = RT500_RSTCTL_CLASS(klass);
+ static const RT500_RSTCTL0_REGISTER_ACCESS_INFO_ARRAY(reg_info);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ RESETTABLE_CLASS(klass)->phases.enter = rt500_rstctl_reset_enter;
+ dc->vmsd = &vmstate_rt500_rstcl0;
+ rc->reg_info = reg_info;
+ rc->reg_info_num = ARRAY_SIZE(reg_info);
+}
+
+static void rt500_rstctl1_class_init(ObjectClass *klass, void *data)
+{
+ RT500RstCtlClass *rc = RT500_RSTCTL_CLASS(klass);
+ static const RT500_RSTCTL1_REGISTER_ACCESS_INFO_ARRAY(reg_info);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ RESETTABLE_CLASS(klass)->phases.enter = rt500_rstctl_reset_enter;
+ dc->vmsd = &vmstate_rt500_rstcl1;
+ rc->reg_info = reg_info;
+ rc->reg_info_num = ARRAY_SIZE(reg_info);
+}
+
+static const TypeInfo rt500_rstctl_types[] = {
+ {
+ .name = TYPE_RT500_RSTCTL,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(RT500RstCtlState),
+ .instance_init = rt500_rstctl_init,
+ .abstract = true,
+ },
+ {
+ .name = TYPE_RT500_RSTCTL0,
+ .parent = TYPE_RT500_RSTCTL,
+ .class_init = rt500_rstctl0_class_init,
+ .class_size = sizeof(RT500RstCtlClass),
+ },
+ {
+ .name = TYPE_RT500_RSTCTL1,
+ .parent = TYPE_RT500_RSTCTL,
+ .class_init = rt500_rstctl1_class_init,
+ .class_size = sizeof(RT500RstCtlClass),
+ },
+};
+
+DEFINE_TYPES(rt500_rstctl_types);
diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build
index 7e59eda0d3..25f4917089 100644
--- a/hw/arm/svd/meson.build
+++ b/hw/arm/svd/meson.build
@@ -22,4 +22,10 @@ if get_option('mcux-soc-svd')
run_target('svd-flexspi', command: svd_gen_header +
[ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexspi.h',
'-p', 'FLEXSPI0', '-t', 'FLEXSPI'])
+ run_target('svd-rt500-rstctl0', command: svd_gen_header +
+ [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/rt500_rstctl0.h',
+ '-p', 'RSTCTL0', '-t', 'RT500_RSTCTL0'])
+ run_target('svd-rt500-rstctl1', command: svd_gen_header +
+ [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/rt500_rstctl1.h',
+ '-p', 'RSTCTL1', '-t', 'RT500_RSTCTL1'])
endif
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 02feb93840..4b688aead2 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -221,4 +221,7 @@ config FLEXCOMM
config RT500_CLKCTL
bool
+config RT500_RSTCTL
+ bool
+
source macio/Kconfig
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index e6d97b387c..faaf2671ba 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -160,3 +160,4 @@ system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c'))
system_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm.c'))
system_ss.add(when: 'CONFIG_RT500_CLKCTL', if_true: files('rt500_clkctl0.c', 'rt500_clkctl1.c'))
+system_ss.add(when: 'CONFIG_RT500_RSTCTL', if_true: files('rt500_rstctl.c'))
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index b19393dd36..721ebe4bb7 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -376,3 +376,7 @@ rt500_clkctl0_reg_write(const char *regname, uint32_t addr, uint32_t val) "%s[0x
# rt500_clkctl1.c
rt500_clkctl1_reg_read(const char *regname, uint32_t addr, uint32_t val) "%s[0x%04x] -> 0x%08x"
rt500_clkctl1_reg_write(const char *regname, uint32_t addr, uint32_t val) "%s[0x%04x] <- 0x%08x"
+
+# rt500_rstctl.c
+rt500_rstctl_reg_read(const char *id, const char *regname, uint32_t addr, uint32_t val) "%s: %s[0x%04x] -> 0x%08x"
+rt500_rstctl_reg_write(const char *id, const char *regname, uint32_t addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x"
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 13/25] hw/arm: add basic support for the RT500 SoC
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (11 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 12/25] hw/misc: add support for RT500's reset controller Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 14/25] hw/arm: add RT595-EVK board Octavian Purdila
` (11 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add basic support for the RT500 SoC. It supports enough peripherals to
run the NXP's microXpresso SDK hello world example.
The patch includes an automatically generated header which contains
peripheral base addreses and interrupt numbers.
The header can be regenerated with the svd-rt500 target when the
build is configured with --enable-mcux-soc-svd.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
include/hw/arm/rt500.h | 44 +++++
include/hw/arm/svd/rt500.h | 63 +++++++
hw/arm/rt500.c | 329 +++++++++++++++++++++++++++++++++++++
hw/arm/Kconfig | 2 +
hw/arm/meson.build | 1 +
hw/arm/svd/meson.build | 4 +
6 files changed, 443 insertions(+)
create mode 100644 include/hw/arm/rt500.h
create mode 100644 include/hw/arm/svd/rt500.h
create mode 100644 hw/arm/rt500.c
diff --git a/include/hw/arm/rt500.h b/include/hw/arm/rt500.h
new file mode 100644
index 0000000000..26e08c39a6
--- /dev/null
+++ b/include/hw/arm/rt500.h
@@ -0,0 +1,44 @@
+/*
+ * i.MX RT500 platforms.
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_ARM_RT500_H
+#define HW_ARM_RT500_H
+
+#include "hw/arm/armv7m.h"
+#include "hw/misc/flexcomm.h"
+#include "hw/misc/rt500_clkctl0.h"
+#include "hw/misc/rt500_clkctl1.h"
+#include "hw/ssi/flexspi.h"
+#include "hw/misc/rt500_rstctl.h"
+
+#define TYPE_RT500 "rt500"
+#define RT500(obj) OBJECT_CHECK(RT500State, (obj), TYPE_RT500)
+
+#define RT500_FLEXCOMM_NUM (17)
+#define RT500_FLEXSPI_NUM (2)
+#define RT500_RSTCTL_NUM (2)
+
+typedef struct RT500State {
+ SysBusDevice parent_obj;
+
+ ARMv7MState armv7m;
+ MemoryRegion *mem;
+ FlexcommState flexcomm[RT500_FLEXCOMM_NUM];
+ RT500ClkCtl0State clkctl0;
+ RT500ClkCtl1State clkctl1;
+ FlexSpiState flexspi[RT500_FLEXSPI_NUM];
+ RT500RstCtlState rstctl[RT500_RSTCTL_NUM];
+
+ Clock *sysclk;
+ Clock *refclk;
+} RT500State;
+
+#endif /* HW_ARM_RT500_H */
diff --git a/include/hw/arm/svd/rt500.h b/include/hw/arm/svd/rt500.h
new file mode 100644
index 0000000000..3594258f2e
--- /dev/null
+++ b/include/hw/arm/svd/rt500.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
+ */
+#pragma once
+
+#define RT500_FLEXCOMM0_BASE 0x40106000UL
+#define RT500_FLEXCOMM1_BASE 0x40107000UL
+#define RT500_FLEXCOMM2_BASE 0x40108000UL
+#define RT500_FLEXCOMM3_BASE 0x40109000UL
+#define RT500_FLEXCOMM4_BASE 0x40122000UL
+#define RT500_FLEXCOMM5_BASE 0x40123000UL
+#define RT500_FLEXCOMM6_BASE 0x40124000UL
+#define RT500_FLEXCOMM7_BASE 0x40125000UL
+#define RT500_FLEXCOMM14_BASE 0x40126000UL
+#define RT500_FLEXCOMM15_BASE 0x40127000UL
+#define RT500_FLEXCOMM16_BASE 0x40128000UL
+#define RT500_FLEXCOMM8_BASE 0x40209000UL
+#define RT500_FLEXCOMM9_BASE 0x4020A000UL
+#define RT500_FLEXCOMM10_BASE 0x4020B000UL
+#define RT500_FLEXCOMM11_BASE 0x4020C000UL
+#define RT500_FLEXCOMM12_BASE 0x4020D000UL
+#define RT500_FLEXCOMM13_BASE 0x4020E000UL
+
+#define RT500_FLEXCOMM0_IRQn 0x14UL
+#define RT500_FLEXCOMM1_IRQn 0x15UL
+#define RT500_FLEXCOMM2_IRQn 0x16UL
+#define RT500_FLEXCOMM3_IRQn 0x17UL
+#define RT500_FLEXCOMM4_IRQn 0x18UL
+#define RT500_FLEXCOMM5_IRQn 0x19UL
+#define RT500_FLEXCOMM6_IRQn 0x43UL
+#define RT500_FLEXCOMM7_IRQn 0x44UL
+#define RT500_FLEXCOMM14_IRQn 0x20UL
+#define RT500_FLEXCOMM15_IRQn 0x21UL
+#define RT500_FLEXCOMM16_IRQn 0x66UL
+#define RT500_FLEXCOMM8_IRQn 0x60UL
+#define RT500_FLEXCOMM9_IRQn 0x61UL
+#define RT500_FLEXCOMM10_IRQn 0x62UL
+#define RT500_FLEXCOMM11_IRQn 0x63UL
+#define RT500_FLEXCOMM12_IRQn 0x64UL
+#define RT500_FLEXCOMM13_IRQn 0x65UL
+
+#define RT500_CLKCTL0_BASE 0x40001000UL
+
+
+#define RT500_CLKCTL1_BASE 0x40021000UL
+
+
+#define RT500_FLEXSPI0_BASE 0x40134000UL
+
+#define RT500_FLEXSPI0_FLEXSPI1_IRQn 0x42UL
+
+#define RT500_FLEXSPI1_BASE 0x4013C000UL
+
+#define RT500_FLEXSPI0_FLEXSPI1_IRQn 0x42UL
+
+#define RT500_RSTCTL0_BASE 0x40000000UL
+
+
+#define RT500_RSTCTL1_BASE 0x40020000UL
+
+
diff --git a/hw/arm/rt500.c b/hw/arm/rt500.c
new file mode 100644
index 0000000000..9e4cfb539e
--- /dev/null
+++ b/hw/arm/rt500.c
@@ -0,0 +1,329 @@
+/*
+ * i.MX RT500 platforms.
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "hw/arm/boot.h"
+#include "hw/boards.h"
+#include "hw/irq.h"
+#include "qemu/log.h"
+#include "qemu/datadir.h"
+#include "qemu/units.h"
+#include "exec/address-spaces.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
+#include "sysemu/sysemu.h"
+#include "hw/arm/armv7m.h"
+#include "hw/loader.h"
+#include "hw/qdev-clock.h"
+#include "hw/misc/unimp.h"
+#include "hw/arm/rt500.h"
+#include "hw/arm/svd/rt500.h"
+
+#define MMAP_SRAM_CODE_BASE (0x0)
+#define MMAP_SRAM_DATA_BASE (0x20000000)
+#define MMAP_SRAM_SIZE (5 * MiB)
+#define MMAP_BOOT_ROM_BASE (0x03000000)
+#define MMAP_BOOT_ROM_SIZE (192 * KiB)
+#define MMAP_SDMA_RAM_BASE (0x24100000)
+#define MMAP_SDMA_RAM_SIZE (32 * KiB)
+#define MMAP_FLEXSPI0_BASE (0x08000000)
+#define MMAP_FLEXSPI0_SIZE (128 * MiB)
+#define MMAP_FLEXSPI1_BASE (0x28000000)
+#define MMAP_FLEXSPI1_SIZE (128 * MiB)
+
+#define SECURE_OFFSET (0x10000000)
+
+#define RT500_NUM_IRQ (RT500_FLEXCOMM16_IRQn + 1)
+
+typedef enum MemInfoType {
+ MEM_RAM,
+ MEM_ROM,
+ MEM_ALIAS
+} MemInfoType;
+
+static void do_sys_reset(void *opaque, int n, int level)
+{
+ if (level) {
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+ }
+}
+
+static void rt500_init(Object *obj)
+{
+ RT500State *s = RT500(obj);
+
+ /* Add ARMv7-M device */
+ object_initialize_child(obj, "armv7m", &s->armv7m, TYPE_ARMV7M);
+
+ for (int i = 0; i < RT500_FLEXCOMM_NUM; i++) {
+ char *id = g_strdup_printf("flexcomm%d", i);
+
+ object_initialize_child(obj, id, &s->flexcomm[i], TYPE_FLEXCOMM);
+ DEVICE(&s->flexcomm[i])->id = id;
+ }
+
+ object_initialize_child(obj, "clkctl0", &s->clkctl0, TYPE_RT500_CLKCTL0);
+ object_initialize_child(obj, "clkctl1", &s->clkctl1, TYPE_RT500_CLKCTL1);
+
+ /* Initialize clocks */
+ s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
+ s->refclk = qdev_init_clock_in(DEVICE(s), "refclk", NULL, NULL, 0);
+
+ for (int i = 0; i < RT500_FLEXSPI_NUM; i++) {
+ char *id = g_strdup_printf("flexspi%d", i);
+
+ object_initialize_child(obj, id, &s->flexspi[i], TYPE_FLEXSPI);
+ DEVICE(&s->flexspi[i])->id = id;
+ }
+
+ for (int i = 0; i < RT500_RSTCTL_NUM; i++) {
+ static const char *types[] = {
+ TYPE_RT500_RSTCTL0, TYPE_RT500_RSTCTL1
+ };
+ char *id = g_strdup_printf("rstctl%d", i);
+
+ object_initialize_child(obj, id, &s->rstctl[i], types[i]);
+ DEVICE(&s->rstctl[i])->id = id;
+ }
+}
+
+static void rt500_realize_memory(RT500State *s, Error **errp)
+{
+ static const struct {
+ const char *name;
+ hwaddr base;
+ size_t size;
+ MemInfoType type;
+ int alias_for;
+ } mem_info[] = {
+ {
+ .name = "SRAM (code bus)",
+ .base = MMAP_SRAM_CODE_BASE,
+ .size = MMAP_SRAM_SIZE,
+ .type = MEM_RAM,
+ },
+ {
+ .name = "BOOT-ROM",
+ .base = MMAP_BOOT_ROM_BASE,
+ .size = MMAP_BOOT_ROM_SIZE,
+ .type = MEM_ROM,
+ },
+ {
+ .name = "Smart DMA RAM",
+ .base = MMAP_SDMA_RAM_BASE,
+ .size = MMAP_SDMA_RAM_SIZE,
+ .type = MEM_RAM,
+ },
+ {
+ .name = "SRAM (data bus)",
+ .base = MMAP_SRAM_DATA_BASE,
+ .size = MMAP_SRAM_SIZE,
+ .type = MEM_ALIAS,
+ .alias_for = 0
+ },
+ };
+
+ s->mem = g_malloc_n(2 * ARRAY_SIZE(mem_info), sizeof(MemoryRegion));
+ for (int i = 0; i < ARRAY_SIZE(mem_info); i++) {
+ const char *name = mem_info[i].name;
+ int size = mem_info[i].size;
+ int type = mem_info[i].type;
+ int alias_for = mem_info[i].alias_for;
+ MemoryRegion *mem = &s->mem[i];
+ uint32_t base = mem_info[i].base;
+ MemoryRegion *sec_mem;
+ char sec_name[256];
+
+ switch (type) {
+ case MEM_RAM:
+ memory_region_init_ram(mem, OBJECT(s), name, size, errp);
+ break;
+ case MEM_ROM:
+ memory_region_init_rom(mem, OBJECT(s), name, size, errp);
+ break;
+ case MEM_ALIAS:
+ {
+ MemoryRegion *orig = &s->mem[alias_for];
+
+ memory_region_init_alias(mem, OBJECT(s), name, orig, 0, size);
+ break;
+ }
+ default:
+ g_assert_not_reached();
+ }
+
+ memory_region_add_subregion(get_system_memory(), base, mem);
+
+ /* create secure alias */
+ snprintf(sec_name, sizeof(sec_name), "SECURE %s", name);
+ sec_mem = &s->mem[ARRAY_SIZE(mem_info) + i];
+ if (type == MEM_ALIAS) {
+ mem = &s->mem[alias_for];
+ }
+ memory_region_init_alias(sec_mem, OBJECT(s), sec_name, mem, 0, size);
+ memory_region_add_subregion(get_system_memory(), base + SECURE_OFFSET,
+ sec_mem);
+
+ if (mem_info[i].type == MEM_ROM) {
+ char *fname = qemu_find_file(QEMU_FILE_TYPE_BIOS, "rt500.rom");
+
+ if (fname) {
+ int fsize = get_image_size(fname);
+ int ret;
+
+ if (fsize > size) {
+ error_setg(errp, "rom file too big: %d > %d", fsize, size);
+ } else {
+ ret = load_image_targphys(fname, base, size);
+ if (ret < 0) {
+ error_setg(errp, "could not load rom: %s", fname);
+ }
+ }
+ }
+ g_free(fname);
+ }
+ }
+}
+
+static void rt500_realize(DeviceState *dev, Error **errp)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ RT500State *s = RT500(dev);
+
+ rt500_realize_memory(s, errp);
+
+ /* Setup ARMv7M CPU */
+ qdev_prop_set_uint32(DEVICE(&s->armv7m), "num-irq", RT500_NUM_IRQ);
+ qdev_prop_set_uint8(DEVICE(&s->armv7m), "num-prio-bits", 3);
+ qdev_prop_set_string(DEVICE(&s->armv7m), "cpu-type", "cortex-m33-arm-cpu");
+ object_property_set_link(OBJECT(&s->armv7m), "memory",
+ OBJECT(get_system_memory()), &error_abort);
+ if (!ms->kernel_filename) {
+ qdev_prop_set_uint32(DEVICE(&s->armv7m), "init-nsvtor",
+ MMAP_BOOT_ROM_BASE);
+ qdev_prop_set_uint32(DEVICE(&s->armv7m), "init-svtor",
+ MMAP_BOOT_ROM_BASE + SECURE_OFFSET);
+ }
+
+ qdev_connect_clock_in(DEVICE(&s->armv7m), "cpuclk", s->sysclk);
+ qdev_connect_clock_in(DEVICE(&s->armv7m), "refclk",
+ qdev_get_clock_out(DEVICE(&s->clkctl0), "systick_clk"));
+
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->armv7m), errp);
+ qdev_connect_gpio_out_named(DEVICE(&s->armv7m), "SYSRESETREQ", 0,
+ qemu_allocate_irq(&do_sys_reset, NULL, 0));
+
+ /* Setup FLEXCOMM */
+ for (int i = 0; i < RT500_FLEXCOMM_NUM; i++) {
+ static const uint32_t addr[] = {
+ RT500_FLEXCOMM0_BASE, RT500_FLEXCOMM1_BASE, RT500_FLEXCOMM2_BASE,
+ RT500_FLEXCOMM3_BASE, RT500_FLEXCOMM4_BASE, RT500_FLEXCOMM5_BASE,
+ RT500_FLEXCOMM6_BASE, RT500_FLEXCOMM7_BASE, RT500_FLEXCOMM8_BASE,
+ RT500_FLEXCOMM8_BASE, RT500_FLEXCOMM10_BASE, RT500_FLEXCOMM11_BASE,
+ RT500_FLEXCOMM12_BASE, RT500_FLEXCOMM13_BASE, RT500_FLEXCOMM14_BASE,
+ RT500_FLEXCOMM15_BASE, RT500_FLEXCOMM16_BASE
+ };
+ static const int irq[] = {
+ RT500_FLEXCOMM0_IRQn, RT500_FLEXCOMM1_IRQn, RT500_FLEXCOMM2_IRQn,
+ RT500_FLEXCOMM3_IRQn, RT500_FLEXCOMM4_IRQn, RT500_FLEXCOMM5_IRQn,
+ RT500_FLEXCOMM6_IRQn, RT500_FLEXCOMM7_IRQn, RT500_FLEXCOMM8_IRQn,
+ RT500_FLEXCOMM9_IRQn, RT500_FLEXCOMM10_IRQn, RT500_FLEXCOMM11_IRQn,
+ RT500_FLEXCOMM12_IRQn, RT500_FLEXCOMM13_IRQn, RT500_FLEXCOMM14_IRQn,
+ RT500_FLEXCOMM15_IRQn, RT500_FLEXCOMM16_IRQn
+ };
+ static const int functions[] = {
+ FLEXCOMM_FULL, FLEXCOMM_FULL, FLEXCOMM_FULL,
+ FLEXCOMM_FULL, FLEXCOMM_FULL, FLEXCOMM_FULL,
+ FLEXCOMM_FULL, FLEXCOMM_FULL, FLEXCOMM_FULL,
+ FLEXCOMM_FULL, FLEXCOMM_FULL, FLEXCOMM_FULL,
+ FLEXCOMM_FULL, FLEXCOMM_FULL, FLEXCOMM_HSSPI,
+ FLEXCOMM_PMICI2C, FLEXCOMM_HSSPI
+ };
+ DeviceState *ds = DEVICE(&s->flexcomm[i]);
+
+ qdev_prop_set_uint32(ds, "functions", functions[i]);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(ds), errp);
+ sysbus_mmio_map(SYS_BUS_DEVICE(ds), 0, addr[i]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(ds), 0,
+ qdev_get_gpio_in(DEVICE(&s->armv7m), irq[i]));
+ }
+
+ /* Setup CTLCTL0 */
+ qdev_connect_clock_in(DEVICE(&s->clkctl0), "sysclk", s->sysclk);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(DEVICE(&s->clkctl0)), errp);
+ sysbus_mmio_map(SYS_BUS_DEVICE(DEVICE(&s->clkctl0)), 0, RT500_CLKCTL0_BASE);
+
+ /* Setup CTLCTL1 */
+ qdev_connect_clock_in(DEVICE(&s->clkctl1), "sysclk", s->sysclk);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(DEVICE(&s->clkctl1)), errp);
+ sysbus_mmio_map(SYS_BUS_DEVICE(DEVICE(&s->clkctl1)), 0, RT500_CLKCTL1_BASE);
+
+ /* Setup FlexSPI */
+ for (int i = 0; i < RT500_FLEXSPI_NUM; i++) {
+ static const uint32_t addr[] = {
+ RT500_FLEXSPI0_BASE, RT500_FLEXSPI1_BASE
+ };
+ static const uint32_t mmap_base[] = {
+ MMAP_FLEXSPI0_BASE, MMAP_FLEXSPI1_BASE
+ };
+ static const uint32_t mmap_size[] = {
+ MMAP_FLEXSPI0_SIZE, MMAP_FLEXSPI1_SIZE,
+ };
+ DeviceState *ds = DEVICE(&s->flexspi[i]);
+
+ qdev_prop_set_uint32(ds, "mmap_size", mmap_size[i]);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(ds), errp);
+ sysbus_mmio_map(SYS_BUS_DEVICE(ds), 0, addr[i]);
+ sysbus_mmio_map(SYS_BUS_DEVICE(ds), 1, mmap_base[i]);
+ }
+
+ /* Setup reset controllers */
+ for (int i = 0; i < RT500_RSTCTL_NUM; i++) {
+ DeviceState *ds = DEVICE(&s->rstctl[i]);
+ static const uint32_t addr[] = {
+ RT500_RSTCTL0_BASE, RT500_RSTCTL1_BASE
+ };
+
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(ds), errp);
+ sysbus_mmio_map(SYS_BUS_DEVICE(ds), 0, addr[i]);
+ }
+}
+
+static void rt500_unrealize(DeviceState *ds)
+{
+ RT500State *s = RT500(ds);
+
+ g_free(s->mem);
+}
+
+static void rt500_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->realize = rt500_realize;
+ dc->unrealize = rt500_unrealize;
+ dc->desc = "RT500 (ARM Cortex-M33)";
+}
+
+static const TypeInfo rt500_types[] = {
+ {
+ .name = TYPE_RT500,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(RT500State),
+ .instance_init = rt500_init,
+ .class_init = rt500_class_init,
+ },
+};
+
+DEFINE_TYPES(rt500_types);
+
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 668135bc85..d1443e8f89 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -717,3 +717,5 @@ config RT500
bool
select FLEXCOMM
select RT500_CLKCTL
+ select FLEXSPI
+ select RT500_RSTCTL
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index fdfd083f75..d0be157092 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -63,6 +63,7 @@ arm_ss.add(when: 'CONFIG_XEN', if_true: files(
'xen-stubs.c',
'xen-pvh.c',
))
+arm_ss.add(when: 'CONFIG_RT500', if_true: files('rt500.c'))
system_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c'))
system_ss.add(when: 'CONFIG_CHEETAH', if_true: files('palm.c'))
diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build
index 25f4917089..b7480e7d48 100644
--- a/hw/arm/svd/meson.build
+++ b/hw/arm/svd/meson.build
@@ -28,4 +28,8 @@ if get_option('mcux-soc-svd')
run_target('svd-rt500-rstctl1', command: svd_gen_header +
[ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/rt500_rstctl1.h',
'-p', 'RSTCTL1', '-t', 'RT500_RSTCTL1'])
+ run_target('svd-rt500', command: svd_gen_header +
+ [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/rt500.h',
+ '-s', 'RT500', '-p', 'FLEXCOMM0', '-p', 'CLKCTL0', '-p', 'CLKCTL1',
+ '-p', 'FLEXSPI0', '-p', 'FLEXSPI1', '-p', 'RSTCTL0', '-p', 'RSTCTL1'])
endif
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 14/25] hw/arm: add RT595-EVK board
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (12 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 13/25] hw/arm: add basic support for the RT500 SoC Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 15/25] tests/qtest: add register access macros and functions Octavian Purdila
` (10 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add basic support for the RT595-EVK board, enough to be able to run
the NXP's microXpresso SDK hello world example.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
hw/arm/rt595-evk.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++
hw/arm/Kconfig | 5 ++++
hw/arm/meson.build | 1 +
3 files changed, 70 insertions(+)
create mode 100644 hw/arm/rt595-evk.c
diff --git a/hw/arm/rt595-evk.c b/hw/arm/rt595-evk.c
new file mode 100644
index 0000000000..e5daecc8b8
--- /dev/null
+++ b/hw/arm/rt595-evk.c
@@ -0,0 +1,64 @@
+/*
+ * i.MX RT595 EVK
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "elf.h"
+#include "exec/address-spaces.h"
+#include "hw/loader.h"
+#include "hw/sysbus.h"
+#include "hw/boards.h"
+#include "qemu/log.h"
+#include "hw/arm/armv7m.h"
+#include "hw/arm/boot.h"
+#include "qapi/error.h"
+#include "hw/arm/rt500.h"
+#include "hw/qdev-clock.h"
+#include "sysemu/reset.h"
+
+static void rt595_evk_reset(MachineState *ms, ShutdownCause reason)
+{
+ /*
+ * CPU reset is not done by default, we need to do it manually when the
+ * machine is reset.
+ */
+ cpu_reset(first_cpu);
+
+ qemu_devices_reset(reason);
+}
+
+static void rt595_evk_init(MachineState *ms)
+{
+ RT500State *s;
+ Clock *sysclk;
+
+ sysclk = clock_new(OBJECT(ms), "SYSCLK");
+ clock_set_hz(sysclk, 200000000);
+
+ s = RT500(object_new(TYPE_RT500));
+ qdev_connect_clock_in(DEVICE(s), "sysclk", sysclk);
+ object_property_add_child(OBJECT(ms), "soc", OBJECT(s));
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(s), &error_fatal);
+
+ if (ms->kernel_filename) {
+ armv7m_load_kernel(ARM_CPU(first_cpu), ms->kernel_filename, 0, 0);
+ }
+}
+
+static void rt595_evk_machine_init(MachineClass *mc)
+{
+ mc->desc = "RT595 EVK Machine (ARM Cortex-M33)";
+ mc->init = rt595_evk_init;
+ mc->reset = rt595_evk_reset;
+
+ mc->ignore_memory_transaction_failures = true;
+}
+
+DEFINE_MACHINE("rt595-evk", rt595_evk_machine_init);
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index d1443e8f89..6720a41f65 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -719,3 +719,8 @@ config RT500
select RT500_CLKCTL
select FLEXSPI
select RT500_RSTCTL
+
+config RT595_EVK
+ bool
+ default y
+ select RT500
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index d0be157092..f8c227c633 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -64,6 +64,7 @@ arm_ss.add(when: 'CONFIG_XEN', if_true: files(
'xen-pvh.c',
))
arm_ss.add(when: 'CONFIG_RT500', if_true: files('rt500.c'))
+arm_ss.add(when: 'CONFIG_RT595_EVK', if_true: files('rt595-evk.c'))
system_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c'))
system_ss.add(when: 'CONFIG_CHEETAH', if_true: files('palm.c'))
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 15/25] tests/qtest: add register access macros and functions
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (13 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 14/25] hw/arm: add RT595-EVK board Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 16/25] system/qtest: add APIS to check for memory access failures Octavian Purdila
` (9 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add utility macros for accessing register or register bit fields in
tests, e.g.:
REG32_WRITE(FLEXCOMM, PSELID, persel);
g_assert(REG32_READ_FIELD(FLEXCOMM, PSELID, PERSEL) == persel);
Signed-off-by: Octavian Purdila <tavip@google.com>
---
tests/qtest/reg-utils.h | 70 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
create mode 100644 tests/qtest/reg-utils.h
diff --git a/tests/qtest/reg-utils.h b/tests/qtest/reg-utils.h
new file mode 100644
index 0000000000..e09aaf3333
--- /dev/null
+++ b/tests/qtest/reg-utils.h
@@ -0,0 +1,70 @@
+/*
+ * Register access utilities for device tests.
+ *
+ * Copyright (C) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef _REG_UTILS_H
+#define _REG_UTILS_H
+
+#include "libqtest-single.h"
+#include "hw/registerfields.h"
+
+#ifdef DEBUG_REG
+#define debug(fmt, args...) fprintf(stderr, fmt, ## args)
+#else
+#define debug(fmt, args...)
+#endif
+
+#define _REG_OFF(mod, reg) (A_##mod##_##reg)
+
+#define REG32_READ(mod, reg) \
+ ({ \
+ uint32_t value; \
+ value = readl(mod##_BASE + _REG_OFF(mod, reg)); \
+ debug("[%s] -> %08x\n", #reg, value); \
+ value; \
+ })
+
+#define REG32_WRITE(mod, reg, value) \
+ do { \
+ debug("[%s] <- %08x\n", #reg, value); \
+ writel(mod##_BASE + _REG_OFF(mod, reg), value); \
+ } while (0)
+
+#define REG_FIELD_VAL(v, mod, reg, field) \
+ FIELD_EX32(v, mod##_##reg, field) \
+
+#define REG32_READ_FIELD(mod, reg, field) \
+ REG_FIELD_VAL(REG32_READ(mod, reg), mod, reg, field)
+
+#define REG32_WRITE_FIELD(mod, reg, field, val) \
+ do { \
+ uint32_t _tmp = REG32_READ(mod, reg); \
+ _tmp = FIELD_DP32(_tmp, mod##_##reg, field, val); \
+ REG32_WRITE(mod, reg, _tmp); \
+ } while (0)
+
+#define REG32_WRITE_FIELD_NOUPDATE(mod, reg, field, val) \
+ do { \
+ uint32_t _tmp = FIELD_DP32(0, mod##_##reg, field, val); \
+ REG32_WRITE(mod, reg, _tmp); \
+ } while (0)
+
+#define WAIT_REG32_FIELD(ns, mod, reg, field, val) \
+ do { \
+ clock_step(ns); \
+ g_assert_cmpuint(REG32_READ_FIELD(mod, reg, field), ==, val); \
+ } while (0)
+
+#define REG32_READ_FAIL(mod, reg) \
+ readl_fail(mod##_BASE + _REG_OFF(mod, reg))
+
+#define REG32_WRITE_FAIL(mod, reg, value) \
+ writel_fail(mod##_BASE + _REG_OFF(mod, reg), value)
+
+#endif /* _REG_UTILS_H */
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 16/25] system/qtest: add APIS to check for memory access failures
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (14 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 15/25] tests/qtest: add register access macros and functions Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 17/25] tests/qtest: add flexcomm tests Octavian Purdila
` (8 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add read*/write*_fail qtest APIs to check for memory access failures.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
tests/qtest/libqtest-single.h | 92 +++++++++++++++++++++++++++++++++++
tests/qtest/libqtest.h | 76 +++++++++++++++++++++++++++++
system/qtest.c | 44 ++++++++++-------
tests/qtest/libqtest.c | 73 ++++++++++++++++++++++++++-
4 files changed, 265 insertions(+), 20 deletions(-)
diff --git a/tests/qtest/libqtest-single.h b/tests/qtest/libqtest-single.h
index 851724cbcb..c22037c8b2 100644
--- a/tests/qtest/libqtest-single.h
+++ b/tests/qtest/libqtest-single.h
@@ -265,6 +265,98 @@ static inline uint64_t readq(uint64_t addr)
return qtest_readq(global_qtest, addr);
}
+/**
+ * writeb_fail:
+ * @addr: Guest address to write to.
+ * @value: Value being written.
+ *
+ * Writes an 8-bit value to memory expecting a failure.
+ */
+static inline void writeb_fail(uint64_t addr, uint8_t value)
+{
+ qtest_writeb_fail(global_qtest, addr, value);
+}
+
+/**
+ * writew_fail:
+ * @addr: Guest address to write to.
+ * @value: Value being written.
+ *
+ * Writes a 16-bit value to memory expecting a failure.
+ */
+static inline void writew_fail(uint64_t addr, uint16_t value)
+{
+ qtest_writew_fail(global_qtest, addr, value);
+}
+
+/**
+ * writel_fail:
+ * @addr: Guest address to write to.
+ * @value: Value being written.
+ *
+ * Writes a 32-bit value to memory expecting a failure.
+ */
+static inline void writel_fail(uint64_t addr, uint32_t value)
+{
+ qtest_writel_fail(global_qtest, addr, value);
+}
+
+/**
+ * writeq_fail:
+ * @addr: Guest address to write to.
+ * @value: Value being written.
+ *
+ * Writes a 64-bit value to memory expecting a failure.
+ */
+static inline void writeq_fail(uint64_t addr, uint64_t value)
+{
+ qtest_writeq_fail(global_qtest, addr, value);
+}
+
+/**
+ * readb_fail:
+ * @addr: Guest address to read from.
+ *
+ * Reads an 8-bit value from memory expecting a failure.
+ */
+static inline void readb_fail(uint64_t addr)
+{
+ qtest_readb_fail(global_qtest, addr);
+}
+
+/**
+ * readw_fail:
+ * @addr: Guest address to read from.
+ *
+ * Reads a 16-bit value from memory expecting a failure.
+ */
+static inline void readw_fail(uint64_t addr)
+{
+ qtest_readw_fail(global_qtest, addr);
+}
+
+/**
+ * readl_fail:
+ * @addr: Guest address to read from.
+ *
+ * Reads a 32-bit value from memory expecting a failure.
+ */
+static inline void readl_fail(uint64_t addr)
+{
+ qtest_readl_fail(global_qtest, addr);
+}
+
+/**
+ * readq_fail:
+ * @addr: Guest address to read from.
+ *
+ * Reads a 64-bit value from memory expecting a failure.
+ */
+static inline void readq_fail(uint64_t addr)
+{
+ qtest_readq_fail(global_qtest, addr);
+}
+
/**
* memread:
* @addr: Guest address to read from.
diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
index beb96b18eb..f9bbeb2e60 100644
--- a/tests/qtest/libqtest.h
+++ b/tests/qtest/libqtest.h
@@ -549,6 +549,82 @@ uint32_t qtest_readl(QTestState *s, uint64_t addr);
*/
uint64_t qtest_readq(QTestState *s, uint64_t addr);
+/**
+ * qtest_writeb_fail:
+ * @s: #QTestState instance to operate on.
+ * @addr: Guest address to write to.
+ * @value: Value being written.
+ *
+ * Writes an 8-bit value to memory expecting a failure.
+ */
+void qtest_writeb_fail(QTestState *s, uint64_t addr, uint8_t value);
+
+/**
+ * qtest_writew_fail:
+ * @s: #QTestState instance to operate on.
+ * @addr: Guest address to write to.
+ * @value: Value being written.
+ *
+ * Writes a 16-bit value to memory expecting a failure.
+ */
+void qtest_writew_fail(QTestState *s, uint64_t addr, uint16_t value);
+
+/**
+ * qtest_writel_fail:
+ * @s: #QTestState instance to operate on.
+ * @addr: Guest address to write to.
+ * @value: Value being written.
+ *
+ * Writes a 32-bit value to memory expecting a failure.
+ */
+void qtest_writel_fail(QTestState *s, uint64_t addr, uint32_t value);
+
+/**
+ * qtest_writeq_fail:
+ * @s: #QTestState instance to operate on.
+ * @addr: Guest address to write to.
+ * @value: Value being written.
+ *
+ * Writes a 64-bit value to memory expecting a failure.
+ */
+void qtest_writeq_fail(QTestState *s, uint64_t addr, uint64_t value);
+
+/**
+ * qtest_readb_fail:
+ * @s: #QTestState instance to operate on.
+ * @addr: Guest address to read from.
+ *
+ * Reads an 8-bit value from memory expecting a failure.
+ */
+void qtest_readb_fail(QTestState *s, uint64_t addr);
+
+/**
+ * qtest_readw_fail:
+ * @s: #QTestState instance to operate on.
+ * @addr: Guest address to read from.
+ *
+ * Reads a 16-bit value from memory expecting a failure.
+ */
+void qtest_readw_fail(QTestState *s, uint64_t addr);
+
+/**
+ * qtest_readl_fail:
+ * @s: #QTestState instance to operate on.
+ * @addr: Guest address to read from.
+ *
+ * Reads a 32-bit value from memory expecting a failure.
+ */
+void qtest_readl_fail(QTestState *s, uint64_t addr);
+
+/**
+ * qtest_readq_fail:
+ * @s: #QTestState instance to operate on.
+ * @addr: Guest address to read from.
+ *
+ * Reads a 64-bit value from memory expecting a failure.
+ */
+void qtest_readq_fail(QTestState *s, uint64_t addr);
+
/**
* qtest_memread:
* @s: #QTestState instance to operate on.
diff --git a/system/qtest.c b/system/qtest.c
index 12703a2045..95bb80a2bc 100644
--- a/system/qtest.c
+++ b/system/qtest.c
@@ -514,26 +514,30 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
if (words[0][5] == 'b') {
uint8_t data = value;
- address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
- &data, 1);
+ ret = address_space_write(first_cpu->as, addr,
+ MEMTXATTRS_UNSPECIFIED, &data, 1);
} else if (words[0][5] == 'w') {
uint16_t data = value;
tswap16s(&data);
- address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
- &data, 2);
+ ret = address_space_write(first_cpu->as, addr,
+ MEMTXATTRS_UNSPECIFIED, &data, 2);
} else if (words[0][5] == 'l') {
uint32_t data = value;
tswap32s(&data);
- address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
- &data, 4);
+ ret = address_space_write(first_cpu->as, addr,
+ MEMTXATTRS_UNSPECIFIED, &data, 4);
} else if (words[0][5] == 'q') {
uint64_t data = value;
tswap64s(&data);
- address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
- &data, 8);
+ ret = address_space_write(first_cpu->as, addr,
+ MEMTXATTRS_UNSPECIFIED, &data, 8);
}
qtest_send_prefix(chr);
- qtest_send(chr, "OK\n");
+ if (ret == MEMTX_OK) {
+ qtest_send(chr, "OK\n");
+ } else {
+ qtest_send(chr, "FAIL\n");
+ }
} else if (strcmp(words[0], "readb") == 0 ||
strcmp(words[0], "readw") == 0 ||
strcmp(words[0], "readl") == 0 ||
@@ -548,26 +552,30 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
if (words[0][4] == 'b') {
uint8_t data;
- address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
- &data, 1);
+ ret = address_space_read(first_cpu->as, addr,
+ MEMTXATTRS_UNSPECIFIED, &data, 1);
value = data;
} else if (words[0][4] == 'w') {
uint16_t data;
- address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
- &data, 2);
+ ret = address_space_read(first_cpu->as, addr,
+ MEMTXATTRS_UNSPECIFIED, &data, 2);
value = tswap16(data);
} else if (words[0][4] == 'l') {
uint32_t data;
- address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
- &data, 4);
+ ret = address_space_read(first_cpu->as, addr,
+ MEMTXATTRS_UNSPECIFIED, &data, 4);
value = tswap32(data);
} else if (words[0][4] == 'q') {
- address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
- &value, 8);
+ ret = address_space_read(first_cpu->as, addr,
+ MEMTXATTRS_UNSPECIFIED, &value, 8);
tswap64s(&value);
}
qtest_send_prefix(chr);
- qtest_sendf(chr, "OK 0x%016" PRIx64 "\n", value);
+ if (ret == MEMTX_OK) {
+ qtest_sendf(chr, "OK 0x%016" PRIx64 "\n", value);
+ } else {
+ qtest_sendf(chr, "FAIL\n");
+ }
} else if (strcmp(words[0], "read") == 0) {
g_autoptr(GString) enc = NULL;
uint64_t addr, len;
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index 9d07de1fbd..4055d6b953 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -666,7 +666,7 @@ static GString *qtest_client_socket_recv_line(QTestState *s)
return line;
}
-static gchar **qtest_rsp_args(QTestState *s, int expected_args)
+static gchar **_qtest_rsp_args(QTestState *s, int expected_args, bool fail)
{
GString *line;
gchar **words;
@@ -700,7 +700,11 @@ redo:
}
g_assert(words[0] != NULL);
- g_assert_cmpstr(words[0], ==, "OK");
+ if (fail) {
+ g_assert_cmpstr(words[0], ==, "FAIL");
+ } else {
+ g_assert_cmpstr(words[0], ==, "OK");
+ }
for (i = 0; i < expected_args; i++) {
g_assert(words[i] != NULL);
@@ -709,6 +713,11 @@ redo:
return words;
}
+static gchar **qtest_rsp_args(QTestState *s, int expected_args)
+{
+ return _qtest_rsp_args(s, expected_args, false);
+}
+
static void qtest_rsp(QTestState *s)
{
gchar **words = qtest_rsp_args(s, 0);
@@ -716,6 +725,13 @@ static void qtest_rsp(QTestState *s)
g_strfreev(words);
}
+static void qtest_rsp_fail(QTestState *s)
+{
+ gchar **words = _qtest_rsp_args(s, 0, true);
+
+ g_strfreev(words);
+}
+
static int qtest_query_target_endianness(QTestState *s)
{
gchar **args;
@@ -1103,6 +1119,13 @@ static void qtest_write(QTestState *s, const char *cmd, uint64_t addr,
qtest_rsp(s);
}
+static void qtest_write_fail(QTestState *s, const char *cmd, uint64_t addr,
+ uint64_t value)
+{
+ qtest_sendf(s, "%s 0x%" PRIx64 " 0x%" PRIx64 "\n", cmd, addr, value);
+ qtest_rsp_fail(s);
+}
+
void qtest_writeb(QTestState *s, uint64_t addr, uint8_t value)
{
qtest_write(s, "writeb", addr, value);
@@ -1123,6 +1146,26 @@ void qtest_writeq(QTestState *s, uint64_t addr, uint64_t value)
qtest_write(s, "writeq", addr, value);
}
+void qtest_writeb_fail(QTestState *s, uint64_t addr, uint8_t value)
+{
+ qtest_write_fail(s, "writeb", addr, value);
+}
+
+void qtest_writew_fail(QTestState *s, uint64_t addr, uint16_t value)
+{
+ qtest_write_fail(s, "writew", addr, value);
+}
+
+void qtest_writel_fail(QTestState *s, uint64_t addr, uint32_t value)
+{
+ qtest_write_fail(s, "writel", addr, value);
+}
+
+void qtest_writeq_fail(QTestState *s, uint64_t addr, uint64_t value)
+{
+ qtest_write_fail(s, "writeq", addr, value);
+}
+
static uint64_t qtest_read(QTestState *s, const char *cmd, uint64_t addr)
{
gchar **args;
@@ -1138,6 +1181,12 @@ static uint64_t qtest_read(QTestState *s, const char *cmd, uint64_t addr)
return value;
}
+static void qtest_read_fail(QTestState *s, const char *cmd, uint64_t addr)
+{
+ qtest_sendf(s, "%s 0x%" PRIx64 "\n", cmd, addr);
+ qtest_rsp_fail(s);
+}
+
uint8_t qtest_readb(QTestState *s, uint64_t addr)
{
return qtest_read(s, "readb", addr);
@@ -1158,6 +1207,26 @@ uint64_t qtest_readq(QTestState *s, uint64_t addr)
return qtest_read(s, "readq", addr);
}
+void qtest_readb_fail(QTestState *s, uint64_t addr)
+{
+ qtest_read_fail(s, "readb", addr);
+}
+
+void qtest_readw_fail(QTestState *s, uint64_t addr)
+{
+ qtest_read_fail(s, "readw", addr);
+}
+
+void qtest_readl_fail(QTestState *s, uint64_t addr)
+{
+ qtest_read_fail(s, "readl", addr);
+}
+
+void qtest_readq_fail(QTestState *s, uint64_t addr)
+{
+ qtest_read(s, "readq", addr);
+}
+
static int hex2nib(char ch)
{
if (ch >= '0' && ch <= '9') {
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 17/25] tests/qtest: add flexcomm tests
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (15 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 16/25] system/qtest: add APIS to check for memory access failures Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 18/25] tests/qtest: add flexcomm usart tests Octavian Purdila
` (7 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add flexcomm function selection unit tests.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
tests/qtest/flexcomm-test.c | 82 +++++++++++++++++++++++++++++++++++++
tests/qtest/meson.build | 1 +
2 files changed, 83 insertions(+)
create mode 100644 tests/qtest/flexcomm-test.c
diff --git a/tests/qtest/flexcomm-test.c b/tests/qtest/flexcomm-test.c
new file mode 100644
index 0000000000..ffbee8bfb8
--- /dev/null
+++ b/tests/qtest/flexcomm-test.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/main-loop.h"
+#include "exec/memory.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+
+#include "hw/misc/flexcomm.h"
+#include "hw/arm/svd/flexcomm.h"
+#include "hw/arm/svd/rt500.h"
+#include "reg-utils.h"
+
+#define FLEXCOMM_BASE RT500_FLEXCOMM0_BASE
+
+static void select_test(gconstpointer data)
+{
+ static const unsigned persel[] = {
+ FLEXCOMM_PERSEL_USART,
+ FLEXCOMM_PERSEL_SPI,
+ FLEXCOMM_PERSEL_I2C,
+ };
+
+ g_assert(REG32_READ_FIELD(FLEXCOMM, PSELID, PERSEL) == 0);
+
+ /* no register access until a function is selected */
+ readl_fail(FLEXCOMM_BASE);
+ writel_fail(FLEXCOMM_BASE, 0);
+
+ for (int i = 0; i < ARRAY_SIZE(persel); i++) {
+
+ REG32_WRITE(FLEXCOMM, PSELID, persel[i]);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM, PSELID, PERSEL), ==,
+ persel[i]);
+
+ /* test that we can access function registers */
+ writel(FLEXCOMM_BASE, 0xabcd);
+ readl(FLEXCOMM_BASE);
+ }
+
+ /* try to select something invalid */
+ REG32_WRITE(FLEXCOMM, PSELID, 7);
+ /* check for no function selected */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM, PSELID, PERSEL), ==, 0);
+
+ /* now select and lock USART */
+ REG32_WRITE(FLEXCOMM, PSELID,
+ FIELD_DP32(FLEXCOMM_PERSEL_USART, FLEXCOMM_PSELID, LOCK, 1));
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM, PSELID, PERSEL), ==,
+ FLEXCOMM_PERSEL_USART);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM, PSELID, LOCK), ==, 1);
+
+ /* try to change the selection to spi */
+ REG32_WRITE(FLEXCOMM, PSELID, FLEXCOMM_PERSEL_SPI);
+ /* it should still be locked USART */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM, PSELID, PERSEL), ==,
+ FLEXCOMM_PERSEL_USART);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM, PSELID, LOCK), ==, 1);
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+
+ qtest_add_data_func("/flexcomm/select", NULL, select_test);
+ qtest_start("-M rt595-evk");
+ ret = g_test_run();
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index fc852f3d8b..cb35778ce6 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -231,6 +231,7 @@ qtests_arm = \
(config_all_devices.has_key('CONFIG_FSI_APB2OPB_ASPEED') ? ['aspeed_fsi-test'] : []) + \
(config_all_devices.has_key('CONFIG_STM32L4X5_SOC') and
config_all_devices.has_key('CONFIG_DM163')? ['dm163-test'] : []) + \
+ (config_all_devices.has_key('CONFIG_FLEXCOMM')? ['flexcomm-test'] : []) + \
['arm-cpu-features',
'boot-serial-test']
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 18/25] tests/qtest: add flexcomm usart tests
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (16 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 17/25] tests/qtest: add flexcomm tests Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 19/25] hw/misc: add i2c-tester Octavian Purdila
` (6 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add flexcomm usart polling and irq unit tests.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
tests/qtest/flexcomm-usart-test.c | 316 ++++++++++++++++++++++++++++++
tests/qtest/meson.build | 3 +-
2 files changed, 318 insertions(+), 1 deletion(-)
create mode 100644 tests/qtest/flexcomm-usart-test.c
diff --git a/tests/qtest/flexcomm-usart-test.c b/tests/qtest/flexcomm-usart-test.c
new file mode 100644
index 0000000000..0ffa49dd6f
--- /dev/null
+++ b/tests/qtest/flexcomm-usart-test.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include <glib/gstdio.h>
+
+#include "io/channel-socket.h"
+#include "qemu/config-file.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+#include "qemu/sockets.h"
+#include "sysemu/sysemu.h"
+#include "qemu/main-loop.h"
+#include "qemu/option.h"
+#include "exec/memory.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+
+#include "hw/misc/flexcomm.h"
+#include "hw/arm/svd/flexcomm_usart.h"
+#include "hw/arm/svd/rt500.h"
+#include "reg-utils.h"
+
+#define FLEXCOMM_BASE RT500_FLEXCOMM0_BASE
+#define FLEXCOMM_USART_BASE RT500_FLEXCOMM0_BASE
+#define DEVICE_NAME "/machine/soc/flexcomm0"
+
+struct TestState {
+ QTestState *qtest;
+ QIOChannel *ioc;
+};
+
+static void polling_test(gconstpointer user_data)
+{
+ struct TestState *t = (struct TestState *)user_data;
+ uint32_t tmp;
+ char byte;
+ int fifo_size;
+ QDict *resp;
+
+ resp = qmp("{\"execute\": \"system_reset\"}");
+ qdict_unref(resp);
+
+ /* select and lock USART */
+ tmp = FIELD_DP32(FLEXCOMM_PERSEL_USART, FLEXCOMM_PSELID, LOCK, 1);
+ REG32_WRITE(FLEXCOMM, PSELID, tmp);
+
+ fifo_size = REG32_READ_FIELD(FLEXCOMM_USART, FIFOSIZE, FIFOSIZE);
+
+ /* enable USART */
+ REG32_WRITE_FIELD(FLEXCOMM_USART, CFG, ENABLE, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, CFG, ENABLE), ==, 1);
+
+ /* enable TX and RX FIFO */
+ REG32_WRITE_FIELD(FLEXCOMM_USART, FIFOCFG, ENABLETX, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOCFG, ENABLETX),
+ ==, 1);
+ REG32_WRITE_FIELD(FLEXCOMM_USART, FIFOCFG, ENABLERX, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOCFG, ENABLERX),
+ ==, 1);
+
+ /* test writes and fifo counters wrap */
+ for (int i = 0; i < fifo_size / 2; i++) {
+ /* check fifostat */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, RXFULL),
+ ==, 0);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, RXNOTEMPTY),
+ ==, 0);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, TXNOTFULL),
+ ==, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, TXEMPTY),
+ ==, 1);
+
+ REG32_WRITE(FLEXCOMM_USART, FIFOWR, 'a' + i);
+ qio_channel_read(t->ioc, &byte, 1, &error_abort);
+ g_assert_cmpuint(byte, ==, 'a' + i);
+ }
+
+ /* test reads and fifo level */
+
+ for (int i = 0; i < fifo_size / 2; i++) {
+ byte = 'A' + i;
+ g_assert_cmpuint(qio_channel_write(t->ioc, &byte, 1, &error_abort),
+ ==, 1);
+ }
+
+ /* wait for the RXLVL to update */
+ WAIT_REG32_FIELD(1000, FLEXCOMM_USART, FIFOSTAT, RXLVL,
+ fifo_size / 2);
+
+ /* check fifo stat */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, RXFULL),
+ ==, 0);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, RXNOTEMPTY),
+ ==, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, TXNOTFULL),
+ ==, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, TXEMPTY),
+ ==, 1);
+
+ /* send until FIFO is full */
+ for (int i = fifo_size / 2; i < fifo_size; i++) {
+ byte = 'A' + i;
+ g_assert_cmpuint(qio_channel_write(t->ioc, &byte, 1, &error_abort),
+ ==, 1);
+ }
+
+ /* wait for the RXLVL to update */
+ WAIT_REG32_FIELD(1000, FLEXCOMM_USART, FIFOSTAT, RXLVL, fifo_size);
+
+ /* check fifo stat */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, RXFULL),
+ ==, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, RXNOTEMPTY),
+ ==, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, TXNOTFULL),
+ ==, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, TXEMPTY),
+ ==, 1);
+
+ /* check read no pop */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFORDNOPOP, RXDATA),
+ ==, 'A');
+
+ /* now read from the fifo */
+ for (int i = 0; i < fifo_size; i++) {
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFORD, RXDATA),
+ ==, 'A' + i);
+ }
+
+ /* check fifostat */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, RXFULL), ==, 0);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, RXNOTEMPTY),
+ ==, 0);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, TXNOTFULL),
+ ==, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, TXEMPTY),
+ ==, 1);
+}
+
+static void irq_test(gconstpointer user_data)
+{
+ struct TestState *t = (struct TestState *)user_data;
+ char buf[256] = { 0, };
+ uint32_t tmp;
+ QDict *resp;
+
+ resp = qmp("{\"execute\": \"system_reset\"}");
+ qdict_unref(resp);
+
+ qtest_irq_intercept_out_named(t->qtest, DEVICE_NAME,
+ SYSBUS_DEVICE_GPIO_IRQ);
+
+ /* select and lock FLEXCOMM_USART */
+ tmp = FIELD_DP32(FLEXCOMM_PERSEL_USART, FLEXCOMM_PSELID, LOCK, 1);
+ REG32_WRITE(FLEXCOMM, PSELID, tmp);
+
+ /*
+ * set RX IRQ/DMA trigger level to 4 bytes - value 3 in FIFOTRIG
+ *
+ * 0000 - Trigger when the RX FIFO has received 1 entry (is no longer empty)
+ * 0001 - Trigger when the RX FIFO has received 2 entries
+ * 1111 - Trigger when the RX FIFO has received 16 entries (has become full)
+ */
+ REG32_WRITE_FIELD(FLEXCOMM_USART, FIFOTRIG, RXLVL, 3);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOTRIG, RXLVL),
+ ==, 3);
+
+ /* enable RX trigger for IRQ/DMA */
+ REG32_WRITE_FIELD(FLEXCOMM_USART, FIFOTRIG, RXLVLENA, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOTRIG, RXLVLENA),
+ ==, 1);
+
+ /* enable RXLVL interrupt */
+ REG32_WRITE_FIELD(FLEXCOMM_USART, FIFOINTENSET, RXLVL, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOINTENSET, RXLVL),
+ ==, 1);
+
+ /* enable FLEXCOMM_USART */
+ REG32_WRITE_FIELD(FLEXCOMM_USART, CFG, ENABLE, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, CFG, ENABLE),
+ ==, 1);
+
+ /* enable TX and RX FIFO */
+ REG32_WRITE_FIELD(FLEXCOMM_USART, FIFOCFG, ENABLETX, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOCFG, ENABLETX),
+ ==, 1);
+ REG32_WRITE_FIELD(FLEXCOMM_USART, FIFOCFG, ENABLERX, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOCFG, ENABLERX),
+ ==, 1);
+
+ /* check interrupt status */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOINTSTAT, RXLVL),
+ ==, 0);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOINTSTAT, TXLVL),
+ ==, 0);
+ g_assert_false(get_irq(0));
+
+ /* enable TX trigger for IRQ/DMA */
+ REG32_WRITE_FIELD(FLEXCOMM_USART, FIFOTRIG, TXLVLENA, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOTRIG, TXLVLENA),
+ ==, 1);
+
+ /* enable irq for TX */
+ REG32_WRITE_FIELD(FLEXCOMM_USART, FIFOINTENSET, TXLVL, 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOINTENSET, TXLVL),
+ ==, 1);
+
+ /* check TX irq */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOINTSTAT, TXLVL),
+ ==, 1);
+ g_assert_true(get_irq(0));
+
+ /* disable irq for TX */
+ REG32_WRITE_FIELD(FLEXCOMM_USART, FIFOTRIG, TXLVLENA, 0);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOTRIG, TXLVLENA),
+ ==, 0);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOINTSTAT, TXLVL),
+ ==, 0);
+ g_assert_false(get_irq(0));
+
+ /* send 3 bytes */
+ g_assert_cmpuint(qio_channel_write(t->ioc, buf, 3, &error_abort),
+ ==, 3);
+
+ /* check that we have 3 bytes in the fifo */
+ WAIT_REG32_FIELD(1000, FLEXCOMM_USART, FIFOSTAT, RXLVL, 3);
+
+ /* and no interrupt has been triggered yet */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOINTSTAT, RXLVL),
+ ==, 0);
+ g_assert_false(get_irq(0));
+
+ /* push it over the edge */
+ g_assert_cmpuint(qio_channel_write(t->ioc, buf, 1, &error_abort), ==, 1);
+
+ /* check that we have 4 bytes in the fifo */
+ WAIT_REG32_FIELD(1000, FLEXCOMM_USART, FIFOSTAT, RXLVL, 4);
+
+ /* and the interrupt has been triggered */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOINTSTAT, RXLVL),
+ ==, 1);
+ g_assert_true(get_irq(0));
+
+ /* read one byte from the fifo */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFORD, RXDATA),
+ ==, 0);
+
+ /* we should have 3 bytes in the FIFO */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOSTAT, RXLVL),
+ ==, 3);
+
+ /* and no interrupts active */
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_USART, FIFOINTSTAT, RXLVL),
+ ==, 0);
+ g_assert_false(get_irq(0));
+}
+
+static void close_ioc(void *ioc)
+{
+ qio_channel_close(ioc, NULL);
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+ struct TestState test;
+ char *tmp_path = g_dir_make_tmp("qemu-flexcomm-usart-test.XXXXXX", NULL);
+ SocketAddress addr = {
+ .type = SOCKET_ADDRESS_TYPE_UNIX,
+ .u.q_unix.path = g_build_filename(tmp_path, "sock", NULL),
+ };
+ char *args;
+ QIOChannelSocket *lioc;
+
+ module_call_init(MODULE_INIT_QOM);
+ g_test_init(&argc, &argv, NULL);
+
+ lioc = qio_channel_socket_new();
+ qio_channel_socket_listen_sync(lioc, &addr, 1, &error_abort);
+
+ qtest_add_data_func("/flexcomm-usart/polling", &test, polling_test);
+ qtest_add_data_func("/flexcomm-usart/irq", &test, irq_test);
+
+ args = g_strdup_printf("-M rt595-evk "
+ "-chardev socket,id=flexcomm0-usart,path=%s",
+ addr.u.q_unix.path);
+ test.qtest = qtest_start(args);
+
+ qio_channel_wait(QIO_CHANNEL(lioc), G_IO_IN);
+ test.ioc = QIO_CHANNEL(qio_channel_socket_accept(lioc, &error_abort));
+ g_assert(test.ioc);
+ qtest_add_abrt_handler(close_ioc, test.ioc);
+
+ ret = g_test_run();
+
+ qtest_end();
+
+ qtest_remove_abrt_handler(test.ioc);
+ g_unlink(addr.u.q_unix.path);
+ g_free(addr.u.q_unix.path);
+ g_rmdir(tmp_path);
+ g_free(tmp_path);
+ g_free(args);
+ object_unref(OBJECT(test.ioc));
+ object_unref(OBJECT(lioc));
+
+ return ret;
+}
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index cb35778ce6..663e44f3c6 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -231,7 +231,7 @@ qtests_arm = \
(config_all_devices.has_key('CONFIG_FSI_APB2OPB_ASPEED') ? ['aspeed_fsi-test'] : []) + \
(config_all_devices.has_key('CONFIG_STM32L4X5_SOC') and
config_all_devices.has_key('CONFIG_DM163')? ['dm163-test'] : []) + \
- (config_all_devices.has_key('CONFIG_FLEXCOMM')? ['flexcomm-test'] : []) + \
+ (config_all_devices.has_key('CONFIG_FLEXCOMM') ? ['flexcomm-test', 'flexcomm-usart-test'] : []) + \
['arm-cpu-features',
'boot-serial-test']
@@ -348,6 +348,7 @@ qtests = {
'virtio-net-failover': files('migration-helpers.c'),
'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'),
'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'),
+ 'flexcomm-usart-test': [io],
}
if vnc.found()
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 19/25] hw/misc: add i2c-tester
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (17 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 18/25] tests/qtest: add flexcomm usart tests Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 20:05 ` Corey Minyard
2024-09-18 19:22 ` [PATCH 20/25] tests/qtest: add tests for flexcomm i2c Octavian Purdila
` (5 subsequent siblings)
24 siblings, 1 reply; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add a simple i2c peripheral to be used for testing I2C device
models. The peripheral has a fixed number of registers that can be
read and written.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
include/hw/misc/i2c_tester.h | 30 ++++++++++
hw/misc/i2c_tester.c | 109 +++++++++++++++++++++++++++++++++++
hw/misc/Kconfig | 5 ++
hw/misc/meson.build | 2 +
4 files changed, 146 insertions(+)
create mode 100644 include/hw/misc/i2c_tester.h
create mode 100644 hw/misc/i2c_tester.c
diff --git a/include/hw/misc/i2c_tester.h b/include/hw/misc/i2c_tester.h
new file mode 100644
index 0000000000..f6b6491008
--- /dev/null
+++ b/include/hw/misc/i2c_tester.h
@@ -0,0 +1,30 @@
+/*
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_I2C_TESTER_H
+#define HW_I2C_TESTER_H
+
+#include "qemu/osdep.h"
+#include "hw/i2c/i2c.h"
+#include "hw/irq.h"
+
+#define I2C_TESTER_NUM_REGS 0x31
+
+#define TYPE_I2C_TESTER "i2c-tester"
+#define I2C_TESTER(obj) OBJECT_CHECK(I2cTesterState, (obj), TYPE_I2C_TESTER)
+
+typedef struct {
+ I2CSlave i2c;
+ bool set_reg_idx;
+ uint8_t reg_idx;
+ uint8_t regs[I2C_TESTER_NUM_REGS];
+} I2cTesterState;
+
+#endif /* HW_I2C_TESTER_H */
diff --git a/hw/misc/i2c_tester.c b/hw/misc/i2c_tester.c
new file mode 100644
index 0000000000..77ce8bf91a
--- /dev/null
+++ b/hw/misc/i2c_tester.c
@@ -0,0 +1,109 @@
+/*
+ * Simple I2C peripheral for testing I2C device models.
+ *
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "hw/misc/i2c_tester.h"
+
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "migration/vmstate.h"
+
+static void i2c_tester_reset_enter(Object *o, ResetType type)
+{
+ I2cTesterState *s = I2C_TESTER(o);
+
+ s->set_reg_idx = false;
+ s->reg_idx = 0;
+ memset(s->regs, 0, I2C_TESTER_NUM_REGS);
+}
+
+static int i2c_tester_event(I2CSlave *i2c, enum i2c_event event)
+{
+ I2cTesterState *s = I2C_TESTER(i2c);
+
+ if (event == I2C_START_SEND) {
+ s->set_reg_idx = true;
+ }
+
+ return 0;
+}
+
+static uint8_t i2c_tester_rx(I2CSlave *i2c)
+{
+ I2cTesterState *s = I2C_TESTER(i2c);
+
+ if (s->reg_idx >= I2C_TESTER_NUM_REGS) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid reg 0x%02x\n", __func__,
+ s->reg_idx);
+ return I2C_NACK;
+ }
+
+ return s->regs[s->reg_idx];
+}
+
+static int i2c_tester_tx(I2CSlave *i2c, uint8_t data)
+{
+ I2cTesterState *s = I2C_TESTER(i2c);
+
+ if (s->set_reg_idx) {
+ /* Setting the register in which the operation will be done. */
+ s->reg_idx = data;
+ s->set_reg_idx = false;
+ return 0;
+ }
+
+ if (s->reg_idx >= I2C_TESTER_NUM_REGS) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid reg 0x%02x\n", __func__,
+ s->reg_idx);
+ return I2C_NACK;
+ }
+
+ /* Write reg data. */
+ s->regs[s->reg_idx] = data;
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_i2c_tester = {
+ .name = "i2c-tester",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_I2C_SLAVE(i2c, I2cTesterState),
+ VMSTATE_BOOL(set_reg_idx, I2cTesterState),
+ VMSTATE_UINT8(reg_idx, I2cTesterState),
+ VMSTATE_UINT8_ARRAY(regs, I2cTesterState, I2C_TESTER_NUM_REGS),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void i2c_tester_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ ResettableClass *rc = RESETTABLE_CLASS(oc);
+ I2CSlaveClass *isc = I2C_SLAVE_CLASS(oc);
+
+ rc->phases.enter = i2c_tester_reset_enter;
+ dc->vmsd = &vmstate_i2c_tester;
+ isc->event = i2c_tester_event;
+ isc->recv = i2c_tester_rx;
+ isc->send = i2c_tester_tx;
+}
+
+static const TypeInfo i2c_tester_types[] = {
+ {
+ .name = TYPE_I2C_TESTER,
+ .parent = TYPE_I2C_SLAVE,
+ .instance_size = sizeof(I2cTesterState),
+ .class_init = i2c_tester_class_init
+ },
+};
+
+DEFINE_TYPES(i2c_tester_types);
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 4b688aead2..3e93c12c8e 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -213,6 +213,11 @@ config IOSB
config XLNX_VERSAL_TRNG
bool
+config I2C_TESTER
+ bool
+ default y if TEST_DEVICES
+ depends on I2C
+
config FLEXCOMM
bool
select I2C
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index faaf2671ba..4f22231fa3 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -158,6 +158,8 @@ system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c'))
# HPPA devices
system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c'))
+system_ss.add(when: 'CONFIG_I2C_TESTER', if_true: files('i2c_tester.c'))
+
system_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm.c'))
system_ss.add(when: 'CONFIG_RT500_CLKCTL', if_true: files('rt500_clkctl0.c', 'rt500_clkctl1.c'))
system_ss.add(when: 'CONFIG_RT500_RSTCTL', if_true: files('rt500_rstctl.c'))
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 20/25] tests/qtest: add tests for flexcomm i2c
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (18 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 19/25] hw/misc: add i2c-tester Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 21/25] hw/ssi: allow NULL realize callbacks for peripherals Octavian Purdila
` (4 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add master mode tests for flexcomm i2c.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
tests/qtest/flexcomm-i2c-test.c | 170 ++++++++++++++++++++++++++++++++
tests/qtest/meson.build | 2 +-
2 files changed, 171 insertions(+), 1 deletion(-)
create mode 100644 tests/qtest/flexcomm-i2c-test.c
diff --git a/tests/qtest/flexcomm-i2c-test.c b/tests/qtest/flexcomm-i2c-test.c
new file mode 100644
index 0000000000..45f31da7de
--- /dev/null
+++ b/tests/qtest/flexcomm-i2c-test.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2024 Google LLC.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "qemu/config-file.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+#include "qemu/sockets.h"
+#include "sysemu/sysemu.h"
+#include "qemu/main-loop.h"
+#include "qemu/option.h"
+#include "exec/memory.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-core.h"
+
+#include "hw/misc/flexcomm.h"
+#include "hw/arm/svd/flexcomm_i2c.h"
+#include "hw/arm/svd/rt500.h"
+#include "hw/misc/i2c_tester.h"
+#include "reg-utils.h"
+
+#define PERIPH_ADDR (0x50)
+#define INVALID_ADDR (0x10)
+
+#define REG_ADDR 11
+#define REG_VALUE 0xAA
+
+#define FLEXCOMM_BASE RT500_FLEXCOMM0_BASE
+#define FLEXCOMM_I2C_BASE RT500_FLEXCOMM0_BASE
+#define DEVICE_NAME "/machine/soc/flexcomm0"
+
+struct TestState {
+ QTestState *qtest;
+};
+
+static void master_test(gconstpointer user_data)
+{
+ struct TestState *t = (struct TestState *)user_data;
+ uint32_t tmp;
+
+ qtest_irq_intercept_out_named(t->qtest, DEVICE_NAME,
+ SYSBUS_DEVICE_GPIO_IRQ);
+
+ /* Select and lock I2C */
+ tmp = FLEXCOMM_PERSEL_I2C;
+ FIELD_DP32(tmp, FLEXCOMM_PSELID, LOCK, 1);
+ REG32_WRITE(FLEXCOMM, PSELID, tmp);
+
+ /* Enable master mode */
+ REG32_WRITE_FIELD(FLEXCOMM_I2C, CFG, MSTEN, 1);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, CFG, MSTEN) == 1);
+
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTPENDING) == 1);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTSTATE) ==
+ MSTSTATE_IDLE);
+
+ /* Enable interrupts */
+ REG32_WRITE_FIELD(FLEXCOMM_I2C, INTENSET, MSTPENDINGEN, 1);
+ g_assert_true(get_irq(0));
+
+ /* start for invalid address */
+ REG32_WRITE(FLEXCOMM_I2C, MSTDAT, INVALID_ADDR);
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTSTART, 1);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTSTATE) ==
+ MSTSTATE_NAKADR);
+ g_assert_true(get_irq(0));
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTSTOP, 1);
+
+ /* write past the last register */
+ REG32_WRITE_FIELD(FLEXCOMM_I2C, MSTDAT, DATA, PERIPH_ADDR);
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTSTART, 1);
+ g_assert_true(get_irq(0));
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTSTATE) ==
+ MSTSTATE_TXRDY);
+ REG32_WRITE_FIELD(FLEXCOMM_I2C, MSTDAT, DATA, I2C_TESTER_NUM_REGS + 10);
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTCONTINUE, 1);
+ g_assert_true(get_irq(0));
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTSTATE) ==
+ MSTSTATE_TXRDY);
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTCONTINUE, 1);
+ g_assert_true(get_irq(0));
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTSTATE) ==
+ MSTSTATE_NAKDAT);
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTSTOP, 1);
+
+ /* write value to register */
+ REG32_WRITE_FIELD(FLEXCOMM_I2C, MSTDAT, DATA, PERIPH_ADDR);
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTSTART, 1);
+ g_assert_true(get_irq(0));
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTSTATE) ==
+ MSTSTATE_TXRDY);
+ REG32_WRITE_FIELD(FLEXCOMM_I2C, MSTDAT, DATA, REG_ADDR);
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTCONTINUE, 1);
+ g_assert_true(get_irq(0));
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTSTATE) ==
+ MSTSTATE_TXRDY);
+ REG32_WRITE_FIELD(FLEXCOMM_I2C, MSTDAT, DATA, REG_VALUE);
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTCONTINUE, 1);
+ g_assert_true(get_irq(0));
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTSTATE) ==
+ MSTSTATE_TXRDY);
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTSTOP, 1);
+ g_assert_true(get_irq(0));
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTSTATE) ==
+ MSTSTATE_IDLE);
+
+ /* read value back from register */
+ REG32_WRITE_FIELD(FLEXCOMM_I2C, MSTDAT, DATA, PERIPH_ADDR);
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTSTART, 1);
+ g_assert_true(get_irq(0));
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTSTATE) ==
+ MSTSTATE_TXRDY);
+ REG32_WRITE_FIELD(FLEXCOMM_I2C, MSTDAT, DATA, REG_ADDR);
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTCONTINUE, 1);
+ g_assert_true(get_irq(0));
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTSTATE) ==
+ MSTSTATE_TXRDY);
+ REG32_WRITE_FIELD(FLEXCOMM_I2C, MSTDAT, DATA, (PERIPH_ADDR + 1));
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTSTART, 1);
+ g_assert_true(get_irq(0));
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTSTATE) ==
+ MSTSTATE_RXRDY);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_I2C, MSTDAT, DATA), ==,
+ REG_VALUE);
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTSTOP, 1);
+
+ /*
+ * Check that the master ended the transaction (i.e. i2c_end_transfer was
+ * called). If the master does not properly end the transaction this would
+ * be seen as a restart and it would not be NACKed.
+ */
+ REG32_WRITE_FIELD(FLEXCOMM_I2C, MSTDAT, DATA, INVALID_ADDR);
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTSTART, 1);
+
+ g_assert(REG32_READ_FIELD(FLEXCOMM_I2C, STAT, MSTSTATE) ==
+ MSTSTATE_NAKADR);
+ g_assert_true(get_irq(0));
+ REG32_WRITE_FIELD_NOUPDATE(FLEXCOMM_I2C, MSTCTL, MSTSTOP, 1);
+
+ /* Disable interrupts */
+ REG32_WRITE_FIELD(FLEXCOMM_I2C, INTENCLR, MSTPENDINGCLR, 1);
+ g_assert_false(get_irq(0));
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+ struct TestState test;
+
+ module_call_init(MODULE_INIT_QOM);
+ g_test_init(&argc, &argv, NULL);
+
+ qtest_add_data_func("/flexcomm-i2c/master", &test, master_test);
+
+ test.qtest = qtest_start("-M rt595-evk "
+ "-device i2c-tester,address=0x50,bus=/flexcomm0-i2c");
+ ret = g_test_run();
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 663e44f3c6..74fef28551 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -231,7 +231,7 @@ qtests_arm = \
(config_all_devices.has_key('CONFIG_FSI_APB2OPB_ASPEED') ? ['aspeed_fsi-test'] : []) + \
(config_all_devices.has_key('CONFIG_STM32L4X5_SOC') and
config_all_devices.has_key('CONFIG_DM163')? ['dm163-test'] : []) + \
- (config_all_devices.has_key('CONFIG_FLEXCOMM') ? ['flexcomm-test', 'flexcomm-usart-test'] : []) + \
+ (config_all_devices.has_key('CONFIG_FLEXCOMM') ? ['flexcomm-test', 'flexcomm-usart-test', 'flexcomm-i2c-test'] : []) + \
['arm-cpu-features',
'boot-serial-test']
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 21/25] hw/ssi: allow NULL realize callbacks for peripherals
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (19 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 20/25] tests/qtest: add tests for flexcomm i2c Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 22/25] hw/misc: add spi-tester Octavian Purdila
` (3 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Signed-off-by: Octavian Purdila <tavip@google.com>
---
hw/ssi/ssi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c
index 3f357e8f16..d1f3ce7c22 100644
--- a/hw/ssi/ssi.c
+++ b/hw/ssi/ssi.c
@@ -105,7 +105,9 @@ static void ssi_peripheral_realize(DeviceState *dev, Error **errp)
}
s->spc = ssc;
- ssc->realize(s, errp);
+ if (ssc->realize) {
+ ssc->realize(s, errp);
+ }
}
static Property ssi_peripheral_properties[] = {
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 22/25] hw/misc: add spi-tester
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (20 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 21/25] hw/ssi: allow NULL realize callbacks for peripherals Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 23/25] tests/qtest: add tests for flexcomm spi Octavian Purdila
` (2 subsequent siblings)
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add a simple SPI peripheral that echoes back received data. Useful for
testing SPI controllers.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
include/hw/misc/spi_tester.h | 32 +++++++++++++++++
hw/misc/spi_tester.c | 67 ++++++++++++++++++++++++++++++++++++
hw/misc/Kconfig | 5 +++
hw/misc/meson.build | 1 +
4 files changed, 105 insertions(+)
create mode 100644 include/hw/misc/spi_tester.h
create mode 100644 hw/misc/spi_tester.c
diff --git a/include/hw/misc/spi_tester.h b/include/hw/misc/spi_tester.h
new file mode 100644
index 0000000000..8935f3f1af
--- /dev/null
+++ b/include/hw/misc/spi_tester.h
@@ -0,0 +1,32 @@
+/*
+ * Simple SPI peripheral device used for SPI controller testing.
+ *
+ * Copyright (c) 2024 Google LLC.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_SPI_TESTER_H
+#define HW_SPI_TESTER_H
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/bswap.h"
+#include "hw/irq.h"
+#include "hw/ssi/ssi.h"
+#include "qemu/timer.h"
+#include "hw/qdev-properties.h"
+
+#define TYPE_SPI_TESTER "spi-tester"
+#define SPI_TESTER(obj) OBJECT_CHECK(SpiTesterState, (obj), TYPE_SPI_TESTER)
+
+typedef struct {
+ SSIPeripheral ssidev;
+ bool cs;
+} SpiTesterState;
+
+#endif /* HW_SPI_TESTER_H */
diff --git a/hw/misc/spi_tester.c b/hw/misc/spi_tester.c
new file mode 100644
index 0000000000..2793ce52dc
--- /dev/null
+++ b/hw/misc/spi_tester.c
@@ -0,0 +1,67 @@
+/*
+ * Simple SPI peripheral echo device used for SPI controller testing.
+ *
+ * Copyright (c) 2024 Google LLC.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "migration/vmstate.h"
+#include "hw/misc/spi_tester.h"
+
+static uint32_t spi_tester_transfer(SSIPeripheral *dev, uint32_t value)
+{
+ SpiTesterState *s = SPI_TESTER(dev);
+
+ if (s->cs) {
+ return 0;
+ }
+
+ return value;
+}
+
+static int spi_tester_set_cs(SSIPeripheral *dev, bool select)
+{
+ SpiTesterState *s = SPI_TESTER(dev);
+
+ s->cs = select;
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_spi_tester = {
+ .name = "spi-tester",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_SSI_PERIPHERAL(ssidev, SpiTesterState),
+ VMSTATE_BOOL(cs, SpiTesterState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void spi_tester_class_init(ObjectClass *klass, void *data)
+{
+ SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->vmsd = &vmstate_spi_tester;
+ k->transfer = spi_tester_transfer;
+ k->set_cs = spi_tester_set_cs;
+ k->cs_polarity = SSI_CS_LOW;
+}
+
+static const TypeInfo spi_tester_types[] = {
+ {
+ .name = TYPE_SPI_TESTER,
+ .parent = TYPE_SSI_PERIPHERAL,
+ .instance_size = sizeof(SpiTesterState),
+ .class_init = spi_tester_class_init,
+ },
+};
+
+DEFINE_TYPES(spi_tester_types);
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 3e93c12c8e..484ee3149f 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -218,6 +218,11 @@ config I2C_TESTER
default y if TEST_DEVICES
depends on I2C
+config SPI_TESTER
+ bool
+ default y if TEST_DEVICES
+ depends on SSI
+
config FLEXCOMM
bool
select I2C
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 4f22231fa3..413171f379 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -159,6 +159,7 @@ system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c'))
system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c'))
system_ss.add(when: 'CONFIG_I2C_TESTER', if_true: files('i2c_tester.c'))
+system_ss.add(when: 'CONFIG_SPI_TESTER', if_true: files('spi_tester.c'))
system_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm.c'))
system_ss.add(when: 'CONFIG_RT500_CLKCTL', if_true: files('rt500_clkctl0.c', 'rt500_clkctl1.c'))
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 23/25] tests/qtest: add tests for flexcomm spi
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (21 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 22/25] hw/misc: add spi-tester Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 24/25] systems/qtest: add device clock APIs Octavian Purdila
2024-09-18 19:22 ` [PATCH 25/25] tests/qtest: add tests for RT500's clock controller Octavian Purdila
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
From: Sebastian Ene <sebastianene@google.com>
Add master and loopback tests for flexcomm spi.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
[tavip: add master mode test, convert to qtest]
Signed-off-by: Octavian Purdila <tavip@google.com>
---
tests/qtest/flexcomm-spi-test.c | 145 ++++++++++++++++++++++++++++++++
tests/qtest/meson.build | 2 +-
2 files changed, 146 insertions(+), 1 deletion(-)
create mode 100644 tests/qtest/flexcomm-spi-test.c
diff --git a/tests/qtest/flexcomm-spi-test.c b/tests/qtest/flexcomm-spi-test.c
new file mode 100644
index 0000000000..4658835b8f
--- /dev/null
+++ b/tests/qtest/flexcomm-spi-test.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2024 Google LLC.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "qemu/config-file.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+#include "qemu/sockets.h"
+#include "sysemu/sysemu.h"
+#include "qemu/main-loop.h"
+#include "qemu/option.h"
+#include "exec/memory.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-core.h"
+
+#include "hw/misc/flexcomm.h"
+#include "hw/arm/svd/flexcomm_spi.h"
+#include "hw/arm/svd/rt500.h"
+#include "reg-utils.h"
+
+/* The number of words sent on the SPI in loopback mode. */
+#define SEQ_LOOPBACK_MODE (8)
+
+/* This value is used to set the cycle counter for the spi tester */
+#define SPI_TESTER_CONFIG (0x10)
+
+#define FLEXCOMM_BASE RT500_FLEXCOMM0_BASE
+#define FLEXCOMM_SPI_BASE RT500_FLEXCOMM0_BASE
+#define DEVICE_NAME "/machine/soc/flexcomm0"
+
+static void configure_spi(bool master, bool is_loopback_mode)
+{
+ uint32_t tmp;
+
+ /* Select and lock SPI */
+ tmp = FLEXCOMM_PERSEL_SPI;
+ FIELD_DP32(tmp, FLEXCOMM_PSELID, LOCK, 1);
+ REG32_WRITE(FLEXCOMM, PSELID, tmp);
+
+ /* Disable the FIFO */
+ REG32_WRITE_FIELD(FLEXCOMM_SPI, CFG, ENABLE, 0);
+ REG32_WRITE_FIELD(FLEXCOMM_SPI, FIFOCFG, ENABLETX, 0);
+ REG32_WRITE_FIELD(FLEXCOMM_SPI, FIFOCFG, ENABLERX, 0);
+
+ if (is_loopback_mode) {
+ /* Set up SPI interface - loop mode, master mode */
+ REG32_WRITE_FIELD(FLEXCOMM_SPI, CFG, LOOP, 1);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_SPI, CFG, LOOP) == 1);
+ }
+
+ if (master) {
+ REG32_WRITE_FIELD(FLEXCOMM_SPI, CFG, MASTER, 1);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_SPI, CFG, MASTER) == 1);
+ } else {
+ REG32_WRITE_FIELD(FLEXCOMM_SPI, CFG, MASTER, 0);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_SPI, CFG, MASTER) == 0);
+ }
+
+ /* Enable the FIFO */
+ REG32_WRITE_FIELD(FLEXCOMM_SPI, FIFOCFG, ENABLETX, 1);
+ REG32_WRITE_FIELD(FLEXCOMM_SPI, FIFOCFG, ENABLERX, 1);
+
+ /* Enable the SPI */
+ REG32_WRITE_FIELD(FLEXCOMM_SPI, CFG, ENABLE, 1);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_SPI, CFG, ENABLE) == 1);
+}
+
+/* The SPI controller running in master mode can run in loopback mode for */
+/* internal testing. Transmit and receive lines are connected together. */
+static void loopback_test(gconstpointer user_data)
+{
+ configure_spi(true, true);
+
+ /* Write a sequence */
+ for (int i = 0; i < SEQ_LOOPBACK_MODE; i++) {
+ REG32_WRITE(FLEXCOMM_SPI, FIFOWR, i);
+ }
+
+ /* Read the sequence back */
+ for (int i = 0; i < SEQ_LOOPBACK_MODE; i++) {
+ g_assert(REG32_READ_FIELD(FLEXCOMM_SPI, FIFORD, RXDATA) == i);
+ }
+}
+
+static void master_test(gconstpointer user_data)
+{
+ uint32_t tmp;
+
+ configure_spi(true, false);
+
+ REG32_WRITE_FIELD(FLEXCOMM_SPI, CFG, LSBF, 1);
+
+ /* single 16bit word transfer */
+
+ tmp = FIELD_DP32(0x1122, FLEXCOMM_SPI_FIFOWR, EOT, 1);
+ tmp = FIELD_DP32(tmp, FLEXCOMM_SPI_FIFOWR, TXSSEL0_N, 1);
+ tmp = FIELD_DP32(tmp, FLEXCOMM_SPI_FIFOWR, LEN, 0xF);
+ REG32_WRITE(FLEXCOMM_SPI, FIFOWR, tmp);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_SPI, FIFOSTAT, RXNOTEMPTY) == 1);
+ g_assert_cmpuint(REG32_READ_FIELD(FLEXCOMM_SPI, FIFORD, RXDATA),
+ ==, 0x1122);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_SPI, FIFOSTAT, RXNOTEMPTY) == 0);
+
+ /* multi word 8 bits transfer */
+
+ tmp = FIELD_DP32(0x11, FLEXCOMM_SPI_FIFOWR, TXSSEL0_N, 1);
+ tmp = FIELD_DP32(tmp, FLEXCOMM_SPI_FIFOWR, LEN, 0x7);
+ REG32_WRITE(FLEXCOMM_SPI, FIFOWR, tmp);
+ tmp = 0x22;
+ FIELD_DP32(tmp, FLEXCOMM_SPI_FIFOWR, EOT, 1);
+ FIELD_DP32(tmp, FLEXCOMM_SPI_FIFOWR, TXSSEL0_N, 1);
+ FIELD_DP32(tmp, FLEXCOMM_SPI_FIFOWR, LEN, 0x7);
+ REG32_WRITE(FLEXCOMM_SPI, FIFOWR, tmp);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_SPI, FIFOSTAT, RXNOTEMPTY) == 1);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_SPI, FIFORD, RXDATA) == 0x11);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_SPI, FIFOSTAT, RXNOTEMPTY) == 1);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_SPI, FIFORD, RXDATA) == 0x22);
+ g_assert(REG32_READ_FIELD(FLEXCOMM_SPI, FIFOSTAT, RXNOTEMPTY) == 0);
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ module_call_init(MODULE_INIT_QOM);
+ g_test_init(&argc, &argv, NULL);
+
+ qtest_add_data_func("/flexcomm-spi/loopack", NULL, loopback_test);
+ qtest_add_data_func("/flexcomm-spi/master", NULL, master_test);
+
+ qtest_start("-M rt595-evk -device spi-tester,bus=/flexcomm0-spi");
+ ret = g_test_run();
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 74fef28551..2cb0fa08c0 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -231,7 +231,7 @@ qtests_arm = \
(config_all_devices.has_key('CONFIG_FSI_APB2OPB_ASPEED') ? ['aspeed_fsi-test'] : []) + \
(config_all_devices.has_key('CONFIG_STM32L4X5_SOC') and
config_all_devices.has_key('CONFIG_DM163')? ['dm163-test'] : []) + \
- (config_all_devices.has_key('CONFIG_FLEXCOMM') ? ['flexcomm-test', 'flexcomm-usart-test', 'flexcomm-i2c-test'] : []) + \
+ (config_all_devices.has_key('CONFIG_FLEXCOMM') ? ['flexcomm-test', 'flexcomm-usart-test', 'flexcomm-i2c-test', 'flexcomm-spi-test'] : []) + \
['arm-cpu-features',
'boot-serial-test']
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 24/25] systems/qtest: add device clock APIs
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (22 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 23/25] tests/qtest: add tests for flexcomm spi Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
2024-09-18 19:22 ` [PATCH 25/25] tests/qtest: add tests for RT500's clock controller Octavian Purdila
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add qtest APIs to check the device clock frequency.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
include/hw/qdev-clock.h | 10 +++++++
tests/qtest/libqtest-single.h | 24 +++++++++++++++++
tests/qtest/libqtest.h | 22 +++++++++++++++
hw/core/qdev-clock.c | 2 +-
system/qtest.c | 51 +++++++++++++++++++++++++++++++++++
tests/qtest/libqtest.c | 29 ++++++++++++++++++++
6 files changed, 137 insertions(+), 1 deletion(-)
diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h
index ffa0f7ba09..19ed34ae88 100644
--- a/include/hw/qdev-clock.h
+++ b/include/hw/qdev-clock.h
@@ -15,6 +15,7 @@
#define QDEV_CLOCK_H
#include "hw/clock.h"
+#include "hw/qdev-core.h"
/**
* qdev_init_clock_in:
@@ -161,4 +162,13 @@ typedef struct ClockPortInitElem ClockPortInitArray[];
*/
void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks);
+/**
+ * qdev_get_clocklist:
+ * @dev: the device to find clock for
+ * @name: clock name
+ *
+ * Returns: a named clock list entry or NULL if the clock was not found
+ */
+NamedClockList *qdev_get_clocklist(DeviceState *dev, const char *name);
+
#endif /* QDEV_CLOCK_H */
diff --git a/tests/qtest/libqtest-single.h b/tests/qtest/libqtest-single.h
index c22037c8b2..51eb69ff74 100644
--- a/tests/qtest/libqtest-single.h
+++ b/tests/qtest/libqtest-single.h
@@ -408,4 +408,28 @@ static inline int64_t clock_step(int64_t step)
return qtest_clock_step(global_qtest, step);
}
+/**
+ * qtest_qdev_clock_in_get_hz:
+ * @path: QOM path of a device.
+ * @name: Clock name.
+ *
+ * Returns: device clock frequency in HZ
+ */
+static inline uint64_t dev_clock_in_get_hz(const char *path, const char *name)
+{
+ return qtest_dev_clock_in_get_hz(global_qtest, path, name);
+}
+
+/**
+ * qtest_qdev_clock_out_get_hz:
+ * @path: QOM path of a device.
+ * @name: Clock name.
+ *
+ * Returns: device clock frequency in HZ
+ */
+static inline uint64_t dev_clock_out_get_hz(const char *path, const char *name)
+{
+ return qtest_dev_clock_out_get_hz(global_qtest, path, name);
+}
+
#endif
diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
index f9bbeb2e60..cfb7098985 100644
--- a/tests/qtest/libqtest.h
+++ b/tests/qtest/libqtest.h
@@ -1169,4 +1169,26 @@ bool have_qemu_img(void);
*/
bool mkimg(const char *file, const char *fmt, unsigned size_mb);
+/**
+ * qtest_qdev_clock_in_get_hz:
+ * @s: #QTestState instance to operate on.
+ * @path: QOM path of a device.
+ * @name: Clock name.
+ *
+ * Returns: device clock frequency in HZ
+ */
+uint64_t qtest_dev_clock_in_get_hz(QTestState *s, const char *path,
+ const char *name);
+
+/**
+ * qtest_qdev_clock_out_get_hz:
+ * @s: #QTestState instance to operate on.
+ * @path: QOM path of a device.
+ * @name: Clock name.
+ *
+ * Returns: device clock frequency in HZ
+ */
+uint64_t qtest_dev_clock_out_get_hz(QTestState *s, const char *path,
+ const char *name);
+
#endif
diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c
index 82799577f3..3c9e2d5d73 100644
--- a/hw/core/qdev-clock.c
+++ b/hw/core/qdev-clock.c
@@ -144,7 +144,7 @@ void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks)
}
}
-static NamedClockList *qdev_get_clocklist(DeviceState *dev, const char *name)
+NamedClockList *qdev_get_clocklist(DeviceState *dev, const char *name)
{
NamedClockList *ncl;
diff --git a/system/qtest.c b/system/qtest.c
index 95bb80a2bc..465666a416 100644
--- a/system/qtest.c
+++ b/system/qtest.c
@@ -19,6 +19,7 @@
#include "exec/ioport.h"
#include "exec/memory.h"
#include "exec/tswap.h"
+#include "hw/qdev-clock.h"
#include "hw/qdev-core.h"
#include "hw/irq.h"
#include "hw/core/cpu.h"
@@ -245,6 +246,20 @@ static void *qtest_server_send_opaque;
*
* Forcibly set the given interrupt pin to the given level.
*
+ * Device clock frequency
+ * """"""""""""""""""""""
+ *
+ * .. code-block:: none
+ *
+ * > qdev_clock_out_get_hz QOM-PATH CLOCK-NAME
+ * < OK HZ
+ *
+ * .. code-block:: none
+ *
+ * > qdev_clock_in_get_hz QOM-PATH CLOCK-NAME
+ * < OK HZ
+ *
+ * where HZ is the clock frequency in hertz.
*/
static int hex2nib(char ch)
@@ -758,6 +773,42 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
qtest_send_prefix(chr);
qtest_sendf(chr, "OK %"PRIi64"\n",
(int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+ } else if (strcmp(words[0], "qdev_clock_in_get_hz") == 0 ||
+ strcmp(words[0], "qdev_clock_out_get_hz") == 0) {
+ bool is_outbound = words[0][11] == 'o';
+ DeviceState *dev;
+ NamedClockList *ncl;
+
+ g_assert(words[1]);
+ g_assert(words[2]);
+
+ dev = DEVICE(object_resolve_path(words[1], NULL));
+ if (!dev) {
+ qtest_send_prefix(chr);
+ qtest_send(chr, "FAIL Unknown device\n");
+ return;
+ }
+
+ ncl = qdev_get_clocklist(dev, words[2]);
+ if (!ncl) {
+ qtest_send_prefix(chr);
+ qtest_send(chr, "FAIL Unknown clock\n");
+ return;
+ }
+
+ if (is_outbound && !ncl->output) {
+ qtest_send_prefix(chr);
+ qtest_send(chr, "FAIL Not an output clock\n");
+ return;
+ }
+
+ if (!is_outbound && ncl->output) {
+ qtest_send_prefix(chr);
+ qtest_send(chr, "FAIL Not an input clock\n");
+ return;
+ }
+
+ qtest_sendf(chr, "OK %u\n", clock_get_hz(ncl->clock));
} else if (process_command_cb && process_command_cb(chr, words)) {
/* Command got consumed by the callback handler */
} else {
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index 4055d6b953..cc11b5f42e 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -2065,3 +2065,32 @@ bool mkimg(const char *file, const char *fmt, unsigned size_mb)
return ret && !err;
}
+
+static uint64_t qtest_dev_clock_get_hz(QTestState *s, const char *path,
+ const char *name, bool out)
+{
+ gchar **args;
+ int ret;
+ uint64_t value;
+
+ qtest_sendf(s, "qdev_clock_%s_get_hz %s %s\n", out ? "out" : "in",
+ path, name);
+ args = qtest_rsp_args(s, 2);
+ ret = qemu_strtou64(args[1], NULL, 0, &value);
+ g_assert(!ret);
+ g_strfreev(args);
+
+ return value;
+}
+
+uint64_t qtest_dev_clock_out_get_hz(QTestState *s, const char *path,
+ const char *name)
+{
+ return qtest_dev_clock_get_hz(s, path, name, true);
+}
+
+uint64_t qtest_dev_clock_in_get_hz(QTestState *s, const char *path,
+ const char *name)
+{
+ return qtest_dev_clock_get_hz(s, path, name, false);
+}
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 25/25] tests/qtest: add tests for RT500's clock controller
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
` (23 preceding siblings ...)
2024-09-18 19:22 ` [PATCH 24/25] systems/qtest: add device clock APIs Octavian Purdila
@ 2024-09-18 19:22 ` Octavian Purdila
24 siblings, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 19:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, stefanst, pbonzini, peter.maydell, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier
Add test to exercise clocks set and clear, system PLL initialization,
audio PLL initialization, systick and ostimer clock source selection.
Signed-off-by: Octavian Purdila <tavip@google.com>
---
tests/qtest/rt500-clkctl-test.c | 195 ++++++++++++++++++++++++++++++++
tests/qtest/meson.build | 1 +
2 files changed, 196 insertions(+)
create mode 100644 tests/qtest/rt500-clkctl-test.c
diff --git a/tests/qtest/rt500-clkctl-test.c b/tests/qtest/rt500-clkctl-test.c
new file mode 100644
index 0000000000..d5b83d81da
--- /dev/null
+++ b/tests/qtest/rt500-clkctl-test.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2024 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/main-loop.h"
+#include "exec/memory.h"
+#include "hw/clock.h"
+#include "hw/irq.h"
+#include "hw/qdev-clock.h"
+#include "hw/qdev-properties.h"
+
+#include "hw/misc/rt500_clkctl0.h"
+#include "hw/misc/rt500_clkctl1.h"
+#include "hw/misc/rt500_clk_freqs.h"
+#include "hw/arm/svd/rt500.h"
+#include "reg-utils.h"
+
+#define SYSCLK_HZ 200000000
+#define CLKCTL0_NAME "/machine/soc/clkctl0"
+#define CLKCTL1_NAME "/machine/soc/clkctl1"
+
+static void pscctl_test(gconstpointer user_data)
+{
+ /* rom controller clock should be enabled at reset */
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, PSCCTL0, ROM_CTRLR_CLK) == 1);
+
+ /* DSP clk is disabled at reset */
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, PSCCTL0, DSP_CLK) == 0);
+
+ /* check PSCTL_SET functionality */
+ REG32_WRITE_FIELD_NOUPDATE(RT500_CLKCTL0, PSCCTL0_SET, DSP_CLK, 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, PSCCTL0, DSP_CLK) == 1);
+
+ /* check PSCTL_CLR functionality */
+ REG32_WRITE_FIELD_NOUPDATE(RT500_CLKCTL0, PSCCTL0_CLR, DSP_CLK, 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, PSCCTL0, DSP_CLK) == 0);
+
+ /* FLEXIO clk is disabled at reset */
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, PSCCTL0, FlexIO) == 0);
+
+ /* check PSCTL_SET functionality */
+ REG32_WRITE_FIELD_NOUPDATE(RT500_CLKCTL1, PSCCTL0_SET, FlexIO, 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, PSCCTL0, FlexIO) == 1);
+
+ /* check PSCTL_CLR functionality */
+ REG32_WRITE_FIELD_NOUPDATE(RT500_CLKCTL1, PSCCTL0_CLR, FlexIO, 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, PSCCTL0, FlexIO) == 0);
+}
+
+static void audiopll0pfd_test(gconstpointer user_data)
+{
+ /* audio plls are gated at boot */
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD3_CLKGATE) == 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD2_CLKGATE) == 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD1_CLKGATE) == 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD0_CLKGATE) == 1);
+
+ /* ,,, and clocks are not ready */
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD3_CLKRDY) == 0);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD2_CLKRDY) == 0);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD1_CLKRDY) == 0);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD0_CLKRDY) == 0);
+
+ /* ungate all plls and check that clocks are ready */
+ REG32_WRITE_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD3_CLKGATE, 0);
+ REG32_WRITE_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD2_CLKGATE, 0);
+ REG32_WRITE_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD1_CLKGATE, 0);
+ REG32_WRITE_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD0_CLKGATE, 0);
+
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD3_CLKRDY) == 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD2_CLKRDY) == 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD1_CLKRDY) == 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL1, AUDIOPLL0PFD, PFD0_CLKRDY) == 1);
+}
+
+static void syspll0pfd_test(gconstpointer user_data)
+{
+ /* system plls are gated at boot */
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD3_CLKGATE) == 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD2_CLKGATE) == 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD1_CLKGATE) == 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD0_CLKGATE) == 1);
+
+ /* ,,, and clocks are not ready */
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD3_CLKRDY) == 0);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD2_CLKRDY) == 0);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD1_CLKRDY) == 0);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD0_CLKRDY) == 0);
+
+ /* ungate all plls and check that clocks are ready */
+ REG32_WRITE_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD3_CLKGATE, 0);
+ REG32_WRITE_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD2_CLKGATE, 0);
+ REG32_WRITE_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD1_CLKGATE, 0);
+ REG32_WRITE_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD0_CLKGATE, 0);
+
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD3_CLKRDY) == 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD2_CLKRDY) == 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD1_CLKRDY) == 1);
+ g_assert(REG32_READ_FIELD(RT500_CLKCTL0, SYSPLL0PFD, PFD0_CLKRDY) == 1);
+}
+
+static void systick_clk_test(gconstpointer user_data)
+{
+ /* systick is not running at reset */
+ g_assert_cmpuint(dev_clock_out_get_hz(CLKCTL0_NAME, "systick_clk"), ==, 0);
+
+ /* select divout no divisor */
+ REG32_WRITE_FIELD(RT500_CLKCTL0, SYSTICKFCLKSEL, SEL,
+ SYSTICKFCLKSEL_DIVOUT);
+ g_assert_cmpuint(dev_clock_out_get_hz(CLKCTL0_NAME, "systick_clk"),
+ ==, SYSCLK_HZ);
+
+ /* change divisor to 2 */
+ REG32_WRITE_FIELD(RT500_CLKCTL0, SYSTICKFCLKDIV, DIV, 1);
+ g_assert_cmpuint(dev_clock_out_get_hz(CLKCTL0_NAME, "systick_clk"),
+ ==, SYSCLK_HZ / 2);
+
+ /* select lpsoc */
+ REG32_WRITE_FIELD(RT500_CLKCTL0, SYSTICKFCLKSEL, SEL,
+ SYSTICKFCLKSEL_LPOSC);
+ g_assert_cmpuint(dev_clock_out_get_hz(CLKCTL0_NAME, "systick_clk"),
+ ==, LPOSC_CLK_HZ);
+
+ /* select lpsoc */
+ REG32_WRITE_FIELD(RT500_CLKCTL0, SYSTICKFCLKSEL, SEL,
+ SYSTICKFCLKSEL_32KHZRTC);
+ g_assert_cmpuint(dev_clock_out_get_hz(CLKCTL0_NAME, "systick_clk"),
+ ==, RTC32KHZ_CLK_HZ);
+
+ /* disable clock */
+ REG32_WRITE_FIELD(RT500_CLKCTL0, SYSTICKFCLKSEL, SEL,
+ SYSTICKFCLKSEL_NONE);
+ g_assert_cmpuint(dev_clock_out_get_hz(CLKCTL0_NAME, "systick_clk"),
+ ==, 0);
+}
+
+static void ostimer_clk_test(gconstpointer user_data)
+{
+ /* systick is not running at reset */
+ g_assert_cmpuint(dev_clock_out_get_hz(CLKCTL1_NAME, "ostimer_clk"), ==, 0);
+
+ /* select lpsoc */
+ REG32_WRITE_FIELD(RT500_CLKCTL1, OSEVENTTFCLKSEL, SEL,
+ OSEVENTTFCLKSEL_LPOSC);
+ g_assert_cmpuint(dev_clock_out_get_hz(CLKCTL1_NAME, "ostimer_clk"), ==,
+ LPOSC_CLK_HZ);
+
+ /* select 32khz RTC */
+ REG32_WRITE_FIELD(RT500_CLKCTL1, OSEVENTTFCLKSEL, SEL,
+ OSEVENTTFCLKSEL_32KHZRTC);
+ g_assert_cmpuint(dev_clock_out_get_hz(CLKCTL1_NAME, "ostimer_clk"), ==,
+ RTC32KHZ_CLK_HZ);
+
+ /* select hclk */
+ REG32_WRITE_FIELD(RT500_CLKCTL1, OSEVENTTFCLKSEL, SEL,
+ OSEVENTTFCLKSEL_HCLK);
+ g_assert_cmpuint(dev_clock_out_get_hz(CLKCTL1_NAME, "ostimer_clk"), ==,
+ SYSCLK_HZ);
+
+ /* disable clock */
+ REG32_WRITE_FIELD(RT500_CLKCTL1, OSEVENTTFCLKSEL, SEL,
+ OSEVENTTFCLKSEL_NONE);
+ g_assert_cmpuint(dev_clock_out_get_hz(CLKCTL1_NAME, "ostimer_clk"), ==, 0);
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+
+ qtest_add_data_func("/rt500-clkctl/pscctl-test", NULL, pscctl_test);
+ qtest_add_data_func("/rt500-clkctl/syspll0pfd-test", NULL,
+ syspll0pfd_test);
+ qtest_add_data_func("/rt500-clkctl/audiopll0pfd-test", NULL,
+ audiopll0pfd_test);
+ g_test_add_data_func("/rt500-clkctl/systick-test", NULL,
+ systick_clk_test);
+ g_test_add_data_func("/rt500-clkctl/ostimer-clk-test", NULL,
+ ostimer_clk_test);
+
+ qtest_start("-M rt595-evk");
+ ret = g_test_run();
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 2cb0fa08c0..101f6889f6 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -232,6 +232,7 @@ qtests_arm = \
(config_all_devices.has_key('CONFIG_STM32L4X5_SOC') and
config_all_devices.has_key('CONFIG_DM163')? ['dm163-test'] : []) + \
(config_all_devices.has_key('CONFIG_FLEXCOMM') ? ['flexcomm-test', 'flexcomm-usart-test', 'flexcomm-i2c-test', 'flexcomm-spi-test'] : []) + \
+ (config_all_devices.has_key('CONFIG_RT500_CLKCTL') ? ['rt500-clkctl-test'] : []) + \
['arm-cpu-features',
'boot-serial-test']
--
2.46.0.662.g92d0881bb0-goog
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH 19/25] hw/misc: add i2c-tester
2024-09-18 19:22 ` [PATCH 19/25] hw/misc: add i2c-tester Octavian Purdila
@ 2024-09-18 20:05 ` Corey Minyard
2024-09-18 23:03 ` Octavian Purdila
0 siblings, 1 reply; 36+ messages in thread
From: Corey Minyard @ 2024-09-18 20:05 UTC (permalink / raw)
To: Octavian Purdila
Cc: qemu-devel, qemu-arm, stefanst, pbonzini, peter.maydell,
marcandre.lureau, berrange, eduardo, luc, damien.hedde, alistair,
thuth, philmd, jsnow, crosa, lvivier
On Wed, Sep 18, 2024 at 12:22:47PM -0700, Octavian Purdila wrote:
> Add a simple i2c peripheral to be used for testing I2C device
> models. The peripheral has a fixed number of registers that can be
> read and written.
Why is this better than just using the eeprom device?
This has some uncommon attributes compared to most i2c devices. For
instance, most i2c devices take their address as the first bytes of a
write operation, then auto-increment after that for reads and writes.
This seems to take one address on a write after a system reset, then use
that forever.
Anyway, unless there is a compelling reason to use this over the eeprom
device, I'm going to recommend against it.
-corey
>
> Signed-off-by: Octavian Purdila <tavip@google.com>
> ---
> include/hw/misc/i2c_tester.h | 30 ++++++++++
> hw/misc/i2c_tester.c | 109 +++++++++++++++++++++++++++++++++++
> hw/misc/Kconfig | 5 ++
> hw/misc/meson.build | 2 +
> 4 files changed, 146 insertions(+)
> create mode 100644 include/hw/misc/i2c_tester.h
> create mode 100644 hw/misc/i2c_tester.c
>
> diff --git a/include/hw/misc/i2c_tester.h b/include/hw/misc/i2c_tester.h
> new file mode 100644
> index 0000000000..f6b6491008
> --- /dev/null
> +++ b/include/hw/misc/i2c_tester.h
> @@ -0,0 +1,30 @@
> +/*
> + *
> + * Copyright (c) 2024 Google LLC
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#ifndef HW_I2C_TESTER_H
> +#define HW_I2C_TESTER_H
> +
> +#include "qemu/osdep.h"
> +#include "hw/i2c/i2c.h"
> +#include "hw/irq.h"
> +
> +#define I2C_TESTER_NUM_REGS 0x31
> +
> +#define TYPE_I2C_TESTER "i2c-tester"
> +#define I2C_TESTER(obj) OBJECT_CHECK(I2cTesterState, (obj), TYPE_I2C_TESTER)
> +
> +typedef struct {
> + I2CSlave i2c;
> + bool set_reg_idx;
> + uint8_t reg_idx;
> + uint8_t regs[I2C_TESTER_NUM_REGS];
> +} I2cTesterState;
> +
> +#endif /* HW_I2C_TESTER_H */
> diff --git a/hw/misc/i2c_tester.c b/hw/misc/i2c_tester.c
> new file mode 100644
> index 0000000000..77ce8bf91a
> --- /dev/null
> +++ b/hw/misc/i2c_tester.c
> @@ -0,0 +1,109 @@
> +/*
> + * Simple I2C peripheral for testing I2C device models.
> + *
> + * Copyright (c) 2024 Google LLC
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#include "hw/misc/i2c_tester.h"
> +
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +#include "migration/vmstate.h"
> +
> +static void i2c_tester_reset_enter(Object *o, ResetType type)
> +{
> + I2cTesterState *s = I2C_TESTER(o);
> +
> + s->set_reg_idx = false;
> + s->reg_idx = 0;
> + memset(s->regs, 0, I2C_TESTER_NUM_REGS);
> +}
> +
> +static int i2c_tester_event(I2CSlave *i2c, enum i2c_event event)
> +{
> + I2cTesterState *s = I2C_TESTER(i2c);
> +
> + if (event == I2C_START_SEND) {
> + s->set_reg_idx = true;
> + }
> +
> + return 0;
> +}
> +
> +static uint8_t i2c_tester_rx(I2CSlave *i2c)
> +{
> + I2cTesterState *s = I2C_TESTER(i2c);
> +
> + if (s->reg_idx >= I2C_TESTER_NUM_REGS) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid reg 0x%02x\n", __func__,
> + s->reg_idx);
> + return I2C_NACK;
> + }
> +
> + return s->regs[s->reg_idx];
> +}
> +
> +static int i2c_tester_tx(I2CSlave *i2c, uint8_t data)
> +{
> + I2cTesterState *s = I2C_TESTER(i2c);
> +
> + if (s->set_reg_idx) {
> + /* Setting the register in which the operation will be done. */
> + s->reg_idx = data;
> + s->set_reg_idx = false;
> + return 0;
> + }
> +
> + if (s->reg_idx >= I2C_TESTER_NUM_REGS) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid reg 0x%02x\n", __func__,
> + s->reg_idx);
> + return I2C_NACK;
> + }
> +
> + /* Write reg data. */
> + s->regs[s->reg_idx] = data;
> +
> + return 0;
> +}
> +
> +static const VMStateDescription vmstate_i2c_tester = {
> + .name = "i2c-tester",
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .fields = (const VMStateField[]) {
> + VMSTATE_I2C_SLAVE(i2c, I2cTesterState),
> + VMSTATE_BOOL(set_reg_idx, I2cTesterState),
> + VMSTATE_UINT8(reg_idx, I2cTesterState),
> + VMSTATE_UINT8_ARRAY(regs, I2cTesterState, I2C_TESTER_NUM_REGS),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> +static void i2c_tester_class_init(ObjectClass *oc, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(oc);
> + ResettableClass *rc = RESETTABLE_CLASS(oc);
> + I2CSlaveClass *isc = I2C_SLAVE_CLASS(oc);
> +
> + rc->phases.enter = i2c_tester_reset_enter;
> + dc->vmsd = &vmstate_i2c_tester;
> + isc->event = i2c_tester_event;
> + isc->recv = i2c_tester_rx;
> + isc->send = i2c_tester_tx;
> +}
> +
> +static const TypeInfo i2c_tester_types[] = {
> + {
> + .name = TYPE_I2C_TESTER,
> + .parent = TYPE_I2C_SLAVE,
> + .instance_size = sizeof(I2cTesterState),
> + .class_init = i2c_tester_class_init
> + },
> +};
> +
> +DEFINE_TYPES(i2c_tester_types);
> diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
> index 4b688aead2..3e93c12c8e 100644
> --- a/hw/misc/Kconfig
> +++ b/hw/misc/Kconfig
> @@ -213,6 +213,11 @@ config IOSB
> config XLNX_VERSAL_TRNG
> bool
>
> +config I2C_TESTER
> + bool
> + default y if TEST_DEVICES
> + depends on I2C
> +
> config FLEXCOMM
> bool
> select I2C
> diff --git a/hw/misc/meson.build b/hw/misc/meson.build
> index faaf2671ba..4f22231fa3 100644
> --- a/hw/misc/meson.build
> +++ b/hw/misc/meson.build
> @@ -158,6 +158,8 @@ system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c'))
> # HPPA devices
> system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c'))
>
> +system_ss.add(when: 'CONFIG_I2C_TESTER', if_true: files('i2c_tester.c'))
> +
> system_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm.c'))
> system_ss.add(when: 'CONFIG_RT500_CLKCTL', if_true: files('rt500_clkctl0.c', 'rt500_clkctl1.c'))
> system_ss.add(when: 'CONFIG_RT500_RSTCTL', if_true: files('rt500_rstctl.c'))
> --
> 2.46.0.662.g92d0881bb0-goog
>
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 08/25] hw/i2c: add support for flexcomm i2c
2024-09-18 19:22 ` [PATCH 08/25] hw/i2c: add support for flexcomm i2c Octavian Purdila
@ 2024-09-18 20:17 ` Corey Minyard
2024-09-18 21:04 ` Octavian Purdila
0 siblings, 1 reply; 36+ messages in thread
From: Corey Minyard @ 2024-09-18 20:17 UTC (permalink / raw)
To: Octavian Purdila
Cc: qemu-devel, qemu-arm, stefanst, pbonzini, peter.maydell,
marcandre.lureau, berrange, eduardo, luc, damien.hedde, alistair,
thuth, philmd, jsnow, crosa, lvivier
On Wed, Sep 18, 2024 at 12:22:36PM -0700, Octavian Purdila wrote:
> Add support for NXP's flexcomm i2c. It does not support slave mode or
> DMA.
>
> The patch includes an automatically generated header which contains
> the register layout and helpers.
>
> The header can be regenerated with the svd-flexcomm-i2c target when
> the build is configured with --enable-mcux-soc-svd.
>
> Signed-off-by: Octavian Purdila <tavip@google.com>
> ---
> include/hw/arm/svd/flexcomm_i2c.h | 1190 +++++++++++++++++++++++++++++
> include/hw/i2c/flexcomm_i2c.h | 40 +
> include/hw/misc/flexcomm.h | 2 +
> hw/i2c/flexcomm_i2c.c | 250 ++++++
> hw/misc/flexcomm.c | 3 +
> hw/arm/svd/meson.build | 3 +
> hw/i2c/meson.build | 1 +
> hw/i2c/trace-events | 10 +
> hw/misc/Kconfig | 1 +
> 9 files changed, 1500 insertions(+)
> create mode 100644 include/hw/arm/svd/flexcomm_i2c.h
> create mode 100644 include/hw/i2c/flexcomm_i2c.h
> create mode 100644 hw/i2c/flexcomm_i2c.c
>
> diff --git a/include/hw/arm/svd/flexcomm_i2c.h b/include/hw/arm/svd/flexcomm_i2c.h
> new file mode 100644
> index 0000000000..9017d48446
> --- /dev/null
> +++ b/include/hw/arm/svd/flexcomm_i2c.h
> @@ -0,0 +1,1190 @@
> +/*
> + * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
> + *
> + * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
> + */
> +#pragma once
> +
> +#include "hw/register.h"
> +
> +/* I2C Bus Interface */
> +#define FLEXCOMM_I2C_REGS_NO (1024)
> +
> +/* Configuration Register */
> +REG32(FLEXCOMM_I2C_CFG, 2048);
> +/* Master Enable */
> +FIELD(FLEXCOMM_I2C_CFG, MSTEN, 0, 1);
> +/* Slave Enable */
> +FIELD(FLEXCOMM_I2C_CFG, SLVEN, 1, 1);
> +/* Monitor Enable */
> +FIELD(FLEXCOMM_I2C_CFG, MONEN, 2, 1);
> +/* I2C bus Time-out Enable */
> +FIELD(FLEXCOMM_I2C_CFG, TIMEOUTEN, 3, 1);
> +/* Monitor function Clock Stretching */
> +FIELD(FLEXCOMM_I2C_CFG, MONCLKSTR, 4, 1);
> +/* High Speed mode Capable enable */
> +FIELD(FLEXCOMM_I2C_CFG, HSCAPABLE, 5, 1);
> +
> +/* Status Register */
> +REG32(FLEXCOMM_I2C_STAT, 2052);
> +/* Master Pending */
> +FIELD(FLEXCOMM_I2C_STAT, MSTPENDING, 0, 1);
> +/* Master State code */
> +FIELD(FLEXCOMM_I2C_STAT, MSTSTATE, 1, 3);
> +/* Master Arbitration Loss flag */
> +FIELD(FLEXCOMM_I2C_STAT, MSTARBLOSS, 4, 1);
> +/* Master Start/Stop Error flag */
> +FIELD(FLEXCOMM_I2C_STAT, MSTSTSTPERR, 6, 1);
> +/* Slave Pending */
> +FIELD(FLEXCOMM_I2C_STAT, SLVPENDING, 8, 1);
> +/* Slave State */
> +FIELD(FLEXCOMM_I2C_STAT, SLVSTATE, 9, 2);
> +/* Slave Not Stretching */
> +FIELD(FLEXCOMM_I2C_STAT, SLVNOTSTR, 11, 1);
> +/* Slave address match Index T */
> +FIELD(FLEXCOMM_I2C_STAT, SLVIDX, 12, 2);
> +/* Slave selected flag */
> +FIELD(FLEXCOMM_I2C_STAT, SLVSEL, 14, 1);
> +/* Slave Deselected flag */
> +FIELD(FLEXCOMM_I2C_STAT, SLVDESEL, 15, 1);
> +/* Monitor Ready */
> +FIELD(FLEXCOMM_I2C_STAT, MONRDY, 16, 1);
> +/* Monitor Overflow flag */
> +FIELD(FLEXCOMM_I2C_STAT, MONOV, 17, 1);
> +/* Monitor Active flag */
> +FIELD(FLEXCOMM_I2C_STAT, MONACTIVE, 18, 1);
> +/* Monitor Idle flag */
> +FIELD(FLEXCOMM_I2C_STAT, MONIDLE, 19, 1);
> +/* Event Time-out Interrupt flag */
> +FIELD(FLEXCOMM_I2C_STAT, EVENTTIMEOUT, 24, 1);
> +/* SCL Time-out Interrupt flag */
> +FIELD(FLEXCOMM_I2C_STAT, SCLTIMEOUT, 25, 1);
> +
> +/* Interrupt Enable Set Register */
> +REG32(FLEXCOMM_I2C_INTENSET, 2056);
> +/* Master Pending interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, MSTPENDINGEN, 0, 1);
> +/* Master Arbitration Loss interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, MSTARBLOSSEN, 4, 1);
> +/* Master Start/Stop Error interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, MSTSTSTPERREN, 6, 1);
> +/* Slave Pending interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, SLVPENDINGEN, 8, 1);
> +/* Slave Not Stretching interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, SLVNOTSTREN, 11, 1);
> +/* Slave Deselect interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, SLVDESELEN, 15, 1);
> +/* Monitor data Ready interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, MONRDYEN, 16, 1);
> +/* Monitor Overrun interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, MONOVEN, 17, 1);
> +/* Monitor Idle interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, MONIDLEEN, 19, 1);
> +/* Event Time-out interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, EVENTTIMEOUTEN, 24, 1);
> +/* SCL Time-out interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, SCLTIMEOUTEN, 25, 1);
> +
> +/* Interrupt Enable Clear Register */
> +REG32(FLEXCOMM_I2C_INTENCLR, 2060);
> +/* Master Pending interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, MSTPENDINGCLR, 0, 1);
> +/* Master Arbitration Loss interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, MSTARBLOSSCLR, 4, 1);
> +/* Master Start/Stop Error interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, MSTSTSTPERRCLR, 6, 1);
> +/* Slave Pending interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, SLVPENDINGCLR, 8, 1);
> +/* Slave Not Stretching interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, SLVNOTSTRCLR, 11, 1);
> +/* Slave Deselect interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, SLVDESELCLR, 15, 1);
> +/* Monitor data Ready interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, MONRDYCLR, 16, 1);
> +/* Monitor Overrun interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, MONOVCLR, 17, 1);
> +/* Monitor Idle interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, MONIDLECLR, 19, 1);
> +/* Event time-out interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, EVENTTIMEOUTCLR, 24, 1);
> +/* SCL time-out interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, SCLTIMEOUTCLR, 25, 1);
> +
> +/* Time-out Register */
> +REG32(FLEXCOMM_I2C_TIMEOUT, 2064);
> +/* Time-out time value, the bottom 4 bits */
> +FIELD(FLEXCOMM_I2C_TIMEOUT, TOMIN, 0, 4);
> +/* Time-out time value */
> +FIELD(FLEXCOMM_I2C_TIMEOUT, TO, 4, 12);
> +
> +/* Clock Divider Register */
> +REG32(FLEXCOMM_I2C_CLKDIV, 2068);
> +/* Divider Value */
> +FIELD(FLEXCOMM_I2C_CLKDIV, DIVVAL, 0, 16);
> +
> +/* Interrupt Status Register */
> +REG32(FLEXCOMM_I2C_INTSTAT, 2072);
> +/* Master Pending */
> +FIELD(FLEXCOMM_I2C_INTSTAT, MSTPENDING, 0, 1);
> +/* Master Arbitration Loss flag */
> +FIELD(FLEXCOMM_I2C_INTSTAT, MSTARBLOSS, 4, 1);
> +/* Master Start/Stop Error flag */
> +FIELD(FLEXCOMM_I2C_INTSTAT, MSTSTSTPERR, 6, 1);
> +/* Slave Pending */
> +FIELD(FLEXCOMM_I2C_INTSTAT, SLVPENDING, 8, 1);
> +/* Slave Not Stretching status */
> +FIELD(FLEXCOMM_I2C_INTSTAT, SLVNOTSTR, 11, 1);
> +/* Slave Deselected flag */
> +FIELD(FLEXCOMM_I2C_INTSTAT, SLVDESEL, 15, 1);
> +/* Monitor Ready */
> +FIELD(FLEXCOMM_I2C_INTSTAT, MONRDY, 16, 1);
> +/* Monitor Overflow flag */
> +FIELD(FLEXCOMM_I2C_INTSTAT, MONOV, 17, 1);
> +/* Monitor Idle flag */
> +FIELD(FLEXCOMM_I2C_INTSTAT, MONIDLE, 19, 1);
> +/* Event Time-out Interrupt flag */
> +FIELD(FLEXCOMM_I2C_INTSTAT, EVENTTIMEOUT, 24, 1);
> +/* SCL Time-out Interrupt flag */
> +FIELD(FLEXCOMM_I2C_INTSTAT, SCLTIMEOUT, 25, 1);
> +
> +/* Master Control Register */
> +REG32(FLEXCOMM_I2C_MSTCTL, 2080);
> +/* Master Continue(write-only) */
> +FIELD(FLEXCOMM_I2C_MSTCTL, MSTCONTINUE, 0, 1);
> +/* Master Start control(write-only) */
> +FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTART, 1, 1);
> +/* Master Stop control(write-only) */
> +FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTOP, 2, 1);
> +/* Master DMA enable */
> +FIELD(FLEXCOMM_I2C_MSTCTL, MSTDMA, 3, 1);
> +
> +/* Master Timing Register */
> +REG32(FLEXCOMM_I2C_MSTTIME, 2084);
> +/* Master SCL Low time */
> +FIELD(FLEXCOMM_I2C_MSTTIME, MSTSCLLOW, 0, 3);
> +/* Master SCL High time */
> +FIELD(FLEXCOMM_I2C_MSTTIME, MSTSCLHIGH, 4, 3);
> +
> +/* Master Data Register */
> +REG32(FLEXCOMM_I2C_MSTDAT, 2088);
> +/* Master function data register */
> +FIELD(FLEXCOMM_I2C_MSTDAT, DATA, 0, 8);
> +
> +/* Slave Control Register */
> +REG32(FLEXCOMM_I2C_SLVCTL, 2112);
> +/* Slave Continue */
> +FIELD(FLEXCOMM_I2C_SLVCTL, SLVCONTINUE, 0, 1);
> +/* Slave NACK */
> +FIELD(FLEXCOMM_I2C_SLVCTL, SLVNACK, 1, 1);
> +/* Slave DMA enable */
> +FIELD(FLEXCOMM_I2C_SLVCTL, SLVDMA, 3, 1);
> +/* Automatic Acknowledge */
> +FIELD(FLEXCOMM_I2C_SLVCTL, AUTOACK, 8, 1);
> +/* Automatic Match Read */
> +FIELD(FLEXCOMM_I2C_SLVCTL, AUTOMATCHREAD, 9, 1);
> +
> +/* Slave Data Register */
> +REG32(FLEXCOMM_I2C_SLVDAT, 2116);
> +/* Slave function data register */
> +FIELD(FLEXCOMM_I2C_SLVDAT, DATA, 0, 8);
> +
> +/* Slave Address Register */
> +REG32(FLEXCOMM_I2C_SLVADR0, 2120);
> +/* Slave Address n Disable */
> +FIELD(FLEXCOMM_I2C_SLVADR0, SADISABLE, 0, 1);
> +/* Slave Address. */
> +FIELD(FLEXCOMM_I2C_SLVADR0, SLVADR, 1, 7);
> +/* Automatic NACK operation */
> +FIELD(FLEXCOMM_I2C_SLVADR0, AUTONACK, 15, 1);
> +
> +/* Slave Address Register */
> +REG32(FLEXCOMM_I2C_SLVADR1, 2124);
> +/* Slave Address n Disable */
> +FIELD(FLEXCOMM_I2C_SLVADR1, SADISABLE, 0, 1);
> +/* Slave Address. */
> +FIELD(FLEXCOMM_I2C_SLVADR1, SLVADR, 1, 7);
> +/* Automatic NACK operation */
> +FIELD(FLEXCOMM_I2C_SLVADR1, AUTONACK, 15, 1);
> +
> +/* Slave Address Register */
> +REG32(FLEXCOMM_I2C_SLVADR2, 2128);
> +/* Slave Address n Disable */
> +FIELD(FLEXCOMM_I2C_SLVADR2, SADISABLE, 0, 1);
> +/* Slave Address. */
> +FIELD(FLEXCOMM_I2C_SLVADR2, SLVADR, 1, 7);
> +/* Automatic NACK operation */
> +FIELD(FLEXCOMM_I2C_SLVADR2, AUTONACK, 15, 1);
> +
> +/* Slave Address Register */
> +REG32(FLEXCOMM_I2C_SLVADR3, 2132);
> +/* Slave Address n Disable */
> +FIELD(FLEXCOMM_I2C_SLVADR3, SADISABLE, 0, 1);
> +/* Slave Address. */
> +FIELD(FLEXCOMM_I2C_SLVADR3, SLVADR, 1, 7);
> +/* Automatic NACK operation */
> +FIELD(FLEXCOMM_I2C_SLVADR3, AUTONACK, 15, 1);
> +
> +/* Slave Qualification for Address 0 Register */
> +REG32(FLEXCOMM_I2C_SLVQUAL0, 2136);
> +/* Qualify mode for slave address 0 */
> +FIELD(FLEXCOMM_I2C_SLVQUAL0, QUALMODE0, 0, 1);
> +/* Slave address Qualifier for address 0 */
> +FIELD(FLEXCOMM_I2C_SLVQUAL0, SLVQUAL0, 1, 7);
> +
> +/* Monitor Receiver Data Register */
> +REG32(FLEXCOMM_I2C_MONRXDAT, 2176);
> +/* Monitor function Receiver Data */
> +FIELD(FLEXCOMM_I2C_MONRXDAT, MONRXDAT, 0, 8);
> +/* Monitor Received Start */
> +FIELD(FLEXCOMM_I2C_MONRXDAT, MONSTART, 8, 1);
> +/* Monitor Received Repeated Start */
> +FIELD(FLEXCOMM_I2C_MONRXDAT, MONRESTART, 9, 1);
> +/* Monitor Received NACK */
> +FIELD(FLEXCOMM_I2C_MONRXDAT, MONNACK, 10, 1);
> +
> +/* Peripheral Identification Register */
> +REG32(FLEXCOMM_I2C_ID, 4092);
> +/* Aperture */
> +FIELD(FLEXCOMM_I2C_ID, APERTURE, 0, 8);
> +/* Minor revision of module implementation */
> +FIELD(FLEXCOMM_I2C_ID, MINOR_REV, 8, 4);
> +/* Major revision of module implementation */
> +FIELD(FLEXCOMM_I2C_ID, MAJOR_REV, 12, 4);
> +/* Module identifier for the selected function */
> +FIELD(FLEXCOMM_I2C_ID, ID, 16, 16);
> +
Are any of the below enums even used? Or for that matter, most of the
above fields?
If these are just here for documentation, I would prefer English text;
it's more dense and easier to read. It's very difficult to tie all this
together into a cohesive view of the device registers.
The .c file itself seems ok.
-corey
> +
> +typedef enum {
> + /*
> + * Disabled. The I2C Master function is disabled. When disabled, the Master
> + * configuration settings are not changed, but the Master function is
> + * internally reset.
> + */
> + FLEXCOMM_I2C_CFG_MSTEN_DISABLED = 0,
> + /* Enabled. The I2C Master function is enabled. */
> + FLEXCOMM_I2C_CFG_MSTEN_ENABLED = 1,
> +} FLEXCOMM_I2C_CFG_MSTEN_Enum;
> +
> +typedef enum {
> + /*
> + * Disabled. The I2C slave function is disabled. When disabled, the Slave
> + * configuration settings are not changed, but the Slave function is
> + * internally reset.
> + */
> + FLEXCOMM_I2C_CFG_SLVEN_DISABLED = 0,
> + /* Enabled. The I2C slave function is enabled. */
> + FLEXCOMM_I2C_CFG_SLVEN_ENABLED = 1,
> +} FLEXCOMM_I2C_CFG_SLVEN_Enum;
> +
> +typedef enum {
> + /*
> + * Disabled. The I2C Monitor function is disabled. When disabled, the
> + * Monitor function configuration settings are not changed, but the Monitor
> + * function is internally reset.
> + */
> + FLEXCOMM_I2C_CFG_MONEN_DISABLED = 0,
> + /* Enabled. The I2C Monitor function is enabled. */
> + FLEXCOMM_I2C_CFG_MONEN_ENABLED = 1,
> +} FLEXCOMM_I2C_CFG_MONEN_Enum;
> +
> +typedef enum {
> + /*
> + * Disabled. The time-out function is disabled. When disabled, the time-out
> + * function is internally reset.
> + */
> + FLEXCOMM_I2C_CFG_TIMEOUTEN_DISABLED = 0,
> + /*
> + * Enabled. The time-out function is enabled. Both types of time-out flags
> + * will be generated and will cause interrupts if those flags are enabled.
> + * Typically, only one time-out flag will be used in a system.
> + */
> + FLEXCOMM_I2C_CFG_TIMEOUTEN_ENABLED = 1,
> +} FLEXCOMM_I2C_CFG_TIMEOUTEN_Enum;
> +
> +typedef enum {
> + /*
> + * Disabled. The Monitor function will not perform clock stretching.
> + * Software or DMA may not always be able to read data provided by the
> + * Monitor function before it (the data) is overwritten. This mode can be
> + * used when non-invasive monitoring is critical.
> + */
> + FLEXCOMM_I2C_CFG_MONCLKSTR_DISABLED = 0,
> + /*
> + * Enabled. The Monitor function will perform clock stretching, to ensure
> + * that the software or DMA can read all incoming data supplied by the
> + * Monitor function.
> + */
> + FLEXCOMM_I2C_CFG_MONCLKSTR_ENABLED = 1,
> +} FLEXCOMM_I2C_CFG_MONCLKSTR_Enum;
> +
> +typedef enum {
> + /* Fast mode Plus enable */
> + FLEXCOMM_I2C_CFG_HSCAPABLE_FAST_MODE_PLUS = 0,
> + /* High Speed mode enable */
> + FLEXCOMM_I2C_CFG_HSCAPABLE_HIGH_SPEED = 1,
> +} FLEXCOMM_I2C_CFG_HSCAPABLE_Enum;
> +
> +typedef enum {
> + /*
> + * In progress. Communication is in progress and the Master function is
> + * busy and cannot currently accept a command.
> + */
> + FLEXCOMM_I2C_STAT_MSTPENDING_IN_PROGRESS = 0,
> + /*
> + * Pending. The Master function needs software service or is in the idle
> + * state. If the master is not in the idle state, then the master is
> + * waiting to receive or transmit data, or is waiting for the NACK bit.
> + */
> + FLEXCOMM_I2C_STAT_MSTPENDING_PENDING = 1,
> +} FLEXCOMM_I2C_STAT_MSTPENDING_Enum;
> +
> +typedef enum {
> + /*
> + * Idle. The Master function is available to be used for a new transaction.
> + */
> + FLEXCOMM_I2C_STAT_MSTSTATE_IDLE = 0,
> + /*
> + * Receive ready. Received data is available (in Master Receiver mode).
> + * Address plus Read was previously sent and Acknowledged by a slave.
> + */
> + FLEXCOMM_I2C_STAT_MSTSTATE_RECEIVE_READY = 1,
> + /*
> + * Transmit ready. Data can be transmitted (in Master Transmitter mode).
> + * Address plus Write was previously sent and Acknowledged by a slave.
> + */
> + FLEXCOMM_I2C_STAT_MSTSTATE_TRANSMIT_READY = 2,
> + /* NACK Address. Slave NACKed address. */
> + FLEXCOMM_I2C_STAT_MSTSTATE_NACK_ADDRESS = 3,
> + /* NACK Data. Slave NACKed transmitted data. */
> + FLEXCOMM_I2C_STAT_MSTSTATE_NACK_DATA = 4,
> +} FLEXCOMM_I2C_STAT_MSTSTATE_Enum;
> +
> +typedef enum {
> + /* No Arbitration Loss has occurred */
> + FLEXCOMM_I2C_STAT_MSTARBLOSS_NO_LOSS = 0,
> + /*
> + * Arbitration loss. The Master function has experienced an Arbitration
> + * Loss. At this point, the Master function has already stopped driving the
> + * bus and has gone into an idle state. Software can respond by doing
> + * nothing, or by sending a Start (to attempt to gain control of the bus
> + * when the bus next becomes idle).
> + */
> + FLEXCOMM_I2C_STAT_MSTARBLOSS_ARBITRATION_LOSS = 1,
> +} FLEXCOMM_I2C_STAT_MSTARBLOSS_Enum;
> +
> +typedef enum {
> + /* No Start/Stop Error has occurred. */
> + FLEXCOMM_I2C_STAT_MSTSTSTPERR_NO_ERROR = 0,
> + /*
> + * The Master function has experienced a Start/Stop Error. A Start or Stop
> + * was detected at a time when Start or Stop is not allowed by the I2C
> + * specification. The Master interface has stopped driving the bus and gone
> + * into an idle state; no action is required. A request for a Start could
> + * be made, or software could attempt to make sure that the bus has not
> + * stalled.
> + */
> + FLEXCOMM_I2C_STAT_MSTSTSTPERR_ERROR = 1,
> +} FLEXCOMM_I2C_STAT_MSTSTSTPERR_Enum;
> +
> +typedef enum {
> + /*
> + * In progress. The Slave function does not currently need software
> + * service.
> + */
> + FLEXCOMM_I2C_STAT_SLVPENDING_IN_PROGRESS = 0,
> + /*
> + * Pending. The Slave function needs software service. Information about
> + * what is needed is in the Slave state field (SLVSTATE).
> + */
> + FLEXCOMM_I2C_STAT_SLVPENDING_PENDING = 1,
> +} FLEXCOMM_I2C_STAT_SLVPENDING_Enum;
> +
> +typedef enum {
> + /*
> + * Slave address. Address plus R/W received. At least one of the 4 slave
> + * addresses has been matched by hardware.
> + */
> + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_ADDRESS = 0,
> + /* Slave receive. Received data is available (in Slave Receiver mode). */
> + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_RECEIVE = 1,
> + /* Slave transmit. Data can be transmitted (in Slave Transmitter mode). */
> + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_TRANSMIT = 2,
> +} FLEXCOMM_I2C_STAT_SLVSTATE_Enum;
> +
> +typedef enum {
> + /*
> + * Stretching. The slave function is currently stretching the I2C bus
> + * clock. Deep-Sleepmode cannot be entered at this time.
> + */
> + FLEXCOMM_I2C_STAT_SLVNOTSTR_STRETCHING = 0,
> + /*
> + * Not stretching. The slave function is not currently stretching the I2C
> + * bus clock. Deep-sleep mode can be entered at this time.
> + */
> + FLEXCOMM_I2C_STAT_SLVNOTSTR_NOT_STRETCHING = 1,
> +} FLEXCOMM_I2C_STAT_SLVNOTSTR_Enum;
> +
> +typedef enum {
> + /* Address 0. Slave address 0 was matched. */
> + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS0 = 0,
> + /* Address 1. Slave address 1 was matched. */
> + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS1 = 1,
> + /* Address 2. Slave address 2 was matched. */
> + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS2 = 2,
> + /* Address 3. Slave address 3 was matched. */
> + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS3 = 3,
> +} FLEXCOMM_I2C_STAT_SLVIDX_Enum;
> +
> +typedef enum {
> + /* Not selected. The Slave function is not currently selected. */
> + FLEXCOMM_I2C_STAT_SLVSEL_NOT_SELECTED = 0,
> + /* Selected. The Slave function is currently selected. */
> + FLEXCOMM_I2C_STAT_SLVSEL_SELECTED = 1,
> +} FLEXCOMM_I2C_STAT_SLVSEL_Enum;
> +
> +typedef enum {
> + /*
> + * Not deselected. The Slave function has not become deselected. This does
> + * not mean that the Slave is currently selected. That information is in
> + * the SLVSEL flag.
> + */
> + FLEXCOMM_I2C_STAT_SLVDESEL_NOT_DESELECTED = 0,
> + /*
> + * Deselected. The Slave function has become deselected. This is
> + * specifically caused by the SLVSEL flag changing from 1 to 0. See SLVSEL
> + * for details about when that event occurs.
> + */
> + FLEXCOMM_I2C_STAT_SLVDESEL_DESELECTED = 1,
> +} FLEXCOMM_I2C_STAT_SLVDESEL_Enum;
> +
> +typedef enum {
> + /* No data. The Monitor function does not currently have data available. */
> + FLEXCOMM_I2C_STAT_MONRDY_NO_DATA = 0,
> + /* Data waiting. The Monitor function has data waiting to be read. */
> + FLEXCOMM_I2C_STAT_MONRDY_DATA_WAITING = 1,
> +} FLEXCOMM_I2C_STAT_MONRDY_Enum;
> +
> +typedef enum {
> + /* No overrun. Monitor data has not overrun. */
> + FLEXCOMM_I2C_STAT_MONOV_NO_OVERRUN = 0,
> + /*
> + * Overrun. A Monitor data overrun has occurred. An overrun can only happen
> + * when Monitor clock stretching not enabled via the CFG[MONCLKSTR] bit.
> + * Writing 1 to MONOV bit clears the MONOV flag.
> + */
> + FLEXCOMM_I2C_STAT_MONOV_OVERRUN = 1,
> +} FLEXCOMM_I2C_STAT_MONOV_Enum;
> +
> +typedef enum {
> + /* Inactive. The Monitor function considers the I2C bus to be inactive. */
> + FLEXCOMM_I2C_STAT_MONACTIVE_INACTIVE = 0,
> + /* Active. The Monitor function considers the I2C bus to be active. */
> + FLEXCOMM_I2C_STAT_MONACTIVE_ACTIVE = 1,
> +} FLEXCOMM_I2C_STAT_MONACTIVE_Enum;
> +
> +typedef enum {
> + /*
> + * Not idle. The I2C bus is not idle, or MONIDLE flag has been cleared by
> + * software.
> + */
> + FLEXCOMM_I2C_STAT_MONIDLE_NOT_IDLE = 0,
> + /*
> + * Idle. The I2C bus has gone idle at least once, since the last time
> + * MONIDLE flag was cleared by software.
> + */
> + FLEXCOMM_I2C_STAT_MONIDLE_IDLE = 1,
> +} FLEXCOMM_I2C_STAT_MONIDLE_Enum;
> +
> +typedef enum {
> + /* No time-out. I2C bus events have not caused a time-out. */
> + FLEXCOMM_I2C_STAT_EVENTTIMEOUT_NO_TIMEOUT = 0,
> + /*
> + * Event time-out. The time between I2C bus events has been longer than the
> + * time specified by the TIMEOUT register.
> + */
> + FLEXCOMM_I2C_STAT_EVENTTIMEOUT_EVEN_TIMEOUT = 1,
> +} FLEXCOMM_I2C_STAT_EVENTTIMEOUT_Enum;
> +
> +typedef enum {
> + /* No time-out. SCL low time has not caused a time-out. */
> + FLEXCOMM_I2C_STAT_SCLTIMEOUT_NO_TIMEOUT = 0,
> + /* Time-out. SCL low time has caused a time-out. */
> + FLEXCOMM_I2C_STAT_SCLTIMEOUT_TIMEOUT = 1,
> +} FLEXCOMM_I2C_STAT_SCLTIMEOUT_Enum;
> +
> +typedef enum {
> + /* Disabled. The MstPending interrupt is disabled. */
> + FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_DISABLED = 0,
> + /* Enabled. The MstPending interrupt is enabled. */
> + FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_ENABLED = 1,
> +} FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_Enum;
> +
> +typedef enum {
> + /* Disabled. The MstArbLoss interrupt is disabled. */
> + FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_DISABLED = 0,
> + /* Enabled. The MstArbLoss interrupt is enabled. */
> + FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_ENABLED = 1,
> +} FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_Enum;
> +
> +typedef enum {
> + /* Disabled. The MstStStpErr interrupt is disabled. */
> + FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_DISABLED = 0,
> + /* Enabled. The MstStStpErr interrupt is enabled. */
> + FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_ENABLED = 1,
> +} FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_Enum;
> +
> +typedef enum {
> + /* Disabled. The SlvPending interrupt is disabled. */
> + FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_DISABLED = 0,
> + /* Enabled. The SlvPending interrupt is enabled. */
> + FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_ENABLED = 1,
> +} FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_Enum;
> +
> +typedef enum {
> + /* Disabled. The SlvNotStr interrupt is disabled. */
> + FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_DISABLED = 0,
> + /* Enabled. The SlvNotStr interrupt is enabled. */
> + FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_ENABLED = 1,
> +} FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_Enum;
> +
> +typedef enum {
> + /* Disabled. The SlvDeSel interrupt is disabled. */
> + FLEXCOMM_I2C_INTENSET_SLVDESELEN_DISABLED = 0,
> + /* Enabled. The SlvDeSel interrupt is enabled. */
> + FLEXCOMM_I2C_INTENSET_SLVDESELEN_ENABLED = 1,
> +} FLEXCOMM_I2C_INTENSET_SLVDESELEN_Enum;
> +
> +typedef enum {
> + /* Disabled. The MonRdy interrupt is disabled. */
> + FLEXCOMM_I2C_INTENSET_MONRDYEN_DISABLED = 0,
> + /* Enabled. The MonRdy interrupt is enabled. */
> + FLEXCOMM_I2C_INTENSET_MONRDYEN_ENABLED = 1,
> +} FLEXCOMM_I2C_INTENSET_MONRDYEN_Enum;
> +
> +typedef enum {
> + /* Disabled. The MonOv interrupt is disabled. */
> + FLEXCOMM_I2C_INTENSET_MONOVEN_DISABLED = 0,
> + /* Enabled. The MonOv interrupt is enabled. */
> + FLEXCOMM_I2C_INTENSET_MONOVEN_ENABLED = 1,
> +} FLEXCOMM_I2C_INTENSET_MONOVEN_Enum;
> +
> +typedef enum {
> + /* Disabled. The MonIdle interrupt is disabled. */
> + FLEXCOMM_I2C_INTENSET_MONIDLEEN_DISABLED = 0,
> + /* Enabled. The MonIdle interrupt is enabled. */
> + FLEXCOMM_I2C_INTENSET_MONIDLEEN_ENABLED = 1,
> +} FLEXCOMM_I2C_INTENSET_MONIDLEEN_Enum;
> +
> +typedef enum {
> + /* Disabled. The Event time-out interrupt is disabled. */
> + FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_DISABLED = 0,
> + /* Enabled. The Event time-out interrupt is enabled. */
> + FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_ENABLED = 1,
> +} FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_Enum;
> +
> +typedef enum {
> + /* Disabled. The SCL time-out interrupt is disabled. */
> + FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_DISABLED = 0,
> + /* Enabled. The SCL time-out interrupt is enabled. */
> + FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_ENABLED = 1,
> +} FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_Enum;
> +
> +typedef enum {
> + /* No effect on interrupt */
> + FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_NO_EFFECT = 0,
> + /* Clears the interrupt bit in INTENSET register */
> + FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_CLEAR_MSTPENDING = 1,
> +} FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_Enum;
> +
> +typedef enum {
> + /* No effect on interrupt */
> + FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_NO_EFFECT = 0,
> + /* Clears the interrupt bit in INTENSET register */
> + FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_CLEAR_MSTARBLOSS = 1,
> +} FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_Enum;
> +
> +typedef enum {
> + /* No effect on interrupt */
> + FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_NO_EFFECT = 0,
> + /* Clears the interrupt bit in INTENSET register */
> + FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_CLEAR_MSTSTSTPERR = 1,
> +} FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_Enum;
> +
> +typedef enum {
> + /* No effect on interrupt */
> + FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_NO_EFFECT = 0,
> + /* Clears the interrupt bit in INTENSET register */
> + FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_CLEAR_SLVPENDING = 1,
> +} FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_Enum;
> +
> +typedef enum {
> + /* No effect on interrupt */
> + FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_NO_EFFECT = 0,
> + /* Clears the interrupt bit in INTENSET register */
> + FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_CLEAR_SLVNOTSTR = 1,
> +} FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_Enum;
> +
> +typedef enum {
> + /* No effect on interrupt */
> + FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_NO_EFFECT = 0,
> + /* Clears the interrupt bit in INTENSET register */
> + FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_CLEAR_SLVDESEL = 1,
> +} FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_Enum;
> +
> +typedef enum {
> + /* No effect on interrupt */
> + FLEXCOMM_I2C_INTENCLR_MONRDYCLR_NO_EFFECT = 0,
> + /* Clears the interrupt bit in INTENSET register */
> + FLEXCOMM_I2C_INTENCLR_MONRDYCLR_CLEAR_MONRDY = 1,
> +} FLEXCOMM_I2C_INTENCLR_MONRDYCLR_Enum;
> +
> +typedef enum {
> + /* No effect on interrupt */
> + FLEXCOMM_I2C_INTENCLR_MONOVCLR_NO_EFFECT = 0,
> + /* Clears the interrupt bit in INTENSET register */
> + FLEXCOMM_I2C_INTENCLR_MONOVCLR_CLEAR_MONOV = 1,
> +} FLEXCOMM_I2C_INTENCLR_MONOVCLR_Enum;
> +
> +typedef enum {
> + /* No effect on interrupt */
> + FLEXCOMM_I2C_INTENCLR_MONIDLECLR_NO_EFFECT = 0,
> + /* Clears the interrupt bit in INTENSET register */
> + FLEXCOMM_I2C_INTENCLR_MONIDLECLR_CLEAR_MONIDLE = 1,
> +} FLEXCOMM_I2C_INTENCLR_MONIDLECLR_Enum;
> +
> +typedef enum {
> + /* No effect on interrupt */
> + FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_NO_EFFECT = 0,
> + /* Clears the interrupt bit in INTENSET register */
> + FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_CLEAR_EVENTTIMEOUT = 1,
> +} FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_Enum;
> +
> +typedef enum {
> + /* No effect on interrupt */
> + FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_NO_EFFECT = 0,
> + /* Clears the interrupt bit in INTENSET register */
> + FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_CLEAR_SCLTIMEOUT = 1,
> +} FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_Enum;
> +
> +typedef enum {
> + /* A time-out will occur after 16 counts of the I2C function clock. */
> + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT16 = 0,
> + /* A time-out will occur after 32 counts of the I2C function clock. */
> + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT32 = 1,
> + /* A time-out will occur after 65,536 counts of the I2C function clock. */
> + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT65K = 4095,
> +} FLEXCOMM_I2C_TIMEOUT_TO_Enum;
> +
> +typedef enum {
> + /* FCLK is used directly by the I2C. */
> + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKUNDIVIDED = 0,
> + /* FCLK is divided by 2 before being used by the I2C. */
> + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV2 = 1,
> + /* FCLK is divided by 3 before being used by the I2C. */
> + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV3 = 2,
> + /* FCLK is divided by 65,536 before being used by the I2C. */
> + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV65K = 65535,
> +} FLEXCOMM_I2C_CLKDIV_DIVVAL_Enum;
> +
> +typedef enum {
> + /* Not active */
> + FLEXCOMM_I2C_INTSTAT_MSTPENDING_MSTPENDING_ISNOTACTIVE = 0,
> + /* Active */
> + FLEXCOMM_I2C_INTSTAT_MSTPENDING_MSTPENDING_ISACTIVE = 1,
> +} FLEXCOMM_I2C_INTSTAT_MSTPENDING_Enum;
> +
> +typedef enum {
> + /* Not active */
> + FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_MSTARBLOSS_ISNOTACTIVE = 0,
> + /* Active */
> + FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_MSTARBLOSS_ISACTIVE = 1,
> +} FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_Enum;
> +
> +typedef enum {
> + /* Not active */
> + FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_MSTSTSTPERR_ISNOTACTIVE = 0,
> + /* Active */
> + FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_MSTSTSTPERR_ISACTIVE = 1,
> +} FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_Enum;
> +
> +typedef enum {
> + /* Not active */
> + FLEXCOMM_I2C_INTSTAT_SLVPENDING_SLVPENDING_ISNOTACTIVE = 0,
> + /* Active */
> + FLEXCOMM_I2C_INTSTAT_SLVPENDING_SLVPENDING_ISACTIVE = 1,
> +} FLEXCOMM_I2C_INTSTAT_SLVPENDING_Enum;
> +
> +typedef enum {
> + /* Not active */
> + FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_SLVNOTSTR_ISNOTACTIVE = 0,
> + /* Active */
> + FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_SLVNOTSTR_ISACTIVE = 1,
> +} FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_Enum;
> +
> +typedef enum {
> + /* Not active */
> + FLEXCOMM_I2C_INTSTAT_SLVDESEL_SLVDESEL_ISNOTACTIVE = 0,
> + /* Active */
> + FLEXCOMM_I2C_INTSTAT_SLVDESEL_SLVDESEL_ISACTIVE = 1,
> +} FLEXCOMM_I2C_INTSTAT_SLVDESEL_Enum;
> +
> +typedef enum {
> + /* Not active */
> + FLEXCOMM_I2C_INTSTAT_MONRDY_MONRDY_ISNOTACTIVE = 0,
> + /* Active */
> + FLEXCOMM_I2C_INTSTAT_MONRDY_MONRDY_ISACTIVE = 1,
> +} FLEXCOMM_I2C_INTSTAT_MONRDY_Enum;
> +
> +typedef enum {
> + /* Not active */
> + FLEXCOMM_I2C_INTSTAT_MONOV_MONOV_ISNOTACTIVE = 0,
> + /* Active */
> + FLEXCOMM_I2C_INTSTAT_MONOV_MONOV_ISACTIVE = 1,
> +} FLEXCOMM_I2C_INTSTAT_MONOV_Enum;
> +
> +typedef enum {
> + /* Not active */
> + FLEXCOMM_I2C_INTSTAT_MONIDLE_MONIDLE_ISNOTACTIVE = 0,
> + /* Active */
> + FLEXCOMM_I2C_INTSTAT_MONIDLE_MONIDLE_ISACTIVE = 1,
> +} FLEXCOMM_I2C_INTSTAT_MONIDLE_Enum;
> +
> +typedef enum {
> + /* Not active */
> + FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_EVENTTIMEOUT_ISNOTACTIVE = 0,
> + /* Active */
> + FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_EVENTTIMEOUT_ISACTIVE = 1,
> +} FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_Enum;
> +
> +typedef enum {
> + /* Not active */
> + FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_SCLTIMEOUT_ISNOTACTIVE = 0,
> + /* Active */
> + FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_SCLTIMEOUT_ISACTIVE = 1,
> +} FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_Enum;
> +
> +typedef enum {
> + /* No effect */
> + FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_NO_EFFECT = 0,
> + /*
> + * Continue. Informs the Master function to continue to the next operation.
> + * This action must done after writing transmit data, reading received
> + * data, or any other housekeeping related to the next bus operation.
> + */
> + FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_CONTINUE = 1,
> +} FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_Enum;
> +
> +typedef enum {
> + /* No effect */
> + FLEXCOMM_I2C_MSTCTL_MSTSTART_NO_EFFECT = 0,
> + /*
> + * Start. A Start will be generated on the I2C bus at the next allowed
> + * time.
> + */
> + FLEXCOMM_I2C_MSTCTL_MSTSTART_START = 1,
> +} FLEXCOMM_I2C_MSTCTL_MSTSTART_Enum;
> +
> +typedef enum {
> + /* No effect */
> + FLEXCOMM_I2C_MSTCTL_MSTSTOP_NO_EFFECT = 0,
> + /*
> + * Stop. A Stop will be generated on the I2C bus at the next allowed time,
> + * preceded by a NACK to the slave if the master is receiving data from the
> + * slave (in Master Receiver mode).
> + */
> + FLEXCOMM_I2C_MSTCTL_MSTSTOP_STOP = 1,
> +} FLEXCOMM_I2C_MSTCTL_MSTSTOP_Enum;
> +
> +typedef enum {
> + /* Disable. No DMA requests are generated for master operation. */
> + FLEXCOMM_I2C_MSTCTL_MSTDMA_DISABLED = 0,
> + /*
> + * Enable. A DMA request is generated for I2C master data operations. When
> + * this I2C master is generating Acknowledge bits in Master Receiver mode,
> + * the acknowledge is generated automatically.
> + */
> + FLEXCOMM_I2C_MSTCTL_MSTDMA_ENABLED = 1,
> +} FLEXCOMM_I2C_MSTCTL_MSTDMA_Enum;
> +
> +typedef enum {
> + /*
> + * 2 clocks. Minimum SCL low time is 2 clocks of the I2C clock pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_2CLOCKS = 0,
> + /*
> + * 3 clocks. Minimum SCL low time is 3 clocks of the I2C clock pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_3CLOCKS = 1,
> + /*
> + * 4 clocks. Minimum SCL low time is 4 clocks of the I2C clock pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_4CLOCKS = 2,
> + /*
> + * 5 clocks. Minimum SCL low time is 5 clocks of the I2C clock pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_5CLOCKS = 3,
> + /*
> + * 6 clocks. Minimum SCL low time is 6 clocks of the I2C clock pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_6CLOCKS = 4,
> + /*
> + * 7 clocks. Minimum SCL low time is 7 clocks of the I2C clock pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_7CLOCKS = 5,
> + /*
> + * 8 clocks. Minimum SCL low time is 8 clocks of the I2C clock pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_8CLOCKS = 6,
> + /*
> + * 9 clocks. Minimum SCL low time is 9 clocks of the I2C clock pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_9CLOCKS = 7,
> +} FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_Enum;
> +
> +typedef enum {
> + /*
> + * 2 clocks. Minimum SCL high time is 2 clocks of the I2C clock
> + * pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_2CLOCKS = 0,
> + /*
> + * 3 clocks. Minimum SCL high time is 3 clocks of the I2C clock pre-divider
> + * .
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_3CLOCKS = 1,
> + /*
> + * 4 clocks. Minimum SCL high time is 4 clocks of the I2C clock
> + * pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_4CLOCKS = 2,
> + /*
> + * 5 clocks. Minimum SCL high time is 5 clocks of the I2C clock
> + * pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_5CLOCKS = 3,
> + /*
> + * 6 clocks. Minimum SCL high time is 6 clocks of the I2C clock
> + * pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_6CLOCKS = 4,
> + /*
> + * 7 clocks. Minimum SCL high time is 7 clocks of the I2C clock
> + * pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_7CLOCKS = 5,
> + /*
> + * 8 clocks. Minimum SCL high time is 8 clocks of the I2C clock
> + * pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_8CLOCKS = 6,
> + /*
> + * 9 clocks. Minimum SCL high time is 9 clocks of the I2C clock
> + * pre-divider.
> + */
> + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_9CLOCKS = 7,
> +} FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_Enum;
> +
> +typedef enum {
> + /* No effect */
> + FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_NO_EFFECT = 0,
> + /*
> + * Continue. Informs the Slave function to continue to the next operation,
> + * by clearing the STAT[SLVPENDING] flag. This must be done after writing
> + * transmit data, reading received data, or any other housekeeping related
> + * to the next bus operation. Automatic Operation has different
> + * requirements. SLVCONTINUE should not be set unless SLVPENDING = 1.
> + */
> + FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_CONTINUE = 1,
> +} FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_Enum;
> +
> +typedef enum {
> + /* No effect */
> + FLEXCOMM_I2C_SLVCTL_SLVNACK_NO_EFFECT = 0,
> + /*
> + * NACK. Causes the Slave function to NACK the master when the slave is
> + * receiving data from the master (in Slave Receiver mode).
> + */
> + FLEXCOMM_I2C_SLVCTL_SLVNACK_NACK = 1,
> +} FLEXCOMM_I2C_SLVCTL_SLVNACK_Enum;
> +
> +typedef enum {
> + /* Disabled. No DMA requests are issued for Slave mode operation. */
> + FLEXCOMM_I2C_SLVCTL_SLVDMA_DISABLED = 0,
> + /*
> + * Enabled. DMA requests are issued for I2C slave data transmission and
> + * reception.
> + */
> + FLEXCOMM_I2C_SLVCTL_SLVDMA_ENABLED = 1,
> +} FLEXCOMM_I2C_SLVCTL_SLVDMA_Enum;
> +
> +typedef enum {
> + /*
> + * Normal, non-automatic operation. If AUTONACK = 0, then a SlvPending
> + * interrupt is generated when a matching address is received. If AUTONACK
> + * = 1, then received addresses are NACKed (ignored).
> + */
> + FLEXCOMM_I2C_SLVCTL_AUTOACK_NORMAL = 0,
> + /*
> + * A header with matching SLVADR0 and matching direction as set by
> + * AUTOMATCHREAD will be ACKed immediately, allowing the master to move on
> + * to the data bytes. If the address matches SLVADR0, but the direction
> + * does not match AUTOMATCHREAD, then the behavior will depend on the
> + * SLVADR0[AUTONACK] bit: if AUTONACK is set, then it will be Nacked; if
> + * AUTONACK is clear, then a SlvPending interrupt is generated.
> + */
> + FLEXCOMM_I2C_SLVCTL_AUTOACK_AUTOMATIC_ACK = 1,
> +} FLEXCOMM_I2C_SLVCTL_AUTOACK_Enum;
> +
> +typedef enum {
> + /* In Automatic Mode, the expected next operation is an I2C write. */
> + FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_I2C_WRITE = 0,
> + /* In Automatic Mode, the expected next operation is an I2C read. */
> + FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_I2C_READ = 1,
> +} FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_Enum;
> +
> +typedef enum {
> + /* Enabled. Slave Address n is enabled. */
> + FLEXCOMM_I2C_SLVADR0_SADISABLE_ENABLED = 0,
> + /* Ignored. Slave Address n is ignored. */
> + FLEXCOMM_I2C_SLVADR0_SADISABLE_DISABLED = 1,
> +} FLEXCOMM_I2C_SLVADR0_SADISABLE_Enum;
> +
> +typedef enum {
> + /* Normal operation, matching I2C addresses are not ignored. */
> + FLEXCOMM_I2C_SLVADR0_AUTONACK_NORMAL = 0,
> + /*
> + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> + * matches the direction.
> + */
> + FLEXCOMM_I2C_SLVADR0_AUTONACK_AUTOMATIC = 1,
> +} FLEXCOMM_I2C_SLVADR0_AUTONACK_Enum;
> +
> +typedef enum {
> + /* Enabled. Slave Address n is enabled. */
> + FLEXCOMM_I2C_SLVADR1_SADISABLE_ENABLED = 0,
> + /* Ignored. Slave Address n is ignored. */
> + FLEXCOMM_I2C_SLVADR1_SADISABLE_DISABLED = 1,
> +} FLEXCOMM_I2C_SLVADR1_SADISABLE_Enum;
> +
> +typedef enum {
> + /* Normal operation, matching I2C addresses are not ignored. */
> + FLEXCOMM_I2C_SLVADR1_AUTONACK_NORMAL = 0,
> + /*
> + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> + * matches the direction.
> + */
> + FLEXCOMM_I2C_SLVADR1_AUTONACK_AUTOMATIC = 1,
> +} FLEXCOMM_I2C_SLVADR1_AUTONACK_Enum;
> +
> +typedef enum {
> + /* Enabled. Slave Address n is enabled. */
> + FLEXCOMM_I2C_SLVADR2_SADISABLE_ENABLED = 0,
> + /* Ignored. Slave Address n is ignored. */
> + FLEXCOMM_I2C_SLVADR2_SADISABLE_DISABLED = 1,
> +} FLEXCOMM_I2C_SLVADR2_SADISABLE_Enum;
> +
> +typedef enum {
> + /* Normal operation, matching I2C addresses are not ignored. */
> + FLEXCOMM_I2C_SLVADR2_AUTONACK_NORMAL = 0,
> + /*
> + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> + * matches the direction.
> + */
> + FLEXCOMM_I2C_SLVADR2_AUTONACK_AUTOMATIC = 1,
> +} FLEXCOMM_I2C_SLVADR2_AUTONACK_Enum;
> +
> +typedef enum {
> + /* Enabled. Slave Address n is enabled. */
> + FLEXCOMM_I2C_SLVADR3_SADISABLE_ENABLED = 0,
> + /* Ignored. Slave Address n is ignored. */
> + FLEXCOMM_I2C_SLVADR3_SADISABLE_DISABLED = 1,
> +} FLEXCOMM_I2C_SLVADR3_SADISABLE_Enum;
> +
> +typedef enum {
> + /* Normal operation, matching I2C addresses are not ignored. */
> + FLEXCOMM_I2C_SLVADR3_AUTONACK_NORMAL = 0,
> + /*
> + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> + * matches the direction.
> + */
> + FLEXCOMM_I2C_SLVADR3_AUTONACK_AUTOMATIC = 1,
> +} FLEXCOMM_I2C_SLVADR3_AUTONACK_Enum;
> +
> +typedef enum {
> + /*
> + * Mask. The SLVQUAL0 field is used as a logical mask for matching address
> + * 0.
> + */
> + FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_MASK = 0,
> + /*
> + * Extend. The SLVQUAL0 field is used to extend address 0 matching in a
> + * range of addresses.
> + */
> + FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_EXTEND = 1,
> +} FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_Enum;
> +
> +typedef enum {
> + /*
> + * No start detected. The Monitor function has not detected a Start event
> + * on the I2C bus.
> + */
> + FLEXCOMM_I2C_MONRXDAT_MONSTART_NO_START_DETECTED = 0,
> + /*
> + * Start detected. The Monitor function has detected a Start event on the
> + * I2C bus.
> + */
> + FLEXCOMM_I2C_MONRXDAT_MONSTART_START_DETECTED = 1,
> +} FLEXCOMM_I2C_MONRXDAT_MONSTART_Enum;
> +
> +typedef enum {
> + /*
> + * No repeated start detected. The Monitor function has not detected a
> + * Repeated Start event on the I2C bus.
> + */
> + FLEXCOMM_I2C_MONRXDAT_MONRESTART_NOT_DETECTED = 0,
> + /*
> + * Repeated start detected. The Monitor function has detected a Repeated
> + * Start event on the I2C bus.
> + */
> + FLEXCOMM_I2C_MONRXDAT_MONRESTART_DETECTED = 1,
> +} FLEXCOMM_I2C_MONRXDAT_MONRESTART_Enum;
> +
> +typedef enum {
> + /*
> + * Acknowledged. The data currently being provided by the Monitor function
> + * was acknowledged by at least one master or slave receiver.
> + */
> + FLEXCOMM_I2C_MONRXDAT_MONNACK_ACKNOWLEDGED = 0,
> + /*
> + * Not acknowledged. The data currently being provided by the Monitor
> + * function was not acknowledged by any receiver.
> + */
> + FLEXCOMM_I2C_MONRXDAT_MONNACK_NOT_ACKNOWLEDGED = 1,
> +} FLEXCOMM_I2C_MONRXDAT_MONNACK_Enum;
> +
> +
> +#define FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(_name) \
> + struct RegisterAccessInfo _name[FLEXCOMM_I2C_REGS_NO] = { \
> + [0 ... FLEXCOMM_I2C_REGS_NO - 1] = { \
> + .name = "", \
> + .addr = -1, \
> + }, \
> + [R_FLEXCOMM_I2C_CFG] = { \
> + .name = "CFG", \
> + .addr = 0x800, \
> + .ro = 0xFFFFFFC0, \
> + .reset = 0x0, \
> + }, \
> + [R_FLEXCOMM_I2C_STAT] = { \
> + .name = "STAT", \
> + .addr = 0x804, \
> + .ro = 0xFCF57FAF, \
> + .reset = 0x801, \
> + }, \
> + [R_FLEXCOMM_I2C_INTENSET] = { \
> + .name = "INTENSET", \
> + .addr = 0x808, \
> + .ro = 0xFCF476AE, \
> + .reset = 0x0, \
> + }, \
> + [R_FLEXCOMM_I2C_INTENCLR] = { \
> + .name = "INTENCLR", \
> + .addr = 0x80C, \
> + .ro = 0xFCF476AE, \
> + .reset = 0x0, \
> + }, \
> + [R_FLEXCOMM_I2C_TIMEOUT] = { \
> + .name = "TIMEOUT", \
> + .addr = 0x810, \
> + .ro = 0xFFFF0000, \
> + .reset = 0xFFFF, \
> + }, \
> + [R_FLEXCOMM_I2C_CLKDIV] = { \
> + .name = "CLKDIV", \
> + .addr = 0x814, \
> + .ro = 0xFFFF0000, \
> + .reset = 0x0, \
> + }, \
> + [R_FLEXCOMM_I2C_INTSTAT] = { \
> + .name = "INTSTAT", \
> + .addr = 0x818, \
> + .ro = 0xFFFFFFFF, \
> + .reset = 0x801, \
> + }, \
> + [R_FLEXCOMM_I2C_MSTCTL] = { \
> + .name = "MSTCTL", \
> + .addr = 0x820, \
> + .ro = 0xFFFFFFF0, \
> + .reset = 0x0, \
> + }, \
> + [R_FLEXCOMM_I2C_MSTTIME] = { \
> + .name = "MSTTIME", \
> + .addr = 0x824, \
> + .ro = 0xFFFFFF88, \
> + .reset = 0x77, \
> + }, \
> + [R_FLEXCOMM_I2C_MSTDAT] = { \
> + .name = "MSTDAT", \
> + .addr = 0x828, \
> + .ro = 0xFFFFFF00, \
> + .reset = 0x0, \
> + }, \
> + [R_FLEXCOMM_I2C_SLVCTL] = { \
> + .name = "SLVCTL", \
> + .addr = 0x840, \
> + .ro = 0xFFFFFCF4, \
> + .reset = 0x0, \
> + }, \
> + [R_FLEXCOMM_I2C_SLVDAT] = { \
> + .name = "SLVDAT", \
> + .addr = 0x844, \
> + .ro = 0xFFFFFF00, \
> + .reset = 0x0, \
> + }, \
> + [R_FLEXCOMM_I2C_SLVADR0] = { \
> + .name = "SLVADR0", \
> + .addr = 0x848, \
> + .ro = 0xFFFF7F00, \
> + .reset = 0x1, \
> + }, \
> + [R_FLEXCOMM_I2C_SLVADR1] = { \
> + .name = "SLVADR1", \
> + .addr = 0x84C, \
> + .ro = 0xFFFF7F00, \
> + .reset = 0x1, \
> + }, \
> + [R_FLEXCOMM_I2C_SLVADR2] = { \
> + .name = "SLVADR2", \
> + .addr = 0x850, \
> + .ro = 0xFFFF7F00, \
> + .reset = 0x1, \
> + }, \
> + [R_FLEXCOMM_I2C_SLVADR3] = { \
> + .name = "SLVADR3", \
> + .addr = 0x854, \
> + .ro = 0xFFFF7F00, \
> + .reset = 0x1, \
> + }, \
> + [R_FLEXCOMM_I2C_SLVQUAL0] = { \
> + .name = "SLVQUAL0", \
> + .addr = 0x858, \
> + .ro = 0xFFFFFF00, \
> + .reset = 0x0, \
> + }, \
> + [R_FLEXCOMM_I2C_MONRXDAT] = { \
> + .name = "MONRXDAT", \
> + .addr = 0x880, \
> + .ro = 0xFFFFFFFF, \
> + .reset = 0x0, \
> + }, \
> + [R_FLEXCOMM_I2C_ID] = { \
> + .name = "ID", \
> + .addr = 0xFFC, \
> + .ro = 0xFFFFFFFF, \
> + .reset = 0xE0301300, \
> + }, \
> + }
> diff --git a/include/hw/i2c/flexcomm_i2c.h b/include/hw/i2c/flexcomm_i2c.h
> new file mode 100644
> index 0000000000..7b27e333d7
> --- /dev/null
> +++ b/include/hw/i2c/flexcomm_i2c.h
> @@ -0,0 +1,40 @@
> +/*
> + * QEMU model for NXP's FLEXCOMM I2C
> + *
> + * Copyright (c) 2024 Google LLC
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#ifndef HW_FLEXCOMM_I2C_H
> +#define HW_FLEXCOMM_I2C_H
> +
> +#include "hw/i2c/i2c.h"
> +#include "hw/misc/flexcomm_function.h"
> +
> +#define TYPE_FLEXCOMM_I2C "flexcomm-i2c"
> +OBJECT_DECLARE_TYPE(FlexcommI2cState, FlexcommI2cClass, FLEXCOMM_I2C);
> +
> +struct FlexcommI2cState {
> + FlexcommFunction parent_obj;
> +
> + I2CBus *bus;
> +};
> +
> +struct FlexcommI2cClass {
> + FlexcommFunctionClass parent_obj;
> +
> + FlexcommFunctionSelect select;
> +};
> +
> +#define MSTSTATE_IDLE 0
> +#define MSTSTATE_RXRDY 1
> +#define MSTSTATE_TXRDY 2
> +#define MSTSTATE_NAKADR 3
> +#define MSTSTATE_NAKDAT 4
> +
> +
> +#endif /* HW_FLEXCOMM_I2C_H */
> diff --git a/include/hw/misc/flexcomm.h b/include/hw/misc/flexcomm.h
> index 679b7ea64d..c9f1cd3890 100644
> --- a/include/hw/misc/flexcomm.h
> +++ b/include/hw/misc/flexcomm.h
> @@ -16,6 +16,7 @@
> #include "hw/arm/svd/flexcomm.h"
> #include "qemu/fifo32.h"
> #include "hw/char/flexcomm_usart.h"
> +#include "hw/i2c/flexcomm_i2c.h"
>
> #define FLEXCOMM_FUNC_USART 0
> #define FLEXCOMM_FUNC_SPI 1
> @@ -48,6 +49,7 @@ struct FlexcommState {
> Fifo32 rx_fifo;
> Fifo32 tx_fifo;
> FlexcommUsartState usart;
> + FlexcommI2cState i2c;
> };
>
> #endif /* HW_FLEXCOMM_H */
> diff --git a/hw/i2c/flexcomm_i2c.c b/hw/i2c/flexcomm_i2c.c
> new file mode 100644
> index 0000000000..e5341ec241
> --- /dev/null
> +++ b/hw/i2c/flexcomm_i2c.c
> @@ -0,0 +1,250 @@
> +/*
> + * QEMU model for NXP's FLEXCOMM I2C
> + *
> + * Copyright (c) 2024 Google LLC
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/cutils.h"
> +#include "hw/irq.h"
> +#include "hw/qdev-properties.h"
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +#include "exec/address-spaces.h"
> +#include "qapi/error.h"
> +#include "trace.h"
> +#include "hw/i2c/flexcomm_i2c.h"
> +#include "hw/arm/svd/flexcomm_i2c.h"
> +
> +#define REG(s, reg) (s->regs[R_FLEXCOMM_I2C_##reg])
> +#define RF_WR(s, reg, field, val) \
> + ARRAY_FIELD_DP32(s->regs, FLEXCOMM_I2C_##reg, field, val)
> +#define RF_RD(s, reg, field) \
> + ARRAY_FIELD_EX32(s->regs, FLEXCOMM_I2C_##reg, field)
> +
> +static FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(reg_info);
> +
> +static void flexcomm_i2c_reset(FlexcommFunction *f)
> +{
> + for (int i = 0; i < FLEXCOMM_I2C_REGS_NO; i++) {
> + hwaddr addr = reg_info[i].addr;
> +
> + if (addr != -1) {
> + struct RegisterInfo ri = {
> + .data = &f->regs[addr / 4],
> + .data_size = 4,
> + .access = ®_info[i],
> + };
> +
> + register_reset(&ri);
> + }
> + }
> +}
> +
> +static void flexcomm_i2c_irq_update(FlexcommFunction *f)
> +{
> + bool enabled = RF_RD(f, CFG, MSTEN);
> + bool irq, per_irqs;
> +
> + REG(f, INTSTAT) = REG(f, STAT) & REG(f, INTENSET);
> + per_irqs = REG(f, INTSTAT) != 0;
> +
> + irq = enabled && per_irqs;
> +
> + trace_flexcomm_i2c_irq(DEVICE(f)->id, irq, per_irqs, enabled);
> + flexcomm_set_irq(f, irq);
> +}
> +
> +static MemTxResult flexcomm_i2c_reg_read(void *opaque, hwaddr addr,
> + uint64_t *data, unsigned size,
> + MemTxAttrs attrs)
> +{
> + FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
> + MemTxResult ret = MEMTX_OK;
> + const struct RegisterAccessInfo *rai = ®_info[addr / 4];
> +
> + if (size != 4) {
> + ret = MEMTX_ERROR;
> + goto out;
> + }
> +
> + *data = f->regs[addr / 4];
> +
> + flexcomm_i2c_irq_update(f);
> +
> +out:
> + trace_flexcomm_i2c_reg_read(DEVICE(f)->id, rai->name, addr, *data);
> + return ret;
> +}
> +
> +static MemTxResult flexcomm_i2c_reg_write(void *opaque, hwaddr addr,
> + uint64_t value, unsigned size,
> + MemTxAttrs attrs)
> +{
> + FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
> + FlexcommI2cState *s = FLEXCOMM_I2C(opaque);
> + const struct RegisterAccessInfo *rai = ®_info[addr / 4];
> + struct RegisterInfo ri = {
> + .data = &f->regs[addr / 4],
> + .data_size = 4,
> + .access = rai,
> + };
> +
> + trace_flexcomm_i2c_reg_write(DEVICE(f)->id, rai->name, addr, value);
> +
> + if (size != 4) {
> + return MEMTX_ERROR;
> + }
> +
> + switch (addr) {
> + case A_FLEXCOMM_I2C_CFG:
> + {
> + register_write(&ri, value, ~0, NULL, false);
> + if (RF_RD(f, CFG, SLVEN)) {
> + qemu_log_mask(LOG_GUEST_ERROR, "I2C slave not supported");
> + }
> + if (RF_RD(f, CFG, MONEN)) {
> + qemu_log_mask(LOG_GUEST_ERROR, "I2C monitoring not supported");
> + }
> + break;
> + }
> + case A_FLEXCOMM_I2C_INTENCLR:
> + {
> + REG(f, INTENSET) &= ~value;
> + break;
> + }
> + case A_FLEXCOMM_I2C_TIMEOUT:
> + {
> + register_write(&ri, value, ~0, NULL, false);
> + /* The bottom 4 bits are hard-wired to 0xF */
> + RF_WR(f, TIMEOUT, TOMIN, 0xf);
> + break;
> + }
> + case A_FLEXCOMM_I2C_MSTCTL:
> + {
> + register_write(&ri, value, ~0, NULL, false);
> + if (RF_RD(f, MSTCTL, MSTSTART)) {
> + uint8_t i2c_addr = RF_RD(f, MSTDAT, DATA);
> + bool recv = i2c_addr & 1;
> +
> + trace_flexcomm_i2c_start(DEVICE(s)->id, i2c_addr, recv);
> + if (i2c_start_transfer(s->bus, i2c_addr, recv)) {
> + RF_WR(f, STAT, MSTSTATE, MSTSTATE_NAKADR);
> + trace_flexcomm_i2c_nak(DEVICE(s)->id);
> + } else {
> + if (recv) {
> + uint8_t data = i2c_recv(s->bus);
> +
> + RF_WR(f, MSTDAT, DATA, data);
> + trace_flexcomm_i2c_rx(DEVICE(s)->id, data);
> + RF_WR(f, STAT, MSTSTATE, MSTSTATE_RXRDY);
> + } else {
> + RF_WR(f, STAT, MSTSTATE, MSTSTATE_TXRDY);
> + }
> + }
> + }
> + if (RF_RD(f, MSTCTL, MSTSTOP)) {
> + RF_WR(f, STAT, MSTSTATE, MSTSTATE_IDLE);
> + i2c_end_transfer(s->bus);
> + }
> + if (RF_RD(f, MSTCTL, MSTCONTINUE)) {
> + if (RF_RD(f, STAT, MSTSTATE) == MSTSTATE_TXRDY) {
> + uint8_t data = RF_RD(f, MSTDAT, DATA);
> +
> + trace_flexcomm_i2c_tx(DEVICE(s)->id, data);
> + if (i2c_send(s->bus, data)) {
> + RF_WR(f, STAT, MSTSTATE, MSTSTATE_NAKDAT);
> + }
> + } else if (RF_RD(f, STAT, MSTSTATE) == MSTSTATE_RXRDY) {
> + uint8_t data = i2c_recv(s->bus);
> +
> + RF_WR(f, MSTDAT, DATA, data);
> + trace_flexcomm_i2c_rx(DEVICE(s)->id, data);
> + }
> + }
> + break;
> + }
> + case A_FLEXCOMM_I2C_STAT:
> + {
> + /* write 1 to clear bits */
> + REG(f, STAT) &= ~value;
> + break;
> + }
> + case A_FLEXCOMM_I2C_SLVCTL:
> + case A_FLEXCOMM_I2C_SLVDAT:
> + case A_FLEXCOMM_I2C_SLVADR0:
> + case A_FLEXCOMM_I2C_SLVADR1:
> + case A_FLEXCOMM_I2C_SLVADR2:
> + case A_FLEXCOMM_I2C_SLVADR3:
> + case A_FLEXCOMM_I2C_SLVQUAL0:
> + {
> + qemu_log_mask(LOG_GUEST_ERROR, "I2C slave not supported\n");
> + break;
> + }
> + default:
> + register_write(&ri, value, ~0, NULL, false);
> + break;
> + }
> +
> + flexcomm_i2c_irq_update(f);
> +
> + return MEMTX_OK;
> +}
> +
> +static void flexcomm_i2c_select(FlexcommFunction *f, bool selected)
> +{
> + FlexcommI2cClass *ic = FLEXCOMM_I2C_GET_CLASS(f);
> +
> + if (selected) {
> + flexcomm_i2c_reset(f);
> + }
> + ic->select(f, selected);
> +}
> +
> +static const MemoryRegionOps flexcomm_i2c_ops = {
> + .read_with_attrs = flexcomm_i2c_reg_read,
> + .write_with_attrs = flexcomm_i2c_reg_write,
> + .endianness = DEVICE_NATIVE_ENDIAN,
> + .valid = {
> + .min_access_size = 4,
> + .max_access_size = 4,
> + .unaligned = false,
> + },
> +};
> +
> +static void flexcomm_i2c_realize(DeviceState *dev, Error **errp)
> +{
> + FlexcommI2cState *s = FLEXCOMM_I2C(dev);
> +
> + s->bus = i2c_init_bus(DEVICE(s), "bus");
> +}
> +
> +static void flexcomm_i2c_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_CLASS(klass);
> + FlexcommI2cClass *ic = FLEXCOMM_I2C_CLASS(klass);
> +
> + dc->realize = flexcomm_i2c_realize;
> + ic->select = fc->select;
> + fc->select = flexcomm_i2c_select;
> + fc->name = "i2c";
> + fc->mmio_ops = &flexcomm_i2c_ops;
> +}
> +
> +static const TypeInfo flexcomm_i2c_types[] = {
> + {
> + .name = TYPE_FLEXCOMM_I2C,
> + .parent = TYPE_FLEXCOMM_FUNCTION,
> + .instance_size = sizeof(FlexcommI2cState),
> + .class_init = flexcomm_i2c_class_init,
> + .class_size = sizeof(FlexcommI2cClass),
> + },
> +};
> +
> +DEFINE_TYPES(flexcomm_i2c_types);
> diff --git a/hw/misc/flexcomm.c b/hw/misc/flexcomm.c
> index a291148f27..b1a2f01acf 100644
> --- a/hw/misc/flexcomm.c
> +++ b/hw/misc/flexcomm.c
> @@ -24,6 +24,7 @@
> #include "hw/misc/flexcomm.h"
> #include "hw/arm/svd/flexcomm_usart.h"
> #include "hw/char/flexcomm_usart.h"
> +#include "hw/i2c/flexcomm_i2c.h"
>
> #define REG(s, reg) (s->regs[R_FLEXCOMM_##reg])
> #define RF_WR(s, reg, field, val) \
> @@ -220,6 +221,7 @@ static void flexcomm_init(Object *obj)
> sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container);
> sysbus_init_irq(sbd, &s->irq);
> object_initialize_child(obj, "usart", &s->usart, TYPE_FLEXCOMM_USART);
> + object_initialize_child(obj, "i2c", &s->i2c, TYPE_FLEXCOMM_I2C);
> }
>
> static void flexcomm_finalize(Object *obj)
> @@ -250,6 +252,7 @@ static void flexcomm_realize(DeviceState *dev, Error **errp)
>
> memory_region_add_subregion_overlap(&s->container, 0, &s->mmio, -1);
> flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->usart), errp);
> + flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->i2c), errp);
> }
>
> static const VMStateDescription vmstate_flexcomm = {
> diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build
> index 2bde34d15b..417491cd5c 100644
> --- a/hw/arm/svd/meson.build
> +++ b/hw/arm/svd/meson.build
> @@ -7,4 +7,7 @@ if get_option('mcux-soc-svd')
> run_target('svd-flexcomm-usart', command: svd_gen_header +
> [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_usart.h',
> '-p', 'USART0', '-t', 'FLEXCOMM_USART'])
> + run_target('svd-flexcomm-i2c', command: svd_gen_header +
> + [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_i2c.h',
> + '-p', 'I2C0', '-t', 'FLEXCOMM_I2C'])
> endif
> diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build
> index c459adcb59..e7d79e6938 100644
> --- a/hw/i2c/meson.build
> +++ b/hw/i2c/meson.build
> @@ -18,4 +18,5 @@ i2c_ss.add(when: 'CONFIG_PPC4XX', if_true: files('ppc4xx_i2c.c'))
> i2c_ss.add(when: 'CONFIG_PCA954X', if_true: files('i2c_mux_pca954x.c'))
> i2c_ss.add(when: 'CONFIG_PMBUS', if_true: files('pmbus_device.c'))
> i2c_ss.add(when: 'CONFIG_BCM2835_I2C', if_true: files('bcm2835_i2c.c'))
> +i2c_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm_i2c.c'))
> system_ss.add_all(when: 'CONFIG_I2C', if_true: i2c_ss)
> diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
> index 6900e06eda..9f0175fab7 100644
> --- a/hw/i2c/trace-events
> +++ b/hw/i2c/trace-events
> @@ -51,3 +51,13 @@ npcm7xx_smbus_recv_fifo(const char *id, uint8_t received, uint8_t expected) "%s
>
> pca954x_write_bytes(uint8_t value) "PCA954X write data: 0x%02x"
> pca954x_read_data(uint8_t value) "PCA954X read data: 0x%02x"
> +
> +# flexcomm_i2c.c
> +
> +flexcomm_i2c_reg_read(const char *id, const char *reg_name, uint32_t addr, uint32_t val) " %s: %s[0x%04x] -> 0x%08x"
> +flexcomm_i2c_reg_write(const char *id, const char *reg_name, uint32_t addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x"
> +flexcomm_i2c_start(const char *id, uint8_t addr, uint8_t recv) "%s: 0x%02x %d"
> +flexcomm_i2c_rx(const char *id, uint8_t data) "%s: <- 0x%02x"
> +flexcomm_i2c_tx(const char *id, uint8_t data) "%s: -> 0x%02x"
> +flexcomm_i2c_nak(const char *id) "%s: <- nak"
> +flexcomm_i2c_irq(const char *id, bool irq, bool perirqs, bool enabled) "%s: %d %d %d"
> diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
> index 14167ae9e8..9a244fa01d 100644
> --- a/hw/misc/Kconfig
> +++ b/hw/misc/Kconfig
> @@ -215,5 +215,6 @@ config XLNX_VERSAL_TRNG
>
> config FLEXCOMM
> bool
> + select I2C
>
> source macio/Kconfig
> --
> 2.46.0.662.g92d0881bb0-goog
>
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 08/25] hw/i2c: add support for flexcomm i2c
2024-09-18 20:17 ` Corey Minyard
@ 2024-09-18 21:04 ` Octavian Purdila
2024-09-18 21:31 ` Corey Minyard
0 siblings, 1 reply; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 21:04 UTC (permalink / raw)
To: corey
Cc: qemu-devel, qemu-arm, stefanst, pbonzini, peter.maydell,
marcandre.lureau, berrange, eduardo, luc, damien.hedde, alistair,
thuth, philmd, jsnow, crosa, lvivier
On Wed, Sep 18, 2024 at 1:17 PM Corey Minyard <corey@minyard.net> wrote:
>
> On Wed, Sep 18, 2024 at 12:22:36PM -0700, Octavian Purdila wrote:
> > Add support for NXP's flexcomm i2c. It does not support slave mode or
> > DMA.
> >
> > The patch includes an automatically generated header which contains
> > the register layout and helpers.
> >
> > The header can be regenerated with the svd-flexcomm-i2c target when
> > the build is configured with --enable-mcux-soc-svd.
> >
> > Signed-off-by: Octavian Purdila <tavip@google.com>
> > ---
> > include/hw/arm/svd/flexcomm_i2c.h | 1190 +++++++++++++++++++++++++++++
> > include/hw/i2c/flexcomm_i2c.h | 40 +
> > include/hw/misc/flexcomm.h | 2 +
> > hw/i2c/flexcomm_i2c.c | 250 ++++++
> > hw/misc/flexcomm.c | 3 +
> > hw/arm/svd/meson.build | 3 +
> > hw/i2c/meson.build | 1 +
> > hw/i2c/trace-events | 10 +
> > hw/misc/Kconfig | 1 +
> > 9 files changed, 1500 insertions(+)
> > create mode 100644 include/hw/arm/svd/flexcomm_i2c.h
> > create mode 100644 include/hw/i2c/flexcomm_i2c.h
> > create mode 100644 hw/i2c/flexcomm_i2c.c
> >
> > diff --git a/include/hw/arm/svd/flexcomm_i2c.h b/include/hw/arm/svd/flexcomm_i2c.h
> > new file mode 100644
> > index 0000000000..9017d48446
> > --- /dev/null
> > +++ b/include/hw/arm/svd/flexcomm_i2c.h
> > @@ -0,0 +1,1190 @@
> > +/*
> > + * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
> > + *
> > + * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
> > + */
> > +#pragma once
> > +
> > +#include "hw/register.h"
> > +
> > +/* I2C Bus Interface */
> > +#define FLEXCOMM_I2C_REGS_NO (1024)
> > +
> > +/* Configuration Register */
> > +REG32(FLEXCOMM_I2C_CFG, 2048);
> > +/* Master Enable */
> > +FIELD(FLEXCOMM_I2C_CFG, MSTEN, 0, 1);
> > +/* Slave Enable */
> > +FIELD(FLEXCOMM_I2C_CFG, SLVEN, 1, 1);
> > +/* Monitor Enable */
> > +FIELD(FLEXCOMM_I2C_CFG, MONEN, 2, 1);
> > +/* I2C bus Time-out Enable */
> > +FIELD(FLEXCOMM_I2C_CFG, TIMEOUTEN, 3, 1);
> > +/* Monitor function Clock Stretching */
> > +FIELD(FLEXCOMM_I2C_CFG, MONCLKSTR, 4, 1);
> > +/* High Speed mode Capable enable */
> > +FIELD(FLEXCOMM_I2C_CFG, HSCAPABLE, 5, 1);
> > +
> > +/* Status Register */
> > +REG32(FLEXCOMM_I2C_STAT, 2052);
> > +/* Master Pending */
> > +FIELD(FLEXCOMM_I2C_STAT, MSTPENDING, 0, 1);
> > +/* Master State code */
> > +FIELD(FLEXCOMM_I2C_STAT, MSTSTATE, 1, 3);
> > +/* Master Arbitration Loss flag */
> > +FIELD(FLEXCOMM_I2C_STAT, MSTARBLOSS, 4, 1);
> > +/* Master Start/Stop Error flag */
> > +FIELD(FLEXCOMM_I2C_STAT, MSTSTSTPERR, 6, 1);
> > +/* Slave Pending */
> > +FIELD(FLEXCOMM_I2C_STAT, SLVPENDING, 8, 1);
> > +/* Slave State */
> > +FIELD(FLEXCOMM_I2C_STAT, SLVSTATE, 9, 2);
> > +/* Slave Not Stretching */
> > +FIELD(FLEXCOMM_I2C_STAT, SLVNOTSTR, 11, 1);
> > +/* Slave address match Index T */
> > +FIELD(FLEXCOMM_I2C_STAT, SLVIDX, 12, 2);
> > +/* Slave selected flag */
> > +FIELD(FLEXCOMM_I2C_STAT, SLVSEL, 14, 1);
> > +/* Slave Deselected flag */
> > +FIELD(FLEXCOMM_I2C_STAT, SLVDESEL, 15, 1);
> > +/* Monitor Ready */
> > +FIELD(FLEXCOMM_I2C_STAT, MONRDY, 16, 1);
> > +/* Monitor Overflow flag */
> > +FIELD(FLEXCOMM_I2C_STAT, MONOV, 17, 1);
> > +/* Monitor Active flag */
> > +FIELD(FLEXCOMM_I2C_STAT, MONACTIVE, 18, 1);
> > +/* Monitor Idle flag */
> > +FIELD(FLEXCOMM_I2C_STAT, MONIDLE, 19, 1);
> > +/* Event Time-out Interrupt flag */
> > +FIELD(FLEXCOMM_I2C_STAT, EVENTTIMEOUT, 24, 1);
> > +/* SCL Time-out Interrupt flag */
> > +FIELD(FLEXCOMM_I2C_STAT, SCLTIMEOUT, 25, 1);
> > +
> > +/* Interrupt Enable Set Register */
> > +REG32(FLEXCOMM_I2C_INTENSET, 2056);
> > +/* Master Pending interrupt Enable */
> > +FIELD(FLEXCOMM_I2C_INTENSET, MSTPENDINGEN, 0, 1);
> > +/* Master Arbitration Loss interrupt Enable */
> > +FIELD(FLEXCOMM_I2C_INTENSET, MSTARBLOSSEN, 4, 1);
> > +/* Master Start/Stop Error interrupt Enable */
> > +FIELD(FLEXCOMM_I2C_INTENSET, MSTSTSTPERREN, 6, 1);
> > +/* Slave Pending interrupt Enable */
> > +FIELD(FLEXCOMM_I2C_INTENSET, SLVPENDINGEN, 8, 1);
> > +/* Slave Not Stretching interrupt Enable */
> > +FIELD(FLEXCOMM_I2C_INTENSET, SLVNOTSTREN, 11, 1);
> > +/* Slave Deselect interrupt Enable */
> > +FIELD(FLEXCOMM_I2C_INTENSET, SLVDESELEN, 15, 1);
> > +/* Monitor data Ready interrupt Enable */
> > +FIELD(FLEXCOMM_I2C_INTENSET, MONRDYEN, 16, 1);
> > +/* Monitor Overrun interrupt Enable */
> > +FIELD(FLEXCOMM_I2C_INTENSET, MONOVEN, 17, 1);
> > +/* Monitor Idle interrupt Enable */
> > +FIELD(FLEXCOMM_I2C_INTENSET, MONIDLEEN, 19, 1);
> > +/* Event Time-out interrupt Enable */
> > +FIELD(FLEXCOMM_I2C_INTENSET, EVENTTIMEOUTEN, 24, 1);
> > +/* SCL Time-out interrupt Enable */
> > +FIELD(FLEXCOMM_I2C_INTENSET, SCLTIMEOUTEN, 25, 1);
> > +
> > +/* Interrupt Enable Clear Register */
> > +REG32(FLEXCOMM_I2C_INTENCLR, 2060);
> > +/* Master Pending interrupt clear */
> > +FIELD(FLEXCOMM_I2C_INTENCLR, MSTPENDINGCLR, 0, 1);
> > +/* Master Arbitration Loss interrupt clear */
> > +FIELD(FLEXCOMM_I2C_INTENCLR, MSTARBLOSSCLR, 4, 1);
> > +/* Master Start/Stop Error interrupt clear */
> > +FIELD(FLEXCOMM_I2C_INTENCLR, MSTSTSTPERRCLR, 6, 1);
> > +/* Slave Pending interrupt clear */
> > +FIELD(FLEXCOMM_I2C_INTENCLR, SLVPENDINGCLR, 8, 1);
> > +/* Slave Not Stretching interrupt clear */
> > +FIELD(FLEXCOMM_I2C_INTENCLR, SLVNOTSTRCLR, 11, 1);
> > +/* Slave Deselect interrupt clear */
> > +FIELD(FLEXCOMM_I2C_INTENCLR, SLVDESELCLR, 15, 1);
> > +/* Monitor data Ready interrupt clear */
> > +FIELD(FLEXCOMM_I2C_INTENCLR, MONRDYCLR, 16, 1);
> > +/* Monitor Overrun interrupt clear */
> > +FIELD(FLEXCOMM_I2C_INTENCLR, MONOVCLR, 17, 1);
> > +/* Monitor Idle interrupt clear */
> > +FIELD(FLEXCOMM_I2C_INTENCLR, MONIDLECLR, 19, 1);
> > +/* Event time-out interrupt clear */
> > +FIELD(FLEXCOMM_I2C_INTENCLR, EVENTTIMEOUTCLR, 24, 1);
> > +/* SCL time-out interrupt clear */
> > +FIELD(FLEXCOMM_I2C_INTENCLR, SCLTIMEOUTCLR, 25, 1);
> > +
> > +/* Time-out Register */
> > +REG32(FLEXCOMM_I2C_TIMEOUT, 2064);
> > +/* Time-out time value, the bottom 4 bits */
> > +FIELD(FLEXCOMM_I2C_TIMEOUT, TOMIN, 0, 4);
> > +/* Time-out time value */
> > +FIELD(FLEXCOMM_I2C_TIMEOUT, TO, 4, 12);
> > +
> > +/* Clock Divider Register */
> > +REG32(FLEXCOMM_I2C_CLKDIV, 2068);
> > +/* Divider Value */
> > +FIELD(FLEXCOMM_I2C_CLKDIV, DIVVAL, 0, 16);
> > +
> > +/* Interrupt Status Register */
> > +REG32(FLEXCOMM_I2C_INTSTAT, 2072);
> > +/* Master Pending */
> > +FIELD(FLEXCOMM_I2C_INTSTAT, MSTPENDING, 0, 1);
> > +/* Master Arbitration Loss flag */
> > +FIELD(FLEXCOMM_I2C_INTSTAT, MSTARBLOSS, 4, 1);
> > +/* Master Start/Stop Error flag */
> > +FIELD(FLEXCOMM_I2C_INTSTAT, MSTSTSTPERR, 6, 1);
> > +/* Slave Pending */
> > +FIELD(FLEXCOMM_I2C_INTSTAT, SLVPENDING, 8, 1);
> > +/* Slave Not Stretching status */
> > +FIELD(FLEXCOMM_I2C_INTSTAT, SLVNOTSTR, 11, 1);
> > +/* Slave Deselected flag */
> > +FIELD(FLEXCOMM_I2C_INTSTAT, SLVDESEL, 15, 1);
> > +/* Monitor Ready */
> > +FIELD(FLEXCOMM_I2C_INTSTAT, MONRDY, 16, 1);
> > +/* Monitor Overflow flag */
> > +FIELD(FLEXCOMM_I2C_INTSTAT, MONOV, 17, 1);
> > +/* Monitor Idle flag */
> > +FIELD(FLEXCOMM_I2C_INTSTAT, MONIDLE, 19, 1);
> > +/* Event Time-out Interrupt flag */
> > +FIELD(FLEXCOMM_I2C_INTSTAT, EVENTTIMEOUT, 24, 1);
> > +/* SCL Time-out Interrupt flag */
> > +FIELD(FLEXCOMM_I2C_INTSTAT, SCLTIMEOUT, 25, 1);
> > +
> > +/* Master Control Register */
> > +REG32(FLEXCOMM_I2C_MSTCTL, 2080);
> > +/* Master Continue(write-only) */
> > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTCONTINUE, 0, 1);
> > +/* Master Start control(write-only) */
> > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTART, 1, 1);
> > +/* Master Stop control(write-only) */
> > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTOP, 2, 1);
> > +/* Master DMA enable */
> > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTDMA, 3, 1);
> > +
> > +/* Master Timing Register */
> > +REG32(FLEXCOMM_I2C_MSTTIME, 2084);
> > +/* Master SCL Low time */
> > +FIELD(FLEXCOMM_I2C_MSTTIME, MSTSCLLOW, 0, 3);
> > +/* Master SCL High time */
> > +FIELD(FLEXCOMM_I2C_MSTTIME, MSTSCLHIGH, 4, 3);
> > +
> > +/* Master Data Register */
> > +REG32(FLEXCOMM_I2C_MSTDAT, 2088);
> > +/* Master function data register */
> > +FIELD(FLEXCOMM_I2C_MSTDAT, DATA, 0, 8);
> > +
> > +/* Slave Control Register */
> > +REG32(FLEXCOMM_I2C_SLVCTL, 2112);
> > +/* Slave Continue */
> > +FIELD(FLEXCOMM_I2C_SLVCTL, SLVCONTINUE, 0, 1);
> > +/* Slave NACK */
> > +FIELD(FLEXCOMM_I2C_SLVCTL, SLVNACK, 1, 1);
> > +/* Slave DMA enable */
> > +FIELD(FLEXCOMM_I2C_SLVCTL, SLVDMA, 3, 1);
> > +/* Automatic Acknowledge */
> > +FIELD(FLEXCOMM_I2C_SLVCTL, AUTOACK, 8, 1);
> > +/* Automatic Match Read */
> > +FIELD(FLEXCOMM_I2C_SLVCTL, AUTOMATCHREAD, 9, 1);
> > +
> > +/* Slave Data Register */
> > +REG32(FLEXCOMM_I2C_SLVDAT, 2116);
> > +/* Slave function data register */
> > +FIELD(FLEXCOMM_I2C_SLVDAT, DATA, 0, 8);
> > +
> > +/* Slave Address Register */
> > +REG32(FLEXCOMM_I2C_SLVADR0, 2120);
> > +/* Slave Address n Disable */
> > +FIELD(FLEXCOMM_I2C_SLVADR0, SADISABLE, 0, 1);
> > +/* Slave Address. */
> > +FIELD(FLEXCOMM_I2C_SLVADR0, SLVADR, 1, 7);
> > +/* Automatic NACK operation */
> > +FIELD(FLEXCOMM_I2C_SLVADR0, AUTONACK, 15, 1);
> > +
> > +/* Slave Address Register */
> > +REG32(FLEXCOMM_I2C_SLVADR1, 2124);
> > +/* Slave Address n Disable */
> > +FIELD(FLEXCOMM_I2C_SLVADR1, SADISABLE, 0, 1);
> > +/* Slave Address. */
> > +FIELD(FLEXCOMM_I2C_SLVADR1, SLVADR, 1, 7);
> > +/* Automatic NACK operation */
> > +FIELD(FLEXCOMM_I2C_SLVADR1, AUTONACK, 15, 1);
> > +
> > +/* Slave Address Register */
> > +REG32(FLEXCOMM_I2C_SLVADR2, 2128);
> > +/* Slave Address n Disable */
> > +FIELD(FLEXCOMM_I2C_SLVADR2, SADISABLE, 0, 1);
> > +/* Slave Address. */
> > +FIELD(FLEXCOMM_I2C_SLVADR2, SLVADR, 1, 7);
> > +/* Automatic NACK operation */
> > +FIELD(FLEXCOMM_I2C_SLVADR2, AUTONACK, 15, 1);
> > +
> > +/* Slave Address Register */
> > +REG32(FLEXCOMM_I2C_SLVADR3, 2132);
> > +/* Slave Address n Disable */
> > +FIELD(FLEXCOMM_I2C_SLVADR3, SADISABLE, 0, 1);
> > +/* Slave Address. */
> > +FIELD(FLEXCOMM_I2C_SLVADR3, SLVADR, 1, 7);
> > +/* Automatic NACK operation */
> > +FIELD(FLEXCOMM_I2C_SLVADR3, AUTONACK, 15, 1);
> > +
> > +/* Slave Qualification for Address 0 Register */
> > +REG32(FLEXCOMM_I2C_SLVQUAL0, 2136);
> > +/* Qualify mode for slave address 0 */
> > +FIELD(FLEXCOMM_I2C_SLVQUAL0, QUALMODE0, 0, 1);
> > +/* Slave address Qualifier for address 0 */
> > +FIELD(FLEXCOMM_I2C_SLVQUAL0, SLVQUAL0, 1, 7);
> > +
> > +/* Monitor Receiver Data Register */
> > +REG32(FLEXCOMM_I2C_MONRXDAT, 2176);
> > +/* Monitor function Receiver Data */
> > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONRXDAT, 0, 8);
> > +/* Monitor Received Start */
> > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONSTART, 8, 1);
> > +/* Monitor Received Repeated Start */
> > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONRESTART, 9, 1);
> > +/* Monitor Received NACK */
> > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONNACK, 10, 1);
> > +
> > +/* Peripheral Identification Register */
> > +REG32(FLEXCOMM_I2C_ID, 4092);
> > +/* Aperture */
> > +FIELD(FLEXCOMM_I2C_ID, APERTURE, 0, 8);
> > +/* Minor revision of module implementation */
> > +FIELD(FLEXCOMM_I2C_ID, MINOR_REV, 8, 4);
> > +/* Major revision of module implementation */
> > +FIELD(FLEXCOMM_I2C_ID, MAJOR_REV, 12, 4);
> > +/* Module identifier for the selected function */
> > +FIELD(FLEXCOMM_I2C_ID, ID, 16, 16);
> > +
>
> Are any of the below enums even used? Or for that matter, most of the
> above fields?
>
> If these are just here for documentation, I would prefer English text;
> it's more dense and easier to read. It's very difficult to tie all this
> together into a cohesive view of the device registers.
>
Since this is autogenerated for the full set of the device registers
there will be fields that are not used either because the emulation is
incomplete or because they don't have effect for emulation.
I think it is still valuable to have this generated automatically
instead of doing it by hand.
Would adding options to only generate certain definitions help? As
long as we are reasonable with the granularity (e.g. register level) I
think it could trim *most* of the unused generated code without
becoming too tedious on how to instruct the tool to generate the code.
However, I expect to still have *some* unused generated code.
> The .c file itself seems ok.
>
> -corey
>
> > +
> > +typedef enum {
> > + /*
> > + * Disabled. The I2C Master function is disabled. When disabled, the Master
> > + * configuration settings are not changed, but the Master function is
> > + * internally reset.
> > + */
> > + FLEXCOMM_I2C_CFG_MSTEN_DISABLED = 0,
> > + /* Enabled. The I2C Master function is enabled. */
> > + FLEXCOMM_I2C_CFG_MSTEN_ENABLED = 1,
> > +} FLEXCOMM_I2C_CFG_MSTEN_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * Disabled. The I2C slave function is disabled. When disabled, the Slave
> > + * configuration settings are not changed, but the Slave function is
> > + * internally reset.
> > + */
> > + FLEXCOMM_I2C_CFG_SLVEN_DISABLED = 0,
> > + /* Enabled. The I2C slave function is enabled. */
> > + FLEXCOMM_I2C_CFG_SLVEN_ENABLED = 1,
> > +} FLEXCOMM_I2C_CFG_SLVEN_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * Disabled. The I2C Monitor function is disabled. When disabled, the
> > + * Monitor function configuration settings are not changed, but the Monitor
> > + * function is internally reset.
> > + */
> > + FLEXCOMM_I2C_CFG_MONEN_DISABLED = 0,
> > + /* Enabled. The I2C Monitor function is enabled. */
> > + FLEXCOMM_I2C_CFG_MONEN_ENABLED = 1,
> > +} FLEXCOMM_I2C_CFG_MONEN_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * Disabled. The time-out function is disabled. When disabled, the time-out
> > + * function is internally reset.
> > + */
> > + FLEXCOMM_I2C_CFG_TIMEOUTEN_DISABLED = 0,
> > + /*
> > + * Enabled. The time-out function is enabled. Both types of time-out flags
> > + * will be generated and will cause interrupts if those flags are enabled.
> > + * Typically, only one time-out flag will be used in a system.
> > + */
> > + FLEXCOMM_I2C_CFG_TIMEOUTEN_ENABLED = 1,
> > +} FLEXCOMM_I2C_CFG_TIMEOUTEN_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * Disabled. The Monitor function will not perform clock stretching.
> > + * Software or DMA may not always be able to read data provided by the
> > + * Monitor function before it (the data) is overwritten. This mode can be
> > + * used when non-invasive monitoring is critical.
> > + */
> > + FLEXCOMM_I2C_CFG_MONCLKSTR_DISABLED = 0,
> > + /*
> > + * Enabled. The Monitor function will perform clock stretching, to ensure
> > + * that the software or DMA can read all incoming data supplied by the
> > + * Monitor function.
> > + */
> > + FLEXCOMM_I2C_CFG_MONCLKSTR_ENABLED = 1,
> > +} FLEXCOMM_I2C_CFG_MONCLKSTR_Enum;
> > +
> > +typedef enum {
> > + /* Fast mode Plus enable */
> > + FLEXCOMM_I2C_CFG_HSCAPABLE_FAST_MODE_PLUS = 0,
> > + /* High Speed mode enable */
> > + FLEXCOMM_I2C_CFG_HSCAPABLE_HIGH_SPEED = 1,
> > +} FLEXCOMM_I2C_CFG_HSCAPABLE_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * In progress. Communication is in progress and the Master function is
> > + * busy and cannot currently accept a command.
> > + */
> > + FLEXCOMM_I2C_STAT_MSTPENDING_IN_PROGRESS = 0,
> > + /*
> > + * Pending. The Master function needs software service or is in the idle
> > + * state. If the master is not in the idle state, then the master is
> > + * waiting to receive or transmit data, or is waiting for the NACK bit.
> > + */
> > + FLEXCOMM_I2C_STAT_MSTPENDING_PENDING = 1,
> > +} FLEXCOMM_I2C_STAT_MSTPENDING_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * Idle. The Master function is available to be used for a new transaction.
> > + */
> > + FLEXCOMM_I2C_STAT_MSTSTATE_IDLE = 0,
> > + /*
> > + * Receive ready. Received data is available (in Master Receiver mode).
> > + * Address plus Read was previously sent and Acknowledged by a slave.
> > + */
> > + FLEXCOMM_I2C_STAT_MSTSTATE_RECEIVE_READY = 1,
> > + /*
> > + * Transmit ready. Data can be transmitted (in Master Transmitter mode).
> > + * Address plus Write was previously sent and Acknowledged by a slave.
> > + */
> > + FLEXCOMM_I2C_STAT_MSTSTATE_TRANSMIT_READY = 2,
> > + /* NACK Address. Slave NACKed address. */
> > + FLEXCOMM_I2C_STAT_MSTSTATE_NACK_ADDRESS = 3,
> > + /* NACK Data. Slave NACKed transmitted data. */
> > + FLEXCOMM_I2C_STAT_MSTSTATE_NACK_DATA = 4,
> > +} FLEXCOMM_I2C_STAT_MSTSTATE_Enum;
> > +
> > +typedef enum {
> > + /* No Arbitration Loss has occurred */
> > + FLEXCOMM_I2C_STAT_MSTARBLOSS_NO_LOSS = 0,
> > + /*
> > + * Arbitration loss. The Master function has experienced an Arbitration
> > + * Loss. At this point, the Master function has already stopped driving the
> > + * bus and has gone into an idle state. Software can respond by doing
> > + * nothing, or by sending a Start (to attempt to gain control of the bus
> > + * when the bus next becomes idle).
> > + */
> > + FLEXCOMM_I2C_STAT_MSTARBLOSS_ARBITRATION_LOSS = 1,
> > +} FLEXCOMM_I2C_STAT_MSTARBLOSS_Enum;
> > +
> > +typedef enum {
> > + /* No Start/Stop Error has occurred. */
> > + FLEXCOMM_I2C_STAT_MSTSTSTPERR_NO_ERROR = 0,
> > + /*
> > + * The Master function has experienced a Start/Stop Error. A Start or Stop
> > + * was detected at a time when Start or Stop is not allowed by the I2C
> > + * specification. The Master interface has stopped driving the bus and gone
> > + * into an idle state; no action is required. A request for a Start could
> > + * be made, or software could attempt to make sure that the bus has not
> > + * stalled.
> > + */
> > + FLEXCOMM_I2C_STAT_MSTSTSTPERR_ERROR = 1,
> > +} FLEXCOMM_I2C_STAT_MSTSTSTPERR_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * In progress. The Slave function does not currently need software
> > + * service.
> > + */
> > + FLEXCOMM_I2C_STAT_SLVPENDING_IN_PROGRESS = 0,
> > + /*
> > + * Pending. The Slave function needs software service. Information about
> > + * what is needed is in the Slave state field (SLVSTATE).
> > + */
> > + FLEXCOMM_I2C_STAT_SLVPENDING_PENDING = 1,
> > +} FLEXCOMM_I2C_STAT_SLVPENDING_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * Slave address. Address plus R/W received. At least one of the 4 slave
> > + * addresses has been matched by hardware.
> > + */
> > + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_ADDRESS = 0,
> > + /* Slave receive. Received data is available (in Slave Receiver mode). */
> > + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_RECEIVE = 1,
> > + /* Slave transmit. Data can be transmitted (in Slave Transmitter mode). */
> > + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_TRANSMIT = 2,
> > +} FLEXCOMM_I2C_STAT_SLVSTATE_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * Stretching. The slave function is currently stretching the I2C bus
> > + * clock. Deep-Sleepmode cannot be entered at this time.
> > + */
> > + FLEXCOMM_I2C_STAT_SLVNOTSTR_STRETCHING = 0,
> > + /*
> > + * Not stretching. The slave function is not currently stretching the I2C
> > + * bus clock. Deep-sleep mode can be entered at this time.
> > + */
> > + FLEXCOMM_I2C_STAT_SLVNOTSTR_NOT_STRETCHING = 1,
> > +} FLEXCOMM_I2C_STAT_SLVNOTSTR_Enum;
> > +
> > +typedef enum {
> > + /* Address 0. Slave address 0 was matched. */
> > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS0 = 0,
> > + /* Address 1. Slave address 1 was matched. */
> > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS1 = 1,
> > + /* Address 2. Slave address 2 was matched. */
> > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS2 = 2,
> > + /* Address 3. Slave address 3 was matched. */
> > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS3 = 3,
> > +} FLEXCOMM_I2C_STAT_SLVIDX_Enum;
> > +
> > +typedef enum {
> > + /* Not selected. The Slave function is not currently selected. */
> > + FLEXCOMM_I2C_STAT_SLVSEL_NOT_SELECTED = 0,
> > + /* Selected. The Slave function is currently selected. */
> > + FLEXCOMM_I2C_STAT_SLVSEL_SELECTED = 1,
> > +} FLEXCOMM_I2C_STAT_SLVSEL_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * Not deselected. The Slave function has not become deselected. This does
> > + * not mean that the Slave is currently selected. That information is in
> > + * the SLVSEL flag.
> > + */
> > + FLEXCOMM_I2C_STAT_SLVDESEL_NOT_DESELECTED = 0,
> > + /*
> > + * Deselected. The Slave function has become deselected. This is
> > + * specifically caused by the SLVSEL flag changing from 1 to 0. See SLVSEL
> > + * for details about when that event occurs.
> > + */
> > + FLEXCOMM_I2C_STAT_SLVDESEL_DESELECTED = 1,
> > +} FLEXCOMM_I2C_STAT_SLVDESEL_Enum;
> > +
> > +typedef enum {
> > + /* No data. The Monitor function does not currently have data available. */
> > + FLEXCOMM_I2C_STAT_MONRDY_NO_DATA = 0,
> > + /* Data waiting. The Monitor function has data waiting to be read. */
> > + FLEXCOMM_I2C_STAT_MONRDY_DATA_WAITING = 1,
> > +} FLEXCOMM_I2C_STAT_MONRDY_Enum;
> > +
> > +typedef enum {
> > + /* No overrun. Monitor data has not overrun. */
> > + FLEXCOMM_I2C_STAT_MONOV_NO_OVERRUN = 0,
> > + /*
> > + * Overrun. A Monitor data overrun has occurred. An overrun can only happen
> > + * when Monitor clock stretching not enabled via the CFG[MONCLKSTR] bit.
> > + * Writing 1 to MONOV bit clears the MONOV flag.
> > + */
> > + FLEXCOMM_I2C_STAT_MONOV_OVERRUN = 1,
> > +} FLEXCOMM_I2C_STAT_MONOV_Enum;
> > +
> > +typedef enum {
> > + /* Inactive. The Monitor function considers the I2C bus to be inactive. */
> > + FLEXCOMM_I2C_STAT_MONACTIVE_INACTIVE = 0,
> > + /* Active. The Monitor function considers the I2C bus to be active. */
> > + FLEXCOMM_I2C_STAT_MONACTIVE_ACTIVE = 1,
> > +} FLEXCOMM_I2C_STAT_MONACTIVE_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * Not idle. The I2C bus is not idle, or MONIDLE flag has been cleared by
> > + * software.
> > + */
> > + FLEXCOMM_I2C_STAT_MONIDLE_NOT_IDLE = 0,
> > + /*
> > + * Idle. The I2C bus has gone idle at least once, since the last time
> > + * MONIDLE flag was cleared by software.
> > + */
> > + FLEXCOMM_I2C_STAT_MONIDLE_IDLE = 1,
> > +} FLEXCOMM_I2C_STAT_MONIDLE_Enum;
> > +
> > +typedef enum {
> > + /* No time-out. I2C bus events have not caused a time-out. */
> > + FLEXCOMM_I2C_STAT_EVENTTIMEOUT_NO_TIMEOUT = 0,
> > + /*
> > + * Event time-out. The time between I2C bus events has been longer than the
> > + * time specified by the TIMEOUT register.
> > + */
> > + FLEXCOMM_I2C_STAT_EVENTTIMEOUT_EVEN_TIMEOUT = 1,
> > +} FLEXCOMM_I2C_STAT_EVENTTIMEOUT_Enum;
> > +
> > +typedef enum {
> > + /* No time-out. SCL low time has not caused a time-out. */
> > + FLEXCOMM_I2C_STAT_SCLTIMEOUT_NO_TIMEOUT = 0,
> > + /* Time-out. SCL low time has caused a time-out. */
> > + FLEXCOMM_I2C_STAT_SCLTIMEOUT_TIMEOUT = 1,
> > +} FLEXCOMM_I2C_STAT_SCLTIMEOUT_Enum;
> > +
> > +typedef enum {
> > + /* Disabled. The MstPending interrupt is disabled. */
> > + FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_DISABLED = 0,
> > + /* Enabled. The MstPending interrupt is enabled. */
> > + FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_ENABLED = 1,
> > +} FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_Enum;
> > +
> > +typedef enum {
> > + /* Disabled. The MstArbLoss interrupt is disabled. */
> > + FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_DISABLED = 0,
> > + /* Enabled. The MstArbLoss interrupt is enabled. */
> > + FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_ENABLED = 1,
> > +} FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_Enum;
> > +
> > +typedef enum {
> > + /* Disabled. The MstStStpErr interrupt is disabled. */
> > + FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_DISABLED = 0,
> > + /* Enabled. The MstStStpErr interrupt is enabled. */
> > + FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_ENABLED = 1,
> > +} FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_Enum;
> > +
> > +typedef enum {
> > + /* Disabled. The SlvPending interrupt is disabled. */
> > + FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_DISABLED = 0,
> > + /* Enabled. The SlvPending interrupt is enabled. */
> > + FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_ENABLED = 1,
> > +} FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_Enum;
> > +
> > +typedef enum {
> > + /* Disabled. The SlvNotStr interrupt is disabled. */
> > + FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_DISABLED = 0,
> > + /* Enabled. The SlvNotStr interrupt is enabled. */
> > + FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_ENABLED = 1,
> > +} FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_Enum;
> > +
> > +typedef enum {
> > + /* Disabled. The SlvDeSel interrupt is disabled. */
> > + FLEXCOMM_I2C_INTENSET_SLVDESELEN_DISABLED = 0,
> > + /* Enabled. The SlvDeSel interrupt is enabled. */
> > + FLEXCOMM_I2C_INTENSET_SLVDESELEN_ENABLED = 1,
> > +} FLEXCOMM_I2C_INTENSET_SLVDESELEN_Enum;
> > +
> > +typedef enum {
> > + /* Disabled. The MonRdy interrupt is disabled. */
> > + FLEXCOMM_I2C_INTENSET_MONRDYEN_DISABLED = 0,
> > + /* Enabled. The MonRdy interrupt is enabled. */
> > + FLEXCOMM_I2C_INTENSET_MONRDYEN_ENABLED = 1,
> > +} FLEXCOMM_I2C_INTENSET_MONRDYEN_Enum;
> > +
> > +typedef enum {
> > + /* Disabled. The MonOv interrupt is disabled. */
> > + FLEXCOMM_I2C_INTENSET_MONOVEN_DISABLED = 0,
> > + /* Enabled. The MonOv interrupt is enabled. */
> > + FLEXCOMM_I2C_INTENSET_MONOVEN_ENABLED = 1,
> > +} FLEXCOMM_I2C_INTENSET_MONOVEN_Enum;
> > +
> > +typedef enum {
> > + /* Disabled. The MonIdle interrupt is disabled. */
> > + FLEXCOMM_I2C_INTENSET_MONIDLEEN_DISABLED = 0,
> > + /* Enabled. The MonIdle interrupt is enabled. */
> > + FLEXCOMM_I2C_INTENSET_MONIDLEEN_ENABLED = 1,
> > +} FLEXCOMM_I2C_INTENSET_MONIDLEEN_Enum;
> > +
> > +typedef enum {
> > + /* Disabled. The Event time-out interrupt is disabled. */
> > + FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_DISABLED = 0,
> > + /* Enabled. The Event time-out interrupt is enabled. */
> > + FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_ENABLED = 1,
> > +} FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_Enum;
> > +
> > +typedef enum {
> > + /* Disabled. The SCL time-out interrupt is disabled. */
> > + FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_DISABLED = 0,
> > + /* Enabled. The SCL time-out interrupt is enabled. */
> > + FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_ENABLED = 1,
> > +} FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_Enum;
> > +
> > +typedef enum {
> > + /* No effect on interrupt */
> > + FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_NO_EFFECT = 0,
> > + /* Clears the interrupt bit in INTENSET register */
> > + FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_CLEAR_MSTPENDING = 1,
> > +} FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_Enum;
> > +
> > +typedef enum {
> > + /* No effect on interrupt */
> > + FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_NO_EFFECT = 0,
> > + /* Clears the interrupt bit in INTENSET register */
> > + FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_CLEAR_MSTARBLOSS = 1,
> > +} FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_Enum;
> > +
> > +typedef enum {
> > + /* No effect on interrupt */
> > + FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_NO_EFFECT = 0,
> > + /* Clears the interrupt bit in INTENSET register */
> > + FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_CLEAR_MSTSTSTPERR = 1,
> > +} FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_Enum;
> > +
> > +typedef enum {
> > + /* No effect on interrupt */
> > + FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_NO_EFFECT = 0,
> > + /* Clears the interrupt bit in INTENSET register */
> > + FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_CLEAR_SLVPENDING = 1,
> > +} FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_Enum;
> > +
> > +typedef enum {
> > + /* No effect on interrupt */
> > + FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_NO_EFFECT = 0,
> > + /* Clears the interrupt bit in INTENSET register */
> > + FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_CLEAR_SLVNOTSTR = 1,
> > +} FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_Enum;
> > +
> > +typedef enum {
> > + /* No effect on interrupt */
> > + FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_NO_EFFECT = 0,
> > + /* Clears the interrupt bit in INTENSET register */
> > + FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_CLEAR_SLVDESEL = 1,
> > +} FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_Enum;
> > +
> > +typedef enum {
> > + /* No effect on interrupt */
> > + FLEXCOMM_I2C_INTENCLR_MONRDYCLR_NO_EFFECT = 0,
> > + /* Clears the interrupt bit in INTENSET register */
> > + FLEXCOMM_I2C_INTENCLR_MONRDYCLR_CLEAR_MONRDY = 1,
> > +} FLEXCOMM_I2C_INTENCLR_MONRDYCLR_Enum;
> > +
> > +typedef enum {
> > + /* No effect on interrupt */
> > + FLEXCOMM_I2C_INTENCLR_MONOVCLR_NO_EFFECT = 0,
> > + /* Clears the interrupt bit in INTENSET register */
> > + FLEXCOMM_I2C_INTENCLR_MONOVCLR_CLEAR_MONOV = 1,
> > +} FLEXCOMM_I2C_INTENCLR_MONOVCLR_Enum;
> > +
> > +typedef enum {
> > + /* No effect on interrupt */
> > + FLEXCOMM_I2C_INTENCLR_MONIDLECLR_NO_EFFECT = 0,
> > + /* Clears the interrupt bit in INTENSET register */
> > + FLEXCOMM_I2C_INTENCLR_MONIDLECLR_CLEAR_MONIDLE = 1,
> > +} FLEXCOMM_I2C_INTENCLR_MONIDLECLR_Enum;
> > +
> > +typedef enum {
> > + /* No effect on interrupt */
> > + FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_NO_EFFECT = 0,
> > + /* Clears the interrupt bit in INTENSET register */
> > + FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_CLEAR_EVENTTIMEOUT = 1,
> > +} FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_Enum;
> > +
> > +typedef enum {
> > + /* No effect on interrupt */
> > + FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_NO_EFFECT = 0,
> > + /* Clears the interrupt bit in INTENSET register */
> > + FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_CLEAR_SCLTIMEOUT = 1,
> > +} FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_Enum;
> > +
> > +typedef enum {
> > + /* A time-out will occur after 16 counts of the I2C function clock. */
> > + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT16 = 0,
> > + /* A time-out will occur after 32 counts of the I2C function clock. */
> > + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT32 = 1,
> > + /* A time-out will occur after 65,536 counts of the I2C function clock. */
> > + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT65K = 4095,
> > +} FLEXCOMM_I2C_TIMEOUT_TO_Enum;
> > +
> > +typedef enum {
> > + /* FCLK is used directly by the I2C. */
> > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKUNDIVIDED = 0,
> > + /* FCLK is divided by 2 before being used by the I2C. */
> > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV2 = 1,
> > + /* FCLK is divided by 3 before being used by the I2C. */
> > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV3 = 2,
> > + /* FCLK is divided by 65,536 before being used by the I2C. */
> > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV65K = 65535,
> > +} FLEXCOMM_I2C_CLKDIV_DIVVAL_Enum;
> > +
> > +typedef enum {
> > + /* Not active */
> > + FLEXCOMM_I2C_INTSTAT_MSTPENDING_MSTPENDING_ISNOTACTIVE = 0,
> > + /* Active */
> > + FLEXCOMM_I2C_INTSTAT_MSTPENDING_MSTPENDING_ISACTIVE = 1,
> > +} FLEXCOMM_I2C_INTSTAT_MSTPENDING_Enum;
> > +
> > +typedef enum {
> > + /* Not active */
> > + FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_MSTARBLOSS_ISNOTACTIVE = 0,
> > + /* Active */
> > + FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_MSTARBLOSS_ISACTIVE = 1,
> > +} FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_Enum;
> > +
> > +typedef enum {
> > + /* Not active */
> > + FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_MSTSTSTPERR_ISNOTACTIVE = 0,
> > + /* Active */
> > + FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_MSTSTSTPERR_ISACTIVE = 1,
> > +} FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_Enum;
> > +
> > +typedef enum {
> > + /* Not active */
> > + FLEXCOMM_I2C_INTSTAT_SLVPENDING_SLVPENDING_ISNOTACTIVE = 0,
> > + /* Active */
> > + FLEXCOMM_I2C_INTSTAT_SLVPENDING_SLVPENDING_ISACTIVE = 1,
> > +} FLEXCOMM_I2C_INTSTAT_SLVPENDING_Enum;
> > +
> > +typedef enum {
> > + /* Not active */
> > + FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_SLVNOTSTR_ISNOTACTIVE = 0,
> > + /* Active */
> > + FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_SLVNOTSTR_ISACTIVE = 1,
> > +} FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_Enum;
> > +
> > +typedef enum {
> > + /* Not active */
> > + FLEXCOMM_I2C_INTSTAT_SLVDESEL_SLVDESEL_ISNOTACTIVE = 0,
> > + /* Active */
> > + FLEXCOMM_I2C_INTSTAT_SLVDESEL_SLVDESEL_ISACTIVE = 1,
> > +} FLEXCOMM_I2C_INTSTAT_SLVDESEL_Enum;
> > +
> > +typedef enum {
> > + /* Not active */
> > + FLEXCOMM_I2C_INTSTAT_MONRDY_MONRDY_ISNOTACTIVE = 0,
> > + /* Active */
> > + FLEXCOMM_I2C_INTSTAT_MONRDY_MONRDY_ISACTIVE = 1,
> > +} FLEXCOMM_I2C_INTSTAT_MONRDY_Enum;
> > +
> > +typedef enum {
> > + /* Not active */
> > + FLEXCOMM_I2C_INTSTAT_MONOV_MONOV_ISNOTACTIVE = 0,
> > + /* Active */
> > + FLEXCOMM_I2C_INTSTAT_MONOV_MONOV_ISACTIVE = 1,
> > +} FLEXCOMM_I2C_INTSTAT_MONOV_Enum;
> > +
> > +typedef enum {
> > + /* Not active */
> > + FLEXCOMM_I2C_INTSTAT_MONIDLE_MONIDLE_ISNOTACTIVE = 0,
> > + /* Active */
> > + FLEXCOMM_I2C_INTSTAT_MONIDLE_MONIDLE_ISACTIVE = 1,
> > +} FLEXCOMM_I2C_INTSTAT_MONIDLE_Enum;
> > +
> > +typedef enum {
> > + /* Not active */
> > + FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_EVENTTIMEOUT_ISNOTACTIVE = 0,
> > + /* Active */
> > + FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_EVENTTIMEOUT_ISACTIVE = 1,
> > +} FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_Enum;
> > +
> > +typedef enum {
> > + /* Not active */
> > + FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_SCLTIMEOUT_ISNOTACTIVE = 0,
> > + /* Active */
> > + FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_SCLTIMEOUT_ISACTIVE = 1,
> > +} FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_Enum;
> > +
> > +typedef enum {
> > + /* No effect */
> > + FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_NO_EFFECT = 0,
> > + /*
> > + * Continue. Informs the Master function to continue to the next operation.
> > + * This action must done after writing transmit data, reading received
> > + * data, or any other housekeeping related to the next bus operation.
> > + */
> > + FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_CONTINUE = 1,
> > +} FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_Enum;
> > +
> > +typedef enum {
> > + /* No effect */
> > + FLEXCOMM_I2C_MSTCTL_MSTSTART_NO_EFFECT = 0,
> > + /*
> > + * Start. A Start will be generated on the I2C bus at the next allowed
> > + * time.
> > + */
> > + FLEXCOMM_I2C_MSTCTL_MSTSTART_START = 1,
> > +} FLEXCOMM_I2C_MSTCTL_MSTSTART_Enum;
> > +
> > +typedef enum {
> > + /* No effect */
> > + FLEXCOMM_I2C_MSTCTL_MSTSTOP_NO_EFFECT = 0,
> > + /*
> > + * Stop. A Stop will be generated on the I2C bus at the next allowed time,
> > + * preceded by a NACK to the slave if the master is receiving data from the
> > + * slave (in Master Receiver mode).
> > + */
> > + FLEXCOMM_I2C_MSTCTL_MSTSTOP_STOP = 1,
> > +} FLEXCOMM_I2C_MSTCTL_MSTSTOP_Enum;
> > +
> > +typedef enum {
> > + /* Disable. No DMA requests are generated for master operation. */
> > + FLEXCOMM_I2C_MSTCTL_MSTDMA_DISABLED = 0,
> > + /*
> > + * Enable. A DMA request is generated for I2C master data operations. When
> > + * this I2C master is generating Acknowledge bits in Master Receiver mode,
> > + * the acknowledge is generated automatically.
> > + */
> > + FLEXCOMM_I2C_MSTCTL_MSTDMA_ENABLED = 1,
> > +} FLEXCOMM_I2C_MSTCTL_MSTDMA_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * 2 clocks. Minimum SCL low time is 2 clocks of the I2C clock pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_2CLOCKS = 0,
> > + /*
> > + * 3 clocks. Minimum SCL low time is 3 clocks of the I2C clock pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_3CLOCKS = 1,
> > + /*
> > + * 4 clocks. Minimum SCL low time is 4 clocks of the I2C clock pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_4CLOCKS = 2,
> > + /*
> > + * 5 clocks. Minimum SCL low time is 5 clocks of the I2C clock pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_5CLOCKS = 3,
> > + /*
> > + * 6 clocks. Minimum SCL low time is 6 clocks of the I2C clock pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_6CLOCKS = 4,
> > + /*
> > + * 7 clocks. Minimum SCL low time is 7 clocks of the I2C clock pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_7CLOCKS = 5,
> > + /*
> > + * 8 clocks. Minimum SCL low time is 8 clocks of the I2C clock pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_8CLOCKS = 6,
> > + /*
> > + * 9 clocks. Minimum SCL low time is 9 clocks of the I2C clock pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_9CLOCKS = 7,
> > +} FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * 2 clocks. Minimum SCL high time is 2 clocks of the I2C clock
> > + * pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_2CLOCKS = 0,
> > + /*
> > + * 3 clocks. Minimum SCL high time is 3 clocks of the I2C clock pre-divider
> > + * .
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_3CLOCKS = 1,
> > + /*
> > + * 4 clocks. Minimum SCL high time is 4 clocks of the I2C clock
> > + * pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_4CLOCKS = 2,
> > + /*
> > + * 5 clocks. Minimum SCL high time is 5 clocks of the I2C clock
> > + * pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_5CLOCKS = 3,
> > + /*
> > + * 6 clocks. Minimum SCL high time is 6 clocks of the I2C clock
> > + * pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_6CLOCKS = 4,
> > + /*
> > + * 7 clocks. Minimum SCL high time is 7 clocks of the I2C clock
> > + * pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_7CLOCKS = 5,
> > + /*
> > + * 8 clocks. Minimum SCL high time is 8 clocks of the I2C clock
> > + * pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_8CLOCKS = 6,
> > + /*
> > + * 9 clocks. Minimum SCL high time is 9 clocks of the I2C clock
> > + * pre-divider.
> > + */
> > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_9CLOCKS = 7,
> > +} FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_Enum;
> > +
> > +typedef enum {
> > + /* No effect */
> > + FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_NO_EFFECT = 0,
> > + /*
> > + * Continue. Informs the Slave function to continue to the next operation,
> > + * by clearing the STAT[SLVPENDING] flag. This must be done after writing
> > + * transmit data, reading received data, or any other housekeeping related
> > + * to the next bus operation. Automatic Operation has different
> > + * requirements. SLVCONTINUE should not be set unless SLVPENDING = 1.
> > + */
> > + FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_CONTINUE = 1,
> > +} FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_Enum;
> > +
> > +typedef enum {
> > + /* No effect */
> > + FLEXCOMM_I2C_SLVCTL_SLVNACK_NO_EFFECT = 0,
> > + /*
> > + * NACK. Causes the Slave function to NACK the master when the slave is
> > + * receiving data from the master (in Slave Receiver mode).
> > + */
> > + FLEXCOMM_I2C_SLVCTL_SLVNACK_NACK = 1,
> > +} FLEXCOMM_I2C_SLVCTL_SLVNACK_Enum;
> > +
> > +typedef enum {
> > + /* Disabled. No DMA requests are issued for Slave mode operation. */
> > + FLEXCOMM_I2C_SLVCTL_SLVDMA_DISABLED = 0,
> > + /*
> > + * Enabled. DMA requests are issued for I2C slave data transmission and
> > + * reception.
> > + */
> > + FLEXCOMM_I2C_SLVCTL_SLVDMA_ENABLED = 1,
> > +} FLEXCOMM_I2C_SLVCTL_SLVDMA_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * Normal, non-automatic operation. If AUTONACK = 0, then a SlvPending
> > + * interrupt is generated when a matching address is received. If AUTONACK
> > + * = 1, then received addresses are NACKed (ignored).
> > + */
> > + FLEXCOMM_I2C_SLVCTL_AUTOACK_NORMAL = 0,
> > + /*
> > + * A header with matching SLVADR0 and matching direction as set by
> > + * AUTOMATCHREAD will be ACKed immediately, allowing the master to move on
> > + * to the data bytes. If the address matches SLVADR0, but the direction
> > + * does not match AUTOMATCHREAD, then the behavior will depend on the
> > + * SLVADR0[AUTONACK] bit: if AUTONACK is set, then it will be Nacked; if
> > + * AUTONACK is clear, then a SlvPending interrupt is generated.
> > + */
> > + FLEXCOMM_I2C_SLVCTL_AUTOACK_AUTOMATIC_ACK = 1,
> > +} FLEXCOMM_I2C_SLVCTL_AUTOACK_Enum;
> > +
> > +typedef enum {
> > + /* In Automatic Mode, the expected next operation is an I2C write. */
> > + FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_I2C_WRITE = 0,
> > + /* In Automatic Mode, the expected next operation is an I2C read. */
> > + FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_I2C_READ = 1,
> > +} FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_Enum;
> > +
> > +typedef enum {
> > + /* Enabled. Slave Address n is enabled. */
> > + FLEXCOMM_I2C_SLVADR0_SADISABLE_ENABLED = 0,
> > + /* Ignored. Slave Address n is ignored. */
> > + FLEXCOMM_I2C_SLVADR0_SADISABLE_DISABLED = 1,
> > +} FLEXCOMM_I2C_SLVADR0_SADISABLE_Enum;
> > +
> > +typedef enum {
> > + /* Normal operation, matching I2C addresses are not ignored. */
> > + FLEXCOMM_I2C_SLVADR0_AUTONACK_NORMAL = 0,
> > + /*
> > + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> > + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> > + * matches the direction.
> > + */
> > + FLEXCOMM_I2C_SLVADR0_AUTONACK_AUTOMATIC = 1,
> > +} FLEXCOMM_I2C_SLVADR0_AUTONACK_Enum;
> > +
> > +typedef enum {
> > + /* Enabled. Slave Address n is enabled. */
> > + FLEXCOMM_I2C_SLVADR1_SADISABLE_ENABLED = 0,
> > + /* Ignored. Slave Address n is ignored. */
> > + FLEXCOMM_I2C_SLVADR1_SADISABLE_DISABLED = 1,
> > +} FLEXCOMM_I2C_SLVADR1_SADISABLE_Enum;
> > +
> > +typedef enum {
> > + /* Normal operation, matching I2C addresses are not ignored. */
> > + FLEXCOMM_I2C_SLVADR1_AUTONACK_NORMAL = 0,
> > + /*
> > + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> > + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> > + * matches the direction.
> > + */
> > + FLEXCOMM_I2C_SLVADR1_AUTONACK_AUTOMATIC = 1,
> > +} FLEXCOMM_I2C_SLVADR1_AUTONACK_Enum;
> > +
> > +typedef enum {
> > + /* Enabled. Slave Address n is enabled. */
> > + FLEXCOMM_I2C_SLVADR2_SADISABLE_ENABLED = 0,
> > + /* Ignored. Slave Address n is ignored. */
> > + FLEXCOMM_I2C_SLVADR2_SADISABLE_DISABLED = 1,
> > +} FLEXCOMM_I2C_SLVADR2_SADISABLE_Enum;
> > +
> > +typedef enum {
> > + /* Normal operation, matching I2C addresses are not ignored. */
> > + FLEXCOMM_I2C_SLVADR2_AUTONACK_NORMAL = 0,
> > + /*
> > + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> > + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> > + * matches the direction.
> > + */
> > + FLEXCOMM_I2C_SLVADR2_AUTONACK_AUTOMATIC = 1,
> > +} FLEXCOMM_I2C_SLVADR2_AUTONACK_Enum;
> > +
> > +typedef enum {
> > + /* Enabled. Slave Address n is enabled. */
> > + FLEXCOMM_I2C_SLVADR3_SADISABLE_ENABLED = 0,
> > + /* Ignored. Slave Address n is ignored. */
> > + FLEXCOMM_I2C_SLVADR3_SADISABLE_DISABLED = 1,
> > +} FLEXCOMM_I2C_SLVADR3_SADISABLE_Enum;
> > +
> > +typedef enum {
> > + /* Normal operation, matching I2C addresses are not ignored. */
> > + FLEXCOMM_I2C_SLVADR3_AUTONACK_NORMAL = 0,
> > + /*
> > + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> > + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> > + * matches the direction.
> > + */
> > + FLEXCOMM_I2C_SLVADR3_AUTONACK_AUTOMATIC = 1,
> > +} FLEXCOMM_I2C_SLVADR3_AUTONACK_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * Mask. The SLVQUAL0 field is used as a logical mask for matching address
> > + * 0.
> > + */
> > + FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_MASK = 0,
> > + /*
> > + * Extend. The SLVQUAL0 field is used to extend address 0 matching in a
> > + * range of addresses.
> > + */
> > + FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_EXTEND = 1,
> > +} FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * No start detected. The Monitor function has not detected a Start event
> > + * on the I2C bus.
> > + */
> > + FLEXCOMM_I2C_MONRXDAT_MONSTART_NO_START_DETECTED = 0,
> > + /*
> > + * Start detected. The Monitor function has detected a Start event on the
> > + * I2C bus.
> > + */
> > + FLEXCOMM_I2C_MONRXDAT_MONSTART_START_DETECTED = 1,
> > +} FLEXCOMM_I2C_MONRXDAT_MONSTART_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * No repeated start detected. The Monitor function has not detected a
> > + * Repeated Start event on the I2C bus.
> > + */
> > + FLEXCOMM_I2C_MONRXDAT_MONRESTART_NOT_DETECTED = 0,
> > + /*
> > + * Repeated start detected. The Monitor function has detected a Repeated
> > + * Start event on the I2C bus.
> > + */
> > + FLEXCOMM_I2C_MONRXDAT_MONRESTART_DETECTED = 1,
> > +} FLEXCOMM_I2C_MONRXDAT_MONRESTART_Enum;
> > +
> > +typedef enum {
> > + /*
> > + * Acknowledged. The data currently being provided by the Monitor function
> > + * was acknowledged by at least one master or slave receiver.
> > + */
> > + FLEXCOMM_I2C_MONRXDAT_MONNACK_ACKNOWLEDGED = 0,
> > + /*
> > + * Not acknowledged. The data currently being provided by the Monitor
> > + * function was not acknowledged by any receiver.
> > + */
> > + FLEXCOMM_I2C_MONRXDAT_MONNACK_NOT_ACKNOWLEDGED = 1,
> > +} FLEXCOMM_I2C_MONRXDAT_MONNACK_Enum;
> > +
> > +
> > +#define FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(_name) \
> > + struct RegisterAccessInfo _name[FLEXCOMM_I2C_REGS_NO] = { \
> > + [0 ... FLEXCOMM_I2C_REGS_NO - 1] = { \
> > + .name = "", \
> > + .addr = -1, \
> > + }, \
> > + [R_FLEXCOMM_I2C_CFG] = { \
> > + .name = "CFG", \
> > + .addr = 0x800, \
> > + .ro = 0xFFFFFFC0, \
> > + .reset = 0x0, \
> > + }, \
> > + [R_FLEXCOMM_I2C_STAT] = { \
> > + .name = "STAT", \
> > + .addr = 0x804, \
> > + .ro = 0xFCF57FAF, \
> > + .reset = 0x801, \
> > + }, \
> > + [R_FLEXCOMM_I2C_INTENSET] = { \
> > + .name = "INTENSET", \
> > + .addr = 0x808, \
> > + .ro = 0xFCF476AE, \
> > + .reset = 0x0, \
> > + }, \
> > + [R_FLEXCOMM_I2C_INTENCLR] = { \
> > + .name = "INTENCLR", \
> > + .addr = 0x80C, \
> > + .ro = 0xFCF476AE, \
> > + .reset = 0x0, \
> > + }, \
> > + [R_FLEXCOMM_I2C_TIMEOUT] = { \
> > + .name = "TIMEOUT", \
> > + .addr = 0x810, \
> > + .ro = 0xFFFF0000, \
> > + .reset = 0xFFFF, \
> > + }, \
> > + [R_FLEXCOMM_I2C_CLKDIV] = { \
> > + .name = "CLKDIV", \
> > + .addr = 0x814, \
> > + .ro = 0xFFFF0000, \
> > + .reset = 0x0, \
> > + }, \
> > + [R_FLEXCOMM_I2C_INTSTAT] = { \
> > + .name = "INTSTAT", \
> > + .addr = 0x818, \
> > + .ro = 0xFFFFFFFF, \
> > + .reset = 0x801, \
> > + }, \
> > + [R_FLEXCOMM_I2C_MSTCTL] = { \
> > + .name = "MSTCTL", \
> > + .addr = 0x820, \
> > + .ro = 0xFFFFFFF0, \
> > + .reset = 0x0, \
> > + }, \
> > + [R_FLEXCOMM_I2C_MSTTIME] = { \
> > + .name = "MSTTIME", \
> > + .addr = 0x824, \
> > + .ro = 0xFFFFFF88, \
> > + .reset = 0x77, \
> > + }, \
> > + [R_FLEXCOMM_I2C_MSTDAT] = { \
> > + .name = "MSTDAT", \
> > + .addr = 0x828, \
> > + .ro = 0xFFFFFF00, \
> > + .reset = 0x0, \
> > + }, \
> > + [R_FLEXCOMM_I2C_SLVCTL] = { \
> > + .name = "SLVCTL", \
> > + .addr = 0x840, \
> > + .ro = 0xFFFFFCF4, \
> > + .reset = 0x0, \
> > + }, \
> > + [R_FLEXCOMM_I2C_SLVDAT] = { \
> > + .name = "SLVDAT", \
> > + .addr = 0x844, \
> > + .ro = 0xFFFFFF00, \
> > + .reset = 0x0, \
> > + }, \
> > + [R_FLEXCOMM_I2C_SLVADR0] = { \
> > + .name = "SLVADR0", \
> > + .addr = 0x848, \
> > + .ro = 0xFFFF7F00, \
> > + .reset = 0x1, \
> > + }, \
> > + [R_FLEXCOMM_I2C_SLVADR1] = { \
> > + .name = "SLVADR1", \
> > + .addr = 0x84C, \
> > + .ro = 0xFFFF7F00, \
> > + .reset = 0x1, \
> > + }, \
> > + [R_FLEXCOMM_I2C_SLVADR2] = { \
> > + .name = "SLVADR2", \
> > + .addr = 0x850, \
> > + .ro = 0xFFFF7F00, \
> > + .reset = 0x1, \
> > + }, \
> > + [R_FLEXCOMM_I2C_SLVADR3] = { \
> > + .name = "SLVADR3", \
> > + .addr = 0x854, \
> > + .ro = 0xFFFF7F00, \
> > + .reset = 0x1, \
> > + }, \
> > + [R_FLEXCOMM_I2C_SLVQUAL0] = { \
> > + .name = "SLVQUAL0", \
> > + .addr = 0x858, \
> > + .ro = 0xFFFFFF00, \
> > + .reset = 0x0, \
> > + }, \
> > + [R_FLEXCOMM_I2C_MONRXDAT] = { \
> > + .name = "MONRXDAT", \
> > + .addr = 0x880, \
> > + .ro = 0xFFFFFFFF, \
> > + .reset = 0x0, \
> > + }, \
> > + [R_FLEXCOMM_I2C_ID] = { \
> > + .name = "ID", \
> > + .addr = 0xFFC, \
> > + .ro = 0xFFFFFFFF, \
> > + .reset = 0xE0301300, \
> > + }, \
> > + }
> > diff --git a/include/hw/i2c/flexcomm_i2c.h b/include/hw/i2c/flexcomm_i2c.h
> > new file mode 100644
> > index 0000000000..7b27e333d7
> > --- /dev/null
> > +++ b/include/hw/i2c/flexcomm_i2c.h
> > @@ -0,0 +1,40 @@
> > +/*
> > + * QEMU model for NXP's FLEXCOMM I2C
> > + *
> > + * Copyright (c) 2024 Google LLC
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + */
> > +
> > +#ifndef HW_FLEXCOMM_I2C_H
> > +#define HW_FLEXCOMM_I2C_H
> > +
> > +#include "hw/i2c/i2c.h"
> > +#include "hw/misc/flexcomm_function.h"
> > +
> > +#define TYPE_FLEXCOMM_I2C "flexcomm-i2c"
> > +OBJECT_DECLARE_TYPE(FlexcommI2cState, FlexcommI2cClass, FLEXCOMM_I2C);
> > +
> > +struct FlexcommI2cState {
> > + FlexcommFunction parent_obj;
> > +
> > + I2CBus *bus;
> > +};
> > +
> > +struct FlexcommI2cClass {
> > + FlexcommFunctionClass parent_obj;
> > +
> > + FlexcommFunctionSelect select;
> > +};
> > +
> > +#define MSTSTATE_IDLE 0
> > +#define MSTSTATE_RXRDY 1
> > +#define MSTSTATE_TXRDY 2
> > +#define MSTSTATE_NAKADR 3
> > +#define MSTSTATE_NAKDAT 4
> > +
> > +
> > +#endif /* HW_FLEXCOMM_I2C_H */
> > diff --git a/include/hw/misc/flexcomm.h b/include/hw/misc/flexcomm.h
> > index 679b7ea64d..c9f1cd3890 100644
> > --- a/include/hw/misc/flexcomm.h
> > +++ b/include/hw/misc/flexcomm.h
> > @@ -16,6 +16,7 @@
> > #include "hw/arm/svd/flexcomm.h"
> > #include "qemu/fifo32.h"
> > #include "hw/char/flexcomm_usart.h"
> > +#include "hw/i2c/flexcomm_i2c.h"
> >
> > #define FLEXCOMM_FUNC_USART 0
> > #define FLEXCOMM_FUNC_SPI 1
> > @@ -48,6 +49,7 @@ struct FlexcommState {
> > Fifo32 rx_fifo;
> > Fifo32 tx_fifo;
> > FlexcommUsartState usart;
> > + FlexcommI2cState i2c;
> > };
> >
> > #endif /* HW_FLEXCOMM_H */
> > diff --git a/hw/i2c/flexcomm_i2c.c b/hw/i2c/flexcomm_i2c.c
> > new file mode 100644
> > index 0000000000..e5341ec241
> > --- /dev/null
> > +++ b/hw/i2c/flexcomm_i2c.c
> > @@ -0,0 +1,250 @@
> > +/*
> > + * QEMU model for NXP's FLEXCOMM I2C
> > + *
> > + * Copyright (c) 2024 Google LLC
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu/cutils.h"
> > +#include "hw/irq.h"
> > +#include "hw/qdev-properties.h"
> > +#include "qemu/log.h"
> > +#include "qemu/module.h"
> > +#include "exec/address-spaces.h"
> > +#include "qapi/error.h"
> > +#include "trace.h"
> > +#include "hw/i2c/flexcomm_i2c.h"
> > +#include "hw/arm/svd/flexcomm_i2c.h"
> > +
> > +#define REG(s, reg) (s->regs[R_FLEXCOMM_I2C_##reg])
> > +#define RF_WR(s, reg, field, val) \
> > + ARRAY_FIELD_DP32(s->regs, FLEXCOMM_I2C_##reg, field, val)
> > +#define RF_RD(s, reg, field) \
> > + ARRAY_FIELD_EX32(s->regs, FLEXCOMM_I2C_##reg, field)
> > +
> > +static FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(reg_info);
> > +
> > +static void flexcomm_i2c_reset(FlexcommFunction *f)
> > +{
> > + for (int i = 0; i < FLEXCOMM_I2C_REGS_NO; i++) {
> > + hwaddr addr = reg_info[i].addr;
> > +
> > + if (addr != -1) {
> > + struct RegisterInfo ri = {
> > + .data = &f->regs[addr / 4],
> > + .data_size = 4,
> > + .access = ®_info[i],
> > + };
> > +
> > + register_reset(&ri);
> > + }
> > + }
> > +}
> > +
> > +static void flexcomm_i2c_irq_update(FlexcommFunction *f)
> > +{
> > + bool enabled = RF_RD(f, CFG, MSTEN);
> > + bool irq, per_irqs;
> > +
> > + REG(f, INTSTAT) = REG(f, STAT) & REG(f, INTENSET);
> > + per_irqs = REG(f, INTSTAT) != 0;
> > +
> > + irq = enabled && per_irqs;
> > +
> > + trace_flexcomm_i2c_irq(DEVICE(f)->id, irq, per_irqs, enabled);
> > + flexcomm_set_irq(f, irq);
> > +}
> > +
> > +static MemTxResult flexcomm_i2c_reg_read(void *opaque, hwaddr addr,
> > + uint64_t *data, unsigned size,
> > + MemTxAttrs attrs)
> > +{
> > + FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
> > + MemTxResult ret = MEMTX_OK;
> > + const struct RegisterAccessInfo *rai = ®_info[addr / 4];
> > +
> > + if (size != 4) {
> > + ret = MEMTX_ERROR;
> > + goto out;
> > + }
> > +
> > + *data = f->regs[addr / 4];
> > +
> > + flexcomm_i2c_irq_update(f);
> > +
> > +out:
> > + trace_flexcomm_i2c_reg_read(DEVICE(f)->id, rai->name, addr, *data);
> > + return ret;
> > +}
> > +
> > +static MemTxResult flexcomm_i2c_reg_write(void *opaque, hwaddr addr,
> > + uint64_t value, unsigned size,
> > + MemTxAttrs attrs)
> > +{
> > + FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
> > + FlexcommI2cState *s = FLEXCOMM_I2C(opaque);
> > + const struct RegisterAccessInfo *rai = ®_info[addr / 4];
> > + struct RegisterInfo ri = {
> > + .data = &f->regs[addr / 4],
> > + .data_size = 4,
> > + .access = rai,
> > + };
> > +
> > + trace_flexcomm_i2c_reg_write(DEVICE(f)->id, rai->name, addr, value);
> > +
> > + if (size != 4) {
> > + return MEMTX_ERROR;
> > + }
> > +
> > + switch (addr) {
> > + case A_FLEXCOMM_I2C_CFG:
> > + {
> > + register_write(&ri, value, ~0, NULL, false);
> > + if (RF_RD(f, CFG, SLVEN)) {
> > + qemu_log_mask(LOG_GUEST_ERROR, "I2C slave not supported");
> > + }
> > + if (RF_RD(f, CFG, MONEN)) {
> > + qemu_log_mask(LOG_GUEST_ERROR, "I2C monitoring not supported");
> > + }
> > + break;
> > + }
> > + case A_FLEXCOMM_I2C_INTENCLR:
> > + {
> > + REG(f, INTENSET) &= ~value;
> > + break;
> > + }
> > + case A_FLEXCOMM_I2C_TIMEOUT:
> > + {
> > + register_write(&ri, value, ~0, NULL, false);
> > + /* The bottom 4 bits are hard-wired to 0xF */
> > + RF_WR(f, TIMEOUT, TOMIN, 0xf);
> > + break;
> > + }
> > + case A_FLEXCOMM_I2C_MSTCTL:
> > + {
> > + register_write(&ri, value, ~0, NULL, false);
> > + if (RF_RD(f, MSTCTL, MSTSTART)) {
> > + uint8_t i2c_addr = RF_RD(f, MSTDAT, DATA);
> > + bool recv = i2c_addr & 1;
> > +
> > + trace_flexcomm_i2c_start(DEVICE(s)->id, i2c_addr, recv);
> > + if (i2c_start_transfer(s->bus, i2c_addr, recv)) {
> > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_NAKADR);
> > + trace_flexcomm_i2c_nak(DEVICE(s)->id);
> > + } else {
> > + if (recv) {
> > + uint8_t data = i2c_recv(s->bus);
> > +
> > + RF_WR(f, MSTDAT, DATA, data);
> > + trace_flexcomm_i2c_rx(DEVICE(s)->id, data);
> > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_RXRDY);
> > + } else {
> > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_TXRDY);
> > + }
> > + }
> > + }
> > + if (RF_RD(f, MSTCTL, MSTSTOP)) {
> > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_IDLE);
> > + i2c_end_transfer(s->bus);
> > + }
> > + if (RF_RD(f, MSTCTL, MSTCONTINUE)) {
> > + if (RF_RD(f, STAT, MSTSTATE) == MSTSTATE_TXRDY) {
> > + uint8_t data = RF_RD(f, MSTDAT, DATA);
> > +
> > + trace_flexcomm_i2c_tx(DEVICE(s)->id, data);
> > + if (i2c_send(s->bus, data)) {
> > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_NAKDAT);
> > + }
> > + } else if (RF_RD(f, STAT, MSTSTATE) == MSTSTATE_RXRDY) {
> > + uint8_t data = i2c_recv(s->bus);
> > +
> > + RF_WR(f, MSTDAT, DATA, data);
> > + trace_flexcomm_i2c_rx(DEVICE(s)->id, data);
> > + }
> > + }
> > + break;
> > + }
> > + case A_FLEXCOMM_I2C_STAT:
> > + {
> > + /* write 1 to clear bits */
> > + REG(f, STAT) &= ~value;
> > + break;
> > + }
> > + case A_FLEXCOMM_I2C_SLVCTL:
> > + case A_FLEXCOMM_I2C_SLVDAT:
> > + case A_FLEXCOMM_I2C_SLVADR0:
> > + case A_FLEXCOMM_I2C_SLVADR1:
> > + case A_FLEXCOMM_I2C_SLVADR2:
> > + case A_FLEXCOMM_I2C_SLVADR3:
> > + case A_FLEXCOMM_I2C_SLVQUAL0:
> > + {
> > + qemu_log_mask(LOG_GUEST_ERROR, "I2C slave not supported\n");
> > + break;
> > + }
> > + default:
> > + register_write(&ri, value, ~0, NULL, false);
> > + break;
> > + }
> > +
> > + flexcomm_i2c_irq_update(f);
> > +
> > + return MEMTX_OK;
> > +}
> > +
> > +static void flexcomm_i2c_select(FlexcommFunction *f, bool selected)
> > +{
> > + FlexcommI2cClass *ic = FLEXCOMM_I2C_GET_CLASS(f);
> > +
> > + if (selected) {
> > + flexcomm_i2c_reset(f);
> > + }
> > + ic->select(f, selected);
> > +}
> > +
> > +static const MemoryRegionOps flexcomm_i2c_ops = {
> > + .read_with_attrs = flexcomm_i2c_reg_read,
> > + .write_with_attrs = flexcomm_i2c_reg_write,
> > + .endianness = DEVICE_NATIVE_ENDIAN,
> > + .valid = {
> > + .min_access_size = 4,
> > + .max_access_size = 4,
> > + .unaligned = false,
> > + },
> > +};
> > +
> > +static void flexcomm_i2c_realize(DeviceState *dev, Error **errp)
> > +{
> > + FlexcommI2cState *s = FLEXCOMM_I2C(dev);
> > +
> > + s->bus = i2c_init_bus(DEVICE(s), "bus");
> > +}
> > +
> > +static void flexcomm_i2c_class_init(ObjectClass *klass, void *data)
> > +{
> > + DeviceClass *dc = DEVICE_CLASS(klass);
> > + FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_CLASS(klass);
> > + FlexcommI2cClass *ic = FLEXCOMM_I2C_CLASS(klass);
> > +
> > + dc->realize = flexcomm_i2c_realize;
> > + ic->select = fc->select;
> > + fc->select = flexcomm_i2c_select;
> > + fc->name = "i2c";
> > + fc->mmio_ops = &flexcomm_i2c_ops;
> > +}
> > +
> > +static const TypeInfo flexcomm_i2c_types[] = {
> > + {
> > + .name = TYPE_FLEXCOMM_I2C,
> > + .parent = TYPE_FLEXCOMM_FUNCTION,
> > + .instance_size = sizeof(FlexcommI2cState),
> > + .class_init = flexcomm_i2c_class_init,
> > + .class_size = sizeof(FlexcommI2cClass),
> > + },
> > +};
> > +
> > +DEFINE_TYPES(flexcomm_i2c_types);
> > diff --git a/hw/misc/flexcomm.c b/hw/misc/flexcomm.c
> > index a291148f27..b1a2f01acf 100644
> > --- a/hw/misc/flexcomm.c
> > +++ b/hw/misc/flexcomm.c
> > @@ -24,6 +24,7 @@
> > #include "hw/misc/flexcomm.h"
> > #include "hw/arm/svd/flexcomm_usart.h"
> > #include "hw/char/flexcomm_usart.h"
> > +#include "hw/i2c/flexcomm_i2c.h"
> >
> > #define REG(s, reg) (s->regs[R_FLEXCOMM_##reg])
> > #define RF_WR(s, reg, field, val) \
> > @@ -220,6 +221,7 @@ static void flexcomm_init(Object *obj)
> > sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container);
> > sysbus_init_irq(sbd, &s->irq);
> > object_initialize_child(obj, "usart", &s->usart, TYPE_FLEXCOMM_USART);
> > + object_initialize_child(obj, "i2c", &s->i2c, TYPE_FLEXCOMM_I2C);
> > }
> >
> > static void flexcomm_finalize(Object *obj)
> > @@ -250,6 +252,7 @@ static void flexcomm_realize(DeviceState *dev, Error **errp)
> >
> > memory_region_add_subregion_overlap(&s->container, 0, &s->mmio, -1);
> > flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->usart), errp);
> > + flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->i2c), errp);
> > }
> >
> > static const VMStateDescription vmstate_flexcomm = {
> > diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build
> > index 2bde34d15b..417491cd5c 100644
> > --- a/hw/arm/svd/meson.build
> > +++ b/hw/arm/svd/meson.build
> > @@ -7,4 +7,7 @@ if get_option('mcux-soc-svd')
> > run_target('svd-flexcomm-usart', command: svd_gen_header +
> > [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_usart.h',
> > '-p', 'USART0', '-t', 'FLEXCOMM_USART'])
> > + run_target('svd-flexcomm-i2c', command: svd_gen_header +
> > + [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_i2c.h',
> > + '-p', 'I2C0', '-t', 'FLEXCOMM_I2C'])
> > endif
> > diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build
> > index c459adcb59..e7d79e6938 100644
> > --- a/hw/i2c/meson.build
> > +++ b/hw/i2c/meson.build
> > @@ -18,4 +18,5 @@ i2c_ss.add(when: 'CONFIG_PPC4XX', if_true: files('ppc4xx_i2c.c'))
> > i2c_ss.add(when: 'CONFIG_PCA954X', if_true: files('i2c_mux_pca954x.c'))
> > i2c_ss.add(when: 'CONFIG_PMBUS', if_true: files('pmbus_device.c'))
> > i2c_ss.add(when: 'CONFIG_BCM2835_I2C', if_true: files('bcm2835_i2c.c'))
> > +i2c_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm_i2c.c'))
> > system_ss.add_all(when: 'CONFIG_I2C', if_true: i2c_ss)
> > diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
> > index 6900e06eda..9f0175fab7 100644
> > --- a/hw/i2c/trace-events
> > +++ b/hw/i2c/trace-events
> > @@ -51,3 +51,13 @@ npcm7xx_smbus_recv_fifo(const char *id, uint8_t received, uint8_t expected) "%s
> >
> > pca954x_write_bytes(uint8_t value) "PCA954X write data: 0x%02x"
> > pca954x_read_data(uint8_t value) "PCA954X read data: 0x%02x"
> > +
> > +# flexcomm_i2c.c
> > +
> > +flexcomm_i2c_reg_read(const char *id, const char *reg_name, uint32_t addr, uint32_t val) " %s: %s[0x%04x] -> 0x%08x"
> > +flexcomm_i2c_reg_write(const char *id, const char *reg_name, uint32_t addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x"
> > +flexcomm_i2c_start(const char *id, uint8_t addr, uint8_t recv) "%s: 0x%02x %d"
> > +flexcomm_i2c_rx(const char *id, uint8_t data) "%s: <- 0x%02x"
> > +flexcomm_i2c_tx(const char *id, uint8_t data) "%s: -> 0x%02x"
> > +flexcomm_i2c_nak(const char *id) "%s: <- nak"
> > +flexcomm_i2c_irq(const char *id, bool irq, bool perirqs, bool enabled) "%s: %d %d %d"
> > diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
> > index 14167ae9e8..9a244fa01d 100644
> > --- a/hw/misc/Kconfig
> > +++ b/hw/misc/Kconfig
> > @@ -215,5 +215,6 @@ config XLNX_VERSAL_TRNG
> >
> > config FLEXCOMM
> > bool
> > + select I2C
> >
> > source macio/Kconfig
> > --
> > 2.46.0.662.g92d0881bb0-goog
> >
> >
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 08/25] hw/i2c: add support for flexcomm i2c
2024-09-18 21:04 ` Octavian Purdila
@ 2024-09-18 21:31 ` Corey Minyard
2024-09-18 22:25 ` Octavian Purdila
2024-09-19 9:36 ` Peter Maydell
0 siblings, 2 replies; 36+ messages in thread
From: Corey Minyard @ 2024-09-18 21:31 UTC (permalink / raw)
To: Octavian Purdila
Cc: qemu-devel, qemu-arm, stefanst, pbonzini, peter.maydell,
marcandre.lureau, berrange, eduardo, luc, damien.hedde, alistair,
thuth, philmd, jsnow, crosa, lvivier
On Wed, Sep 18, 2024 at 02:04:58PM -0700, Octavian Purdila wrote:
> On Wed, Sep 18, 2024 at 1:17???PM Corey Minyard <corey@minyard.net> wrote:
> >
> > On Wed, Sep 18, 2024 at 12:22:36PM -0700, Octavian Purdila wrote:
> > > Add support for NXP's flexcomm i2c. It does not support slave mode or
> > > DMA.
> > >
> > > The patch includes an automatically generated header which contains
> > > the register layout and helpers.
> > >
> > > The header can be regenerated with the svd-flexcomm-i2c target when
> > > the build is configured with --enable-mcux-soc-svd.
> > >
> > > Signed-off-by: Octavian Purdila <tavip@google.com>
> > > ---
> > > include/hw/arm/svd/flexcomm_i2c.h | 1190 +++++++++++++++++++++++++++++
> > > include/hw/i2c/flexcomm_i2c.h | 40 +
> > > include/hw/misc/flexcomm.h | 2 +
> > > hw/i2c/flexcomm_i2c.c | 250 ++++++
> > > hw/misc/flexcomm.c | 3 +
> > > hw/arm/svd/meson.build | 3 +
> > > hw/i2c/meson.build | 1 +
> > > hw/i2c/trace-events | 10 +
> > > hw/misc/Kconfig | 1 +
> > > 9 files changed, 1500 insertions(+)
> > > create mode 100644 include/hw/arm/svd/flexcomm_i2c.h
> > > create mode 100644 include/hw/i2c/flexcomm_i2c.h
> > > create mode 100644 hw/i2c/flexcomm_i2c.c
> > >
> > > diff --git a/include/hw/arm/svd/flexcomm_i2c.h b/include/hw/arm/svd/flexcomm_i2c.h
> > > new file mode 100644
> > > index 0000000000..9017d48446
> > > --- /dev/null
> > > +++ b/include/hw/arm/svd/flexcomm_i2c.h
> > > @@ -0,0 +1,1190 @@
> > > +/*
> > > + * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
> > > + *
> > > + * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
> > > + */
> > > +#pragma once
> > > +
> > > +#include "hw/register.h"
> > > +
> > > +/* I2C Bus Interface */
> > > +#define FLEXCOMM_I2C_REGS_NO (1024)
> > > +
> > > +/* Configuration Register */
> > > +REG32(FLEXCOMM_I2C_CFG, 2048);
> > > +/* Master Enable */
> > > +FIELD(FLEXCOMM_I2C_CFG, MSTEN, 0, 1);
> > > +/* Slave Enable */
> > > +FIELD(FLEXCOMM_I2C_CFG, SLVEN, 1, 1);
> > > +/* Monitor Enable */
> > > +FIELD(FLEXCOMM_I2C_CFG, MONEN, 2, 1);
> > > +/* I2C bus Time-out Enable */
> > > +FIELD(FLEXCOMM_I2C_CFG, TIMEOUTEN, 3, 1);
> > > +/* Monitor function Clock Stretching */
> > > +FIELD(FLEXCOMM_I2C_CFG, MONCLKSTR, 4, 1);
> > > +/* High Speed mode Capable enable */
> > > +FIELD(FLEXCOMM_I2C_CFG, HSCAPABLE, 5, 1);
> > > +
> > > +/* Status Register */
> > > +REG32(FLEXCOMM_I2C_STAT, 2052);
> > > +/* Master Pending */
> > > +FIELD(FLEXCOMM_I2C_STAT, MSTPENDING, 0, 1);
> > > +/* Master State code */
> > > +FIELD(FLEXCOMM_I2C_STAT, MSTSTATE, 1, 3);
> > > +/* Master Arbitration Loss flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, MSTARBLOSS, 4, 1);
> > > +/* Master Start/Stop Error flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, MSTSTSTPERR, 6, 1);
> > > +/* Slave Pending */
> > > +FIELD(FLEXCOMM_I2C_STAT, SLVPENDING, 8, 1);
> > > +/* Slave State */
> > > +FIELD(FLEXCOMM_I2C_STAT, SLVSTATE, 9, 2);
> > > +/* Slave Not Stretching */
> > > +FIELD(FLEXCOMM_I2C_STAT, SLVNOTSTR, 11, 1);
> > > +/* Slave address match Index T */
> > > +FIELD(FLEXCOMM_I2C_STAT, SLVIDX, 12, 2);
> > > +/* Slave selected flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, SLVSEL, 14, 1);
> > > +/* Slave Deselected flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, SLVDESEL, 15, 1);
> > > +/* Monitor Ready */
> > > +FIELD(FLEXCOMM_I2C_STAT, MONRDY, 16, 1);
> > > +/* Monitor Overflow flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, MONOV, 17, 1);
> > > +/* Monitor Active flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, MONACTIVE, 18, 1);
> > > +/* Monitor Idle flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, MONIDLE, 19, 1);
> > > +/* Event Time-out Interrupt flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, EVENTTIMEOUT, 24, 1);
> > > +/* SCL Time-out Interrupt flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, SCLTIMEOUT, 25, 1);
> > > +
> > > +/* Interrupt Enable Set Register */
> > > +REG32(FLEXCOMM_I2C_INTENSET, 2056);
> > > +/* Master Pending interrupt Enable */
> > > +FIELD(FLEXCOMM_I2C_INTENSET, MSTPENDINGEN, 0, 1);
> > > +/* Master Arbitration Loss interrupt Enable */
> > > +FIELD(FLEXCOMM_I2C_INTENSET, MSTARBLOSSEN, 4, 1);
> > > +/* Master Start/Stop Error interrupt Enable */
> > > +FIELD(FLEXCOMM_I2C_INTENSET, MSTSTSTPERREN, 6, 1);
> > > +/* Slave Pending interrupt Enable */
> > > +FIELD(FLEXCOMM_I2C_INTENSET, SLVPENDINGEN, 8, 1);
> > > +/* Slave Not Stretching interrupt Enable */
> > > +FIELD(FLEXCOMM_I2C_INTENSET, SLVNOTSTREN, 11, 1);
> > > +/* Slave Deselect interrupt Enable */
> > > +FIELD(FLEXCOMM_I2C_INTENSET, SLVDESELEN, 15, 1);
> > > +/* Monitor data Ready interrupt Enable */
> > > +FIELD(FLEXCOMM_I2C_INTENSET, MONRDYEN, 16, 1);
> > > +/* Monitor Overrun interrupt Enable */
> > > +FIELD(FLEXCOMM_I2C_INTENSET, MONOVEN, 17, 1);
> > > +/* Monitor Idle interrupt Enable */
> > > +FIELD(FLEXCOMM_I2C_INTENSET, MONIDLEEN, 19, 1);
> > > +/* Event Time-out interrupt Enable */
> > > +FIELD(FLEXCOMM_I2C_INTENSET, EVENTTIMEOUTEN, 24, 1);
> > > +/* SCL Time-out interrupt Enable */
> > > +FIELD(FLEXCOMM_I2C_INTENSET, SCLTIMEOUTEN, 25, 1);
> > > +
> > > +/* Interrupt Enable Clear Register */
> > > +REG32(FLEXCOMM_I2C_INTENCLR, 2060);
> > > +/* Master Pending interrupt clear */
> > > +FIELD(FLEXCOMM_I2C_INTENCLR, MSTPENDINGCLR, 0, 1);
> > > +/* Master Arbitration Loss interrupt clear */
> > > +FIELD(FLEXCOMM_I2C_INTENCLR, MSTARBLOSSCLR, 4, 1);
> > > +/* Master Start/Stop Error interrupt clear */
> > > +FIELD(FLEXCOMM_I2C_INTENCLR, MSTSTSTPERRCLR, 6, 1);
> > > +/* Slave Pending interrupt clear */
> > > +FIELD(FLEXCOMM_I2C_INTENCLR, SLVPENDINGCLR, 8, 1);
> > > +/* Slave Not Stretching interrupt clear */
> > > +FIELD(FLEXCOMM_I2C_INTENCLR, SLVNOTSTRCLR, 11, 1);
> > > +/* Slave Deselect interrupt clear */
> > > +FIELD(FLEXCOMM_I2C_INTENCLR, SLVDESELCLR, 15, 1);
> > > +/* Monitor data Ready interrupt clear */
> > > +FIELD(FLEXCOMM_I2C_INTENCLR, MONRDYCLR, 16, 1);
> > > +/* Monitor Overrun interrupt clear */
> > > +FIELD(FLEXCOMM_I2C_INTENCLR, MONOVCLR, 17, 1);
> > > +/* Monitor Idle interrupt clear */
> > > +FIELD(FLEXCOMM_I2C_INTENCLR, MONIDLECLR, 19, 1);
> > > +/* Event time-out interrupt clear */
> > > +FIELD(FLEXCOMM_I2C_INTENCLR, EVENTTIMEOUTCLR, 24, 1);
> > > +/* SCL time-out interrupt clear */
> > > +FIELD(FLEXCOMM_I2C_INTENCLR, SCLTIMEOUTCLR, 25, 1);
> > > +
> > > +/* Time-out Register */
> > > +REG32(FLEXCOMM_I2C_TIMEOUT, 2064);
> > > +/* Time-out time value, the bottom 4 bits */
> > > +FIELD(FLEXCOMM_I2C_TIMEOUT, TOMIN, 0, 4);
> > > +/* Time-out time value */
> > > +FIELD(FLEXCOMM_I2C_TIMEOUT, TO, 4, 12);
> > > +
> > > +/* Clock Divider Register */
> > > +REG32(FLEXCOMM_I2C_CLKDIV, 2068);
> > > +/* Divider Value */
> > > +FIELD(FLEXCOMM_I2C_CLKDIV, DIVVAL, 0, 16);
> > > +
> > > +/* Interrupt Status Register */
> > > +REG32(FLEXCOMM_I2C_INTSTAT, 2072);
> > > +/* Master Pending */
> > > +FIELD(FLEXCOMM_I2C_INTSTAT, MSTPENDING, 0, 1);
> > > +/* Master Arbitration Loss flag */
> > > +FIELD(FLEXCOMM_I2C_INTSTAT, MSTARBLOSS, 4, 1);
> > > +/* Master Start/Stop Error flag */
> > > +FIELD(FLEXCOMM_I2C_INTSTAT, MSTSTSTPERR, 6, 1);
> > > +/* Slave Pending */
> > > +FIELD(FLEXCOMM_I2C_INTSTAT, SLVPENDING, 8, 1);
> > > +/* Slave Not Stretching status */
> > > +FIELD(FLEXCOMM_I2C_INTSTAT, SLVNOTSTR, 11, 1);
> > > +/* Slave Deselected flag */
> > > +FIELD(FLEXCOMM_I2C_INTSTAT, SLVDESEL, 15, 1);
> > > +/* Monitor Ready */
> > > +FIELD(FLEXCOMM_I2C_INTSTAT, MONRDY, 16, 1);
> > > +/* Monitor Overflow flag */
> > > +FIELD(FLEXCOMM_I2C_INTSTAT, MONOV, 17, 1);
> > > +/* Monitor Idle flag */
> > > +FIELD(FLEXCOMM_I2C_INTSTAT, MONIDLE, 19, 1);
> > > +/* Event Time-out Interrupt flag */
> > > +FIELD(FLEXCOMM_I2C_INTSTAT, EVENTTIMEOUT, 24, 1);
> > > +/* SCL Time-out Interrupt flag */
> > > +FIELD(FLEXCOMM_I2C_INTSTAT, SCLTIMEOUT, 25, 1);
> > > +
> > > +/* Master Control Register */
> > > +REG32(FLEXCOMM_I2C_MSTCTL, 2080);
> > > +/* Master Continue(write-only) */
> > > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTCONTINUE, 0, 1);
> > > +/* Master Start control(write-only) */
> > > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTART, 1, 1);
> > > +/* Master Stop control(write-only) */
> > > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTOP, 2, 1);
> > > +/* Master DMA enable */
> > > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTDMA, 3, 1);
> > > +
> > > +/* Master Timing Register */
> > > +REG32(FLEXCOMM_I2C_MSTTIME, 2084);
> > > +/* Master SCL Low time */
> > > +FIELD(FLEXCOMM_I2C_MSTTIME, MSTSCLLOW, 0, 3);
> > > +/* Master SCL High time */
> > > +FIELD(FLEXCOMM_I2C_MSTTIME, MSTSCLHIGH, 4, 3);
> > > +
> > > +/* Master Data Register */
> > > +REG32(FLEXCOMM_I2C_MSTDAT, 2088);
> > > +/* Master function data register */
> > > +FIELD(FLEXCOMM_I2C_MSTDAT, DATA, 0, 8);
> > > +
> > > +/* Slave Control Register */
> > > +REG32(FLEXCOMM_I2C_SLVCTL, 2112);
> > > +/* Slave Continue */
> > > +FIELD(FLEXCOMM_I2C_SLVCTL, SLVCONTINUE, 0, 1);
> > > +/* Slave NACK */
> > > +FIELD(FLEXCOMM_I2C_SLVCTL, SLVNACK, 1, 1);
> > > +/* Slave DMA enable */
> > > +FIELD(FLEXCOMM_I2C_SLVCTL, SLVDMA, 3, 1);
> > > +/* Automatic Acknowledge */
> > > +FIELD(FLEXCOMM_I2C_SLVCTL, AUTOACK, 8, 1);
> > > +/* Automatic Match Read */
> > > +FIELD(FLEXCOMM_I2C_SLVCTL, AUTOMATCHREAD, 9, 1);
> > > +
> > > +/* Slave Data Register */
> > > +REG32(FLEXCOMM_I2C_SLVDAT, 2116);
> > > +/* Slave function data register */
> > > +FIELD(FLEXCOMM_I2C_SLVDAT, DATA, 0, 8);
> > > +
> > > +/* Slave Address Register */
> > > +REG32(FLEXCOMM_I2C_SLVADR0, 2120);
> > > +/* Slave Address n Disable */
> > > +FIELD(FLEXCOMM_I2C_SLVADR0, SADISABLE, 0, 1);
> > > +/* Slave Address. */
> > > +FIELD(FLEXCOMM_I2C_SLVADR0, SLVADR, 1, 7);
> > > +/* Automatic NACK operation */
> > > +FIELD(FLEXCOMM_I2C_SLVADR0, AUTONACK, 15, 1);
> > > +
> > > +/* Slave Address Register */
> > > +REG32(FLEXCOMM_I2C_SLVADR1, 2124);
> > > +/* Slave Address n Disable */
> > > +FIELD(FLEXCOMM_I2C_SLVADR1, SADISABLE, 0, 1);
> > > +/* Slave Address. */
> > > +FIELD(FLEXCOMM_I2C_SLVADR1, SLVADR, 1, 7);
> > > +/* Automatic NACK operation */
> > > +FIELD(FLEXCOMM_I2C_SLVADR1, AUTONACK, 15, 1);
> > > +
> > > +/* Slave Address Register */
> > > +REG32(FLEXCOMM_I2C_SLVADR2, 2128);
> > > +/* Slave Address n Disable */
> > > +FIELD(FLEXCOMM_I2C_SLVADR2, SADISABLE, 0, 1);
> > > +/* Slave Address. */
> > > +FIELD(FLEXCOMM_I2C_SLVADR2, SLVADR, 1, 7);
> > > +/* Automatic NACK operation */
> > > +FIELD(FLEXCOMM_I2C_SLVADR2, AUTONACK, 15, 1);
> > > +
> > > +/* Slave Address Register */
> > > +REG32(FLEXCOMM_I2C_SLVADR3, 2132);
> > > +/* Slave Address n Disable */
> > > +FIELD(FLEXCOMM_I2C_SLVADR3, SADISABLE, 0, 1);
> > > +/* Slave Address. */
> > > +FIELD(FLEXCOMM_I2C_SLVADR3, SLVADR, 1, 7);
> > > +/* Automatic NACK operation */
> > > +FIELD(FLEXCOMM_I2C_SLVADR3, AUTONACK, 15, 1);
> > > +
> > > +/* Slave Qualification for Address 0 Register */
> > > +REG32(FLEXCOMM_I2C_SLVQUAL0, 2136);
> > > +/* Qualify mode for slave address 0 */
> > > +FIELD(FLEXCOMM_I2C_SLVQUAL0, QUALMODE0, 0, 1);
> > > +/* Slave address Qualifier for address 0 */
> > > +FIELD(FLEXCOMM_I2C_SLVQUAL0, SLVQUAL0, 1, 7);
> > > +
> > > +/* Monitor Receiver Data Register */
> > > +REG32(FLEXCOMM_I2C_MONRXDAT, 2176);
> > > +/* Monitor function Receiver Data */
> > > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONRXDAT, 0, 8);
> > > +/* Monitor Received Start */
> > > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONSTART, 8, 1);
> > > +/* Monitor Received Repeated Start */
> > > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONRESTART, 9, 1);
> > > +/* Monitor Received NACK */
> > > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONNACK, 10, 1);
> > > +
> > > +/* Peripheral Identification Register */
> > > +REG32(FLEXCOMM_I2C_ID, 4092);
> > > +/* Aperture */
> > > +FIELD(FLEXCOMM_I2C_ID, APERTURE, 0, 8);
> > > +/* Minor revision of module implementation */
> > > +FIELD(FLEXCOMM_I2C_ID, MINOR_REV, 8, 4);
> > > +/* Major revision of module implementation */
> > > +FIELD(FLEXCOMM_I2C_ID, MAJOR_REV, 12, 4);
> > > +/* Module identifier for the selected function */
> > > +FIELD(FLEXCOMM_I2C_ID, ID, 16, 16);
> > > +
> >
> > Are any of the below enums even used? Or for that matter, most of the
> > above fields?
> >
> > If these are just here for documentation, I would prefer English text;
> > it's more dense and easier to read. It's very difficult to tie all this
> > together into a cohesive view of the device registers.
> >
>
> Since this is autogenerated for the full set of the device registers
> there will be fields that are not used either because the emulation is
> incomplete or because they don't have effect for emulation.
>
> I think it is still valuable to have this generated automatically
> instead of doing it by hand.
>
> Would adding options to only generate certain definitions help? As
> long as we are reasonable with the granularity (e.g. register level) I
> think it could trim *most* of the unused generated code without
> becoming too tedious on how to instruct the tool to generate the code.
> However, I expect to still have *some* unused generated code.
Generally it's frowned upon to have a ton of extra stuff that's not
used. I would think some is ok, like defining bits in registers that
aren't used yet, but I have no idea how all the enums below here
actually tie into anything. I'm guessing these are just bitmasks into
registers, but really, it's a lot easier to read if you have something
like:
/*
* The I2C Master function enable. When disabled, the Master
* configuration settings are not changed, but the Master function is
* internally reset.
*/
#define FLEXCOMM_I2C_CFG_MSTEN (1 << 4)
and them have them grouped together with the register they belong to. I
don't know how you would even use these enums. AFAICT, none of them are
used.
And the whole idea of this is to make the code more readable. So if
you define these things, you should use them. Look around through the
code of other devices to get a feel of how things are done.
-corey
>
>
> > The .c file itself seems ok.
> >
> > -corey
> >
> > > +
> > > +typedef enum {
> > > + /*
> > > + * Disabled. The I2C Master function is disabled. When disabled, the Master
> > > + * configuration settings are not changed, but the Master function is
> > > + * internally reset.
> > > + */
> > > + FLEXCOMM_I2C_CFG_MSTEN_DISABLED = 0,
> > > + /* Enabled. The I2C Master function is enabled. */
> > > + FLEXCOMM_I2C_CFG_MSTEN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_CFG_MSTEN_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * Disabled. The I2C slave function is disabled. When disabled, the Slave
> > > + * configuration settings are not changed, but the Slave function is
> > > + * internally reset.
> > > + */
> > > + FLEXCOMM_I2C_CFG_SLVEN_DISABLED = 0,
> > > + /* Enabled. The I2C slave function is enabled. */
> > > + FLEXCOMM_I2C_CFG_SLVEN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_CFG_SLVEN_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * Disabled. The I2C Monitor function is disabled. When disabled, the
> > > + * Monitor function configuration settings are not changed, but the Monitor
> > > + * function is internally reset.
> > > + */
> > > + FLEXCOMM_I2C_CFG_MONEN_DISABLED = 0,
> > > + /* Enabled. The I2C Monitor function is enabled. */
> > > + FLEXCOMM_I2C_CFG_MONEN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_CFG_MONEN_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * Disabled. The time-out function is disabled. When disabled, the time-out
> > > + * function is internally reset.
> > > + */
> > > + FLEXCOMM_I2C_CFG_TIMEOUTEN_DISABLED = 0,
> > > + /*
> > > + * Enabled. The time-out function is enabled. Both types of time-out flags
> > > + * will be generated and will cause interrupts if those flags are enabled.
> > > + * Typically, only one time-out flag will be used in a system.
> > > + */
> > > + FLEXCOMM_I2C_CFG_TIMEOUTEN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_CFG_TIMEOUTEN_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * Disabled. The Monitor function will not perform clock stretching.
> > > + * Software or DMA may not always be able to read data provided by the
> > > + * Monitor function before it (the data) is overwritten. This mode can be
> > > + * used when non-invasive monitoring is critical.
> > > + */
> > > + FLEXCOMM_I2C_CFG_MONCLKSTR_DISABLED = 0,
> > > + /*
> > > + * Enabled. The Monitor function will perform clock stretching, to ensure
> > > + * that the software or DMA can read all incoming data supplied by the
> > > + * Monitor function.
> > > + */
> > > + FLEXCOMM_I2C_CFG_MONCLKSTR_ENABLED = 1,
> > > +} FLEXCOMM_I2C_CFG_MONCLKSTR_Enum;
> > > +
> > > +typedef enum {
> > > + /* Fast mode Plus enable */
> > > + FLEXCOMM_I2C_CFG_HSCAPABLE_FAST_MODE_PLUS = 0,
> > > + /* High Speed mode enable */
> > > + FLEXCOMM_I2C_CFG_HSCAPABLE_HIGH_SPEED = 1,
> > > +} FLEXCOMM_I2C_CFG_HSCAPABLE_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * In progress. Communication is in progress and the Master function is
> > > + * busy and cannot currently accept a command.
> > > + */
> > > + FLEXCOMM_I2C_STAT_MSTPENDING_IN_PROGRESS = 0,
> > > + /*
> > > + * Pending. The Master function needs software service or is in the idle
> > > + * state. If the master is not in the idle state, then the master is
> > > + * waiting to receive or transmit data, or is waiting for the NACK bit.
> > > + */
> > > + FLEXCOMM_I2C_STAT_MSTPENDING_PENDING = 1,
> > > +} FLEXCOMM_I2C_STAT_MSTPENDING_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * Idle. The Master function is available to be used for a new transaction.
> > > + */
> > > + FLEXCOMM_I2C_STAT_MSTSTATE_IDLE = 0,
> > > + /*
> > > + * Receive ready. Received data is available (in Master Receiver mode).
> > > + * Address plus Read was previously sent and Acknowledged by a slave.
> > > + */
> > > + FLEXCOMM_I2C_STAT_MSTSTATE_RECEIVE_READY = 1,
> > > + /*
> > > + * Transmit ready. Data can be transmitted (in Master Transmitter mode).
> > > + * Address plus Write was previously sent and Acknowledged by a slave.
> > > + */
> > > + FLEXCOMM_I2C_STAT_MSTSTATE_TRANSMIT_READY = 2,
> > > + /* NACK Address. Slave NACKed address. */
> > > + FLEXCOMM_I2C_STAT_MSTSTATE_NACK_ADDRESS = 3,
> > > + /* NACK Data. Slave NACKed transmitted data. */
> > > + FLEXCOMM_I2C_STAT_MSTSTATE_NACK_DATA = 4,
> > > +} FLEXCOMM_I2C_STAT_MSTSTATE_Enum;
> > > +
> > > +typedef enum {
> > > + /* No Arbitration Loss has occurred */
> > > + FLEXCOMM_I2C_STAT_MSTARBLOSS_NO_LOSS = 0,
> > > + /*
> > > + * Arbitration loss. The Master function has experienced an Arbitration
> > > + * Loss. At this point, the Master function has already stopped driving the
> > > + * bus and has gone into an idle state. Software can respond by doing
> > > + * nothing, or by sending a Start (to attempt to gain control of the bus
> > > + * when the bus next becomes idle).
> > > + */
> > > + FLEXCOMM_I2C_STAT_MSTARBLOSS_ARBITRATION_LOSS = 1,
> > > +} FLEXCOMM_I2C_STAT_MSTARBLOSS_Enum;
> > > +
> > > +typedef enum {
> > > + /* No Start/Stop Error has occurred. */
> > > + FLEXCOMM_I2C_STAT_MSTSTSTPERR_NO_ERROR = 0,
> > > + /*
> > > + * The Master function has experienced a Start/Stop Error. A Start or Stop
> > > + * was detected at a time when Start or Stop is not allowed by the I2C
> > > + * specification. The Master interface has stopped driving the bus and gone
> > > + * into an idle state; no action is required. A request for a Start could
> > > + * be made, or software could attempt to make sure that the bus has not
> > > + * stalled.
> > > + */
> > > + FLEXCOMM_I2C_STAT_MSTSTSTPERR_ERROR = 1,
> > > +} FLEXCOMM_I2C_STAT_MSTSTSTPERR_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * In progress. The Slave function does not currently need software
> > > + * service.
> > > + */
> > > + FLEXCOMM_I2C_STAT_SLVPENDING_IN_PROGRESS = 0,
> > > + /*
> > > + * Pending. The Slave function needs software service. Information about
> > > + * what is needed is in the Slave state field (SLVSTATE).
> > > + */
> > > + FLEXCOMM_I2C_STAT_SLVPENDING_PENDING = 1,
> > > +} FLEXCOMM_I2C_STAT_SLVPENDING_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * Slave address. Address plus R/W received. At least one of the 4 slave
> > > + * addresses has been matched by hardware.
> > > + */
> > > + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_ADDRESS = 0,
> > > + /* Slave receive. Received data is available (in Slave Receiver mode). */
> > > + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_RECEIVE = 1,
> > > + /* Slave transmit. Data can be transmitted (in Slave Transmitter mode). */
> > > + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_TRANSMIT = 2,
> > > +} FLEXCOMM_I2C_STAT_SLVSTATE_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * Stretching. The slave function is currently stretching the I2C bus
> > > + * clock. Deep-Sleepmode cannot be entered at this time.
> > > + */
> > > + FLEXCOMM_I2C_STAT_SLVNOTSTR_STRETCHING = 0,
> > > + /*
> > > + * Not stretching. The slave function is not currently stretching the I2C
> > > + * bus clock. Deep-sleep mode can be entered at this time.
> > > + */
> > > + FLEXCOMM_I2C_STAT_SLVNOTSTR_NOT_STRETCHING = 1,
> > > +} FLEXCOMM_I2C_STAT_SLVNOTSTR_Enum;
> > > +
> > > +typedef enum {
> > > + /* Address 0. Slave address 0 was matched. */
> > > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS0 = 0,
> > > + /* Address 1. Slave address 1 was matched. */
> > > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS1 = 1,
> > > + /* Address 2. Slave address 2 was matched. */
> > > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS2 = 2,
> > > + /* Address 3. Slave address 3 was matched. */
> > > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS3 = 3,
> > > +} FLEXCOMM_I2C_STAT_SLVIDX_Enum;
> > > +
> > > +typedef enum {
> > > + /* Not selected. The Slave function is not currently selected. */
> > > + FLEXCOMM_I2C_STAT_SLVSEL_NOT_SELECTED = 0,
> > > + /* Selected. The Slave function is currently selected. */
> > > + FLEXCOMM_I2C_STAT_SLVSEL_SELECTED = 1,
> > > +} FLEXCOMM_I2C_STAT_SLVSEL_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * Not deselected. The Slave function has not become deselected. This does
> > > + * not mean that the Slave is currently selected. That information is in
> > > + * the SLVSEL flag.
> > > + */
> > > + FLEXCOMM_I2C_STAT_SLVDESEL_NOT_DESELECTED = 0,
> > > + /*
> > > + * Deselected. The Slave function has become deselected. This is
> > > + * specifically caused by the SLVSEL flag changing from 1 to 0. See SLVSEL
> > > + * for details about when that event occurs.
> > > + */
> > > + FLEXCOMM_I2C_STAT_SLVDESEL_DESELECTED = 1,
> > > +} FLEXCOMM_I2C_STAT_SLVDESEL_Enum;
> > > +
> > > +typedef enum {
> > > + /* No data. The Monitor function does not currently have data available. */
> > > + FLEXCOMM_I2C_STAT_MONRDY_NO_DATA = 0,
> > > + /* Data waiting. The Monitor function has data waiting to be read. */
> > > + FLEXCOMM_I2C_STAT_MONRDY_DATA_WAITING = 1,
> > > +} FLEXCOMM_I2C_STAT_MONRDY_Enum;
> > > +
> > > +typedef enum {
> > > + /* No overrun. Monitor data has not overrun. */
> > > + FLEXCOMM_I2C_STAT_MONOV_NO_OVERRUN = 0,
> > > + /*
> > > + * Overrun. A Monitor data overrun has occurred. An overrun can only happen
> > > + * when Monitor clock stretching not enabled via the CFG[MONCLKSTR] bit.
> > > + * Writing 1 to MONOV bit clears the MONOV flag.
> > > + */
> > > + FLEXCOMM_I2C_STAT_MONOV_OVERRUN = 1,
> > > +} FLEXCOMM_I2C_STAT_MONOV_Enum;
> > > +
> > > +typedef enum {
> > > + /* Inactive. The Monitor function considers the I2C bus to be inactive. */
> > > + FLEXCOMM_I2C_STAT_MONACTIVE_INACTIVE = 0,
> > > + /* Active. The Monitor function considers the I2C bus to be active. */
> > > + FLEXCOMM_I2C_STAT_MONACTIVE_ACTIVE = 1,
> > > +} FLEXCOMM_I2C_STAT_MONACTIVE_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * Not idle. The I2C bus is not idle, or MONIDLE flag has been cleared by
> > > + * software.
> > > + */
> > > + FLEXCOMM_I2C_STAT_MONIDLE_NOT_IDLE = 0,
> > > + /*
> > > + * Idle. The I2C bus has gone idle at least once, since the last time
> > > + * MONIDLE flag was cleared by software.
> > > + */
> > > + FLEXCOMM_I2C_STAT_MONIDLE_IDLE = 1,
> > > +} FLEXCOMM_I2C_STAT_MONIDLE_Enum;
> > > +
> > > +typedef enum {
> > > + /* No time-out. I2C bus events have not caused a time-out. */
> > > + FLEXCOMM_I2C_STAT_EVENTTIMEOUT_NO_TIMEOUT = 0,
> > > + /*
> > > + * Event time-out. The time between I2C bus events has been longer than the
> > > + * time specified by the TIMEOUT register.
> > > + */
> > > + FLEXCOMM_I2C_STAT_EVENTTIMEOUT_EVEN_TIMEOUT = 1,
> > > +} FLEXCOMM_I2C_STAT_EVENTTIMEOUT_Enum;
> > > +
> > > +typedef enum {
> > > + /* No time-out. SCL low time has not caused a time-out. */
> > > + FLEXCOMM_I2C_STAT_SCLTIMEOUT_NO_TIMEOUT = 0,
> > > + /* Time-out. SCL low time has caused a time-out. */
> > > + FLEXCOMM_I2C_STAT_SCLTIMEOUT_TIMEOUT = 1,
> > > +} FLEXCOMM_I2C_STAT_SCLTIMEOUT_Enum;
> > > +
> > > +typedef enum {
> > > + /* Disabled. The MstPending interrupt is disabled. */
> > > + FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_DISABLED = 0,
> > > + /* Enabled. The MstPending interrupt is enabled. */
> > > + FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_Enum;
> > > +
> > > +typedef enum {
> > > + /* Disabled. The MstArbLoss interrupt is disabled. */
> > > + FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_DISABLED = 0,
> > > + /* Enabled. The MstArbLoss interrupt is enabled. */
> > > + FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_Enum;
> > > +
> > > +typedef enum {
> > > + /* Disabled. The MstStStpErr interrupt is disabled. */
> > > + FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_DISABLED = 0,
> > > + /* Enabled. The MstStStpErr interrupt is enabled. */
> > > + FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_Enum;
> > > +
> > > +typedef enum {
> > > + /* Disabled. The SlvPending interrupt is disabled. */
> > > + FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_DISABLED = 0,
> > > + /* Enabled. The SlvPending interrupt is enabled. */
> > > + FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_Enum;
> > > +
> > > +typedef enum {
> > > + /* Disabled. The SlvNotStr interrupt is disabled. */
> > > + FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_DISABLED = 0,
> > > + /* Enabled. The SlvNotStr interrupt is enabled. */
> > > + FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_Enum;
> > > +
> > > +typedef enum {
> > > + /* Disabled. The SlvDeSel interrupt is disabled. */
> > > + FLEXCOMM_I2C_INTENSET_SLVDESELEN_DISABLED = 0,
> > > + /* Enabled. The SlvDeSel interrupt is enabled. */
> > > + FLEXCOMM_I2C_INTENSET_SLVDESELEN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_INTENSET_SLVDESELEN_Enum;
> > > +
> > > +typedef enum {
> > > + /* Disabled. The MonRdy interrupt is disabled. */
> > > + FLEXCOMM_I2C_INTENSET_MONRDYEN_DISABLED = 0,
> > > + /* Enabled. The MonRdy interrupt is enabled. */
> > > + FLEXCOMM_I2C_INTENSET_MONRDYEN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_INTENSET_MONRDYEN_Enum;
> > > +
> > > +typedef enum {
> > > + /* Disabled. The MonOv interrupt is disabled. */
> > > + FLEXCOMM_I2C_INTENSET_MONOVEN_DISABLED = 0,
> > > + /* Enabled. The MonOv interrupt is enabled. */
> > > + FLEXCOMM_I2C_INTENSET_MONOVEN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_INTENSET_MONOVEN_Enum;
> > > +
> > > +typedef enum {
> > > + /* Disabled. The MonIdle interrupt is disabled. */
> > > + FLEXCOMM_I2C_INTENSET_MONIDLEEN_DISABLED = 0,
> > > + /* Enabled. The MonIdle interrupt is enabled. */
> > > + FLEXCOMM_I2C_INTENSET_MONIDLEEN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_INTENSET_MONIDLEEN_Enum;
> > > +
> > > +typedef enum {
> > > + /* Disabled. The Event time-out interrupt is disabled. */
> > > + FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_DISABLED = 0,
> > > + /* Enabled. The Event time-out interrupt is enabled. */
> > > + FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_Enum;
> > > +
> > > +typedef enum {
> > > + /* Disabled. The SCL time-out interrupt is disabled. */
> > > + FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_DISABLED = 0,
> > > + /* Enabled. The SCL time-out interrupt is enabled. */
> > > + FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_ENABLED = 1,
> > > +} FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect on interrupt */
> > > + FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_NO_EFFECT = 0,
> > > + /* Clears the interrupt bit in INTENSET register */
> > > + FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_CLEAR_MSTPENDING = 1,
> > > +} FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect on interrupt */
> > > + FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_NO_EFFECT = 0,
> > > + /* Clears the interrupt bit in INTENSET register */
> > > + FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_CLEAR_MSTARBLOSS = 1,
> > > +} FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect on interrupt */
> > > + FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_NO_EFFECT = 0,
> > > + /* Clears the interrupt bit in INTENSET register */
> > > + FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_CLEAR_MSTSTSTPERR = 1,
> > > +} FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect on interrupt */
> > > + FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_NO_EFFECT = 0,
> > > + /* Clears the interrupt bit in INTENSET register */
> > > + FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_CLEAR_SLVPENDING = 1,
> > > +} FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect on interrupt */
> > > + FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_NO_EFFECT = 0,
> > > + /* Clears the interrupt bit in INTENSET register */
> > > + FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_CLEAR_SLVNOTSTR = 1,
> > > +} FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect on interrupt */
> > > + FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_NO_EFFECT = 0,
> > > + /* Clears the interrupt bit in INTENSET register */
> > > + FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_CLEAR_SLVDESEL = 1,
> > > +} FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect on interrupt */
> > > + FLEXCOMM_I2C_INTENCLR_MONRDYCLR_NO_EFFECT = 0,
> > > + /* Clears the interrupt bit in INTENSET register */
> > > + FLEXCOMM_I2C_INTENCLR_MONRDYCLR_CLEAR_MONRDY = 1,
> > > +} FLEXCOMM_I2C_INTENCLR_MONRDYCLR_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect on interrupt */
> > > + FLEXCOMM_I2C_INTENCLR_MONOVCLR_NO_EFFECT = 0,
> > > + /* Clears the interrupt bit in INTENSET register */
> > > + FLEXCOMM_I2C_INTENCLR_MONOVCLR_CLEAR_MONOV = 1,
> > > +} FLEXCOMM_I2C_INTENCLR_MONOVCLR_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect on interrupt */
> > > + FLEXCOMM_I2C_INTENCLR_MONIDLECLR_NO_EFFECT = 0,
> > > + /* Clears the interrupt bit in INTENSET register */
> > > + FLEXCOMM_I2C_INTENCLR_MONIDLECLR_CLEAR_MONIDLE = 1,
> > > +} FLEXCOMM_I2C_INTENCLR_MONIDLECLR_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect on interrupt */
> > > + FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_NO_EFFECT = 0,
> > > + /* Clears the interrupt bit in INTENSET register */
> > > + FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_CLEAR_EVENTTIMEOUT = 1,
> > > +} FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect on interrupt */
> > > + FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_NO_EFFECT = 0,
> > > + /* Clears the interrupt bit in INTENSET register */
> > > + FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_CLEAR_SCLTIMEOUT = 1,
> > > +} FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_Enum;
> > > +
> > > +typedef enum {
> > > + /* A time-out will occur after 16 counts of the I2C function clock. */
> > > + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT16 = 0,
> > > + /* A time-out will occur after 32 counts of the I2C function clock. */
> > > + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT32 = 1,
> > > + /* A time-out will occur after 65,536 counts of the I2C function clock. */
> > > + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT65K = 4095,
> > > +} FLEXCOMM_I2C_TIMEOUT_TO_Enum;
> > > +
> > > +typedef enum {
> > > + /* FCLK is used directly by the I2C. */
> > > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKUNDIVIDED = 0,
> > > + /* FCLK is divided by 2 before being used by the I2C. */
> > > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV2 = 1,
> > > + /* FCLK is divided by 3 before being used by the I2C. */
> > > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV3 = 2,
> > > + /* FCLK is divided by 65,536 before being used by the I2C. */
> > > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV65K = 65535,
> > > +} FLEXCOMM_I2C_CLKDIV_DIVVAL_Enum;
> > > +
> > > +typedef enum {
> > > + /* Not active */
> > > + FLEXCOMM_I2C_INTSTAT_MSTPENDING_MSTPENDING_ISNOTACTIVE = 0,
> > > + /* Active */
> > > + FLEXCOMM_I2C_INTSTAT_MSTPENDING_MSTPENDING_ISACTIVE = 1,
> > > +} FLEXCOMM_I2C_INTSTAT_MSTPENDING_Enum;
> > > +
> > > +typedef enum {
> > > + /* Not active */
> > > + FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_MSTARBLOSS_ISNOTACTIVE = 0,
> > > + /* Active */
> > > + FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_MSTARBLOSS_ISACTIVE = 1,
> > > +} FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_Enum;
> > > +
> > > +typedef enum {
> > > + /* Not active */
> > > + FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_MSTSTSTPERR_ISNOTACTIVE = 0,
> > > + /* Active */
> > > + FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_MSTSTSTPERR_ISACTIVE = 1,
> > > +} FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_Enum;
> > > +
> > > +typedef enum {
> > > + /* Not active */
> > > + FLEXCOMM_I2C_INTSTAT_SLVPENDING_SLVPENDING_ISNOTACTIVE = 0,
> > > + /* Active */
> > > + FLEXCOMM_I2C_INTSTAT_SLVPENDING_SLVPENDING_ISACTIVE = 1,
> > > +} FLEXCOMM_I2C_INTSTAT_SLVPENDING_Enum;
> > > +
> > > +typedef enum {
> > > + /* Not active */
> > > + FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_SLVNOTSTR_ISNOTACTIVE = 0,
> > > + /* Active */
> > > + FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_SLVNOTSTR_ISACTIVE = 1,
> > > +} FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_Enum;
> > > +
> > > +typedef enum {
> > > + /* Not active */
> > > + FLEXCOMM_I2C_INTSTAT_SLVDESEL_SLVDESEL_ISNOTACTIVE = 0,
> > > + /* Active */
> > > + FLEXCOMM_I2C_INTSTAT_SLVDESEL_SLVDESEL_ISACTIVE = 1,
> > > +} FLEXCOMM_I2C_INTSTAT_SLVDESEL_Enum;
> > > +
> > > +typedef enum {
> > > + /* Not active */
> > > + FLEXCOMM_I2C_INTSTAT_MONRDY_MONRDY_ISNOTACTIVE = 0,
> > > + /* Active */
> > > + FLEXCOMM_I2C_INTSTAT_MONRDY_MONRDY_ISACTIVE = 1,
> > > +} FLEXCOMM_I2C_INTSTAT_MONRDY_Enum;
> > > +
> > > +typedef enum {
> > > + /* Not active */
> > > + FLEXCOMM_I2C_INTSTAT_MONOV_MONOV_ISNOTACTIVE = 0,
> > > + /* Active */
> > > + FLEXCOMM_I2C_INTSTAT_MONOV_MONOV_ISACTIVE = 1,
> > > +} FLEXCOMM_I2C_INTSTAT_MONOV_Enum;
> > > +
> > > +typedef enum {
> > > + /* Not active */
> > > + FLEXCOMM_I2C_INTSTAT_MONIDLE_MONIDLE_ISNOTACTIVE = 0,
> > > + /* Active */
> > > + FLEXCOMM_I2C_INTSTAT_MONIDLE_MONIDLE_ISACTIVE = 1,
> > > +} FLEXCOMM_I2C_INTSTAT_MONIDLE_Enum;
> > > +
> > > +typedef enum {
> > > + /* Not active */
> > > + FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_EVENTTIMEOUT_ISNOTACTIVE = 0,
> > > + /* Active */
> > > + FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_EVENTTIMEOUT_ISACTIVE = 1,
> > > +} FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_Enum;
> > > +
> > > +typedef enum {
> > > + /* Not active */
> > > + FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_SCLTIMEOUT_ISNOTACTIVE = 0,
> > > + /* Active */
> > > + FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_SCLTIMEOUT_ISACTIVE = 1,
> > > +} FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect */
> > > + FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_NO_EFFECT = 0,
> > > + /*
> > > + * Continue. Informs the Master function to continue to the next operation.
> > > + * This action must done after writing transmit data, reading received
> > > + * data, or any other housekeeping related to the next bus operation.
> > > + */
> > > + FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_CONTINUE = 1,
> > > +} FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect */
> > > + FLEXCOMM_I2C_MSTCTL_MSTSTART_NO_EFFECT = 0,
> > > + /*
> > > + * Start. A Start will be generated on the I2C bus at the next allowed
> > > + * time.
> > > + */
> > > + FLEXCOMM_I2C_MSTCTL_MSTSTART_START = 1,
> > > +} FLEXCOMM_I2C_MSTCTL_MSTSTART_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect */
> > > + FLEXCOMM_I2C_MSTCTL_MSTSTOP_NO_EFFECT = 0,
> > > + /*
> > > + * Stop. A Stop will be generated on the I2C bus at the next allowed time,
> > > + * preceded by a NACK to the slave if the master is receiving data from the
> > > + * slave (in Master Receiver mode).
> > > + */
> > > + FLEXCOMM_I2C_MSTCTL_MSTSTOP_STOP = 1,
> > > +} FLEXCOMM_I2C_MSTCTL_MSTSTOP_Enum;
> > > +
> > > +typedef enum {
> > > + /* Disable. No DMA requests are generated for master operation. */
> > > + FLEXCOMM_I2C_MSTCTL_MSTDMA_DISABLED = 0,
> > > + /*
> > > + * Enable. A DMA request is generated for I2C master data operations. When
> > > + * this I2C master is generating Acknowledge bits in Master Receiver mode,
> > > + * the acknowledge is generated automatically.
> > > + */
> > > + FLEXCOMM_I2C_MSTCTL_MSTDMA_ENABLED = 1,
> > > +} FLEXCOMM_I2C_MSTCTL_MSTDMA_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * 2 clocks. Minimum SCL low time is 2 clocks of the I2C clock pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_2CLOCKS = 0,
> > > + /*
> > > + * 3 clocks. Minimum SCL low time is 3 clocks of the I2C clock pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_3CLOCKS = 1,
> > > + /*
> > > + * 4 clocks. Minimum SCL low time is 4 clocks of the I2C clock pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_4CLOCKS = 2,
> > > + /*
> > > + * 5 clocks. Minimum SCL low time is 5 clocks of the I2C clock pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_5CLOCKS = 3,
> > > + /*
> > > + * 6 clocks. Minimum SCL low time is 6 clocks of the I2C clock pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_6CLOCKS = 4,
> > > + /*
> > > + * 7 clocks. Minimum SCL low time is 7 clocks of the I2C clock pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_7CLOCKS = 5,
> > > + /*
> > > + * 8 clocks. Minimum SCL low time is 8 clocks of the I2C clock pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_8CLOCKS = 6,
> > > + /*
> > > + * 9 clocks. Minimum SCL low time is 9 clocks of the I2C clock pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_9CLOCKS = 7,
> > > +} FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * 2 clocks. Minimum SCL high time is 2 clocks of the I2C clock
> > > + * pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_2CLOCKS = 0,
> > > + /*
> > > + * 3 clocks. Minimum SCL high time is 3 clocks of the I2C clock pre-divider
> > > + * .
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_3CLOCKS = 1,
> > > + /*
> > > + * 4 clocks. Minimum SCL high time is 4 clocks of the I2C clock
> > > + * pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_4CLOCKS = 2,
> > > + /*
> > > + * 5 clocks. Minimum SCL high time is 5 clocks of the I2C clock
> > > + * pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_5CLOCKS = 3,
> > > + /*
> > > + * 6 clocks. Minimum SCL high time is 6 clocks of the I2C clock
> > > + * pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_6CLOCKS = 4,
> > > + /*
> > > + * 7 clocks. Minimum SCL high time is 7 clocks of the I2C clock
> > > + * pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_7CLOCKS = 5,
> > > + /*
> > > + * 8 clocks. Minimum SCL high time is 8 clocks of the I2C clock
> > > + * pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_8CLOCKS = 6,
> > > + /*
> > > + * 9 clocks. Minimum SCL high time is 9 clocks of the I2C clock
> > > + * pre-divider.
> > > + */
> > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_9CLOCKS = 7,
> > > +} FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect */
> > > + FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_NO_EFFECT = 0,
> > > + /*
> > > + * Continue. Informs the Slave function to continue to the next operation,
> > > + * by clearing the STAT[SLVPENDING] flag. This must be done after writing
> > > + * transmit data, reading received data, or any other housekeeping related
> > > + * to the next bus operation. Automatic Operation has different
> > > + * requirements. SLVCONTINUE should not be set unless SLVPENDING = 1.
> > > + */
> > > + FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_CONTINUE = 1,
> > > +} FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_Enum;
> > > +
> > > +typedef enum {
> > > + /* No effect */
> > > + FLEXCOMM_I2C_SLVCTL_SLVNACK_NO_EFFECT = 0,
> > > + /*
> > > + * NACK. Causes the Slave function to NACK the master when the slave is
> > > + * receiving data from the master (in Slave Receiver mode).
> > > + */
> > > + FLEXCOMM_I2C_SLVCTL_SLVNACK_NACK = 1,
> > > +} FLEXCOMM_I2C_SLVCTL_SLVNACK_Enum;
> > > +
> > > +typedef enum {
> > > + /* Disabled. No DMA requests are issued for Slave mode operation. */
> > > + FLEXCOMM_I2C_SLVCTL_SLVDMA_DISABLED = 0,
> > > + /*
> > > + * Enabled. DMA requests are issued for I2C slave data transmission and
> > > + * reception.
> > > + */
> > > + FLEXCOMM_I2C_SLVCTL_SLVDMA_ENABLED = 1,
> > > +} FLEXCOMM_I2C_SLVCTL_SLVDMA_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * Normal, non-automatic operation. If AUTONACK = 0, then a SlvPending
> > > + * interrupt is generated when a matching address is received. If AUTONACK
> > > + * = 1, then received addresses are NACKed (ignored).
> > > + */
> > > + FLEXCOMM_I2C_SLVCTL_AUTOACK_NORMAL = 0,
> > > + /*
> > > + * A header with matching SLVADR0 and matching direction as set by
> > > + * AUTOMATCHREAD will be ACKed immediately, allowing the master to move on
> > > + * to the data bytes. If the address matches SLVADR0, but the direction
> > > + * does not match AUTOMATCHREAD, then the behavior will depend on the
> > > + * SLVADR0[AUTONACK] bit: if AUTONACK is set, then it will be Nacked; if
> > > + * AUTONACK is clear, then a SlvPending interrupt is generated.
> > > + */
> > > + FLEXCOMM_I2C_SLVCTL_AUTOACK_AUTOMATIC_ACK = 1,
> > > +} FLEXCOMM_I2C_SLVCTL_AUTOACK_Enum;
> > > +
> > > +typedef enum {
> > > + /* In Automatic Mode, the expected next operation is an I2C write. */
> > > + FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_I2C_WRITE = 0,
> > > + /* In Automatic Mode, the expected next operation is an I2C read. */
> > > + FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_I2C_READ = 1,
> > > +} FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_Enum;
> > > +
> > > +typedef enum {
> > > + /* Enabled. Slave Address n is enabled. */
> > > + FLEXCOMM_I2C_SLVADR0_SADISABLE_ENABLED = 0,
> > > + /* Ignored. Slave Address n is ignored. */
> > > + FLEXCOMM_I2C_SLVADR0_SADISABLE_DISABLED = 1,
> > > +} FLEXCOMM_I2C_SLVADR0_SADISABLE_Enum;
> > > +
> > > +typedef enum {
> > > + /* Normal operation, matching I2C addresses are not ignored. */
> > > + FLEXCOMM_I2C_SLVADR0_AUTONACK_NORMAL = 0,
> > > + /*
> > > + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> > > + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> > > + * matches the direction.
> > > + */
> > > + FLEXCOMM_I2C_SLVADR0_AUTONACK_AUTOMATIC = 1,
> > > +} FLEXCOMM_I2C_SLVADR0_AUTONACK_Enum;
> > > +
> > > +typedef enum {
> > > + /* Enabled. Slave Address n is enabled. */
> > > + FLEXCOMM_I2C_SLVADR1_SADISABLE_ENABLED = 0,
> > > + /* Ignored. Slave Address n is ignored. */
> > > + FLEXCOMM_I2C_SLVADR1_SADISABLE_DISABLED = 1,
> > > +} FLEXCOMM_I2C_SLVADR1_SADISABLE_Enum;
> > > +
> > > +typedef enum {
> > > + /* Normal operation, matching I2C addresses are not ignored. */
> > > + FLEXCOMM_I2C_SLVADR1_AUTONACK_NORMAL = 0,
> > > + /*
> > > + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> > > + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> > > + * matches the direction.
> > > + */
> > > + FLEXCOMM_I2C_SLVADR1_AUTONACK_AUTOMATIC = 1,
> > > +} FLEXCOMM_I2C_SLVADR1_AUTONACK_Enum;
> > > +
> > > +typedef enum {
> > > + /* Enabled. Slave Address n is enabled. */
> > > + FLEXCOMM_I2C_SLVADR2_SADISABLE_ENABLED = 0,
> > > + /* Ignored. Slave Address n is ignored. */
> > > + FLEXCOMM_I2C_SLVADR2_SADISABLE_DISABLED = 1,
> > > +} FLEXCOMM_I2C_SLVADR2_SADISABLE_Enum;
> > > +
> > > +typedef enum {
> > > + /* Normal operation, matching I2C addresses are not ignored. */
> > > + FLEXCOMM_I2C_SLVADR2_AUTONACK_NORMAL = 0,
> > > + /*
> > > + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> > > + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> > > + * matches the direction.
> > > + */
> > > + FLEXCOMM_I2C_SLVADR2_AUTONACK_AUTOMATIC = 1,
> > > +} FLEXCOMM_I2C_SLVADR2_AUTONACK_Enum;
> > > +
> > > +typedef enum {
> > > + /* Enabled. Slave Address n is enabled. */
> > > + FLEXCOMM_I2C_SLVADR3_SADISABLE_ENABLED = 0,
> > > + /* Ignored. Slave Address n is ignored. */
> > > + FLEXCOMM_I2C_SLVADR3_SADISABLE_DISABLED = 1,
> > > +} FLEXCOMM_I2C_SLVADR3_SADISABLE_Enum;
> > > +
> > > +typedef enum {
> > > + /* Normal operation, matching I2C addresses are not ignored. */
> > > + FLEXCOMM_I2C_SLVADR3_AUTONACK_NORMAL = 0,
> > > + /*
> > > + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> > > + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> > > + * matches the direction.
> > > + */
> > > + FLEXCOMM_I2C_SLVADR3_AUTONACK_AUTOMATIC = 1,
> > > +} FLEXCOMM_I2C_SLVADR3_AUTONACK_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * Mask. The SLVQUAL0 field is used as a logical mask for matching address
> > > + * 0.
> > > + */
> > > + FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_MASK = 0,
> > > + /*
> > > + * Extend. The SLVQUAL0 field is used to extend address 0 matching in a
> > > + * range of addresses.
> > > + */
> > > + FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_EXTEND = 1,
> > > +} FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * No start detected. The Monitor function has not detected a Start event
> > > + * on the I2C bus.
> > > + */
> > > + FLEXCOMM_I2C_MONRXDAT_MONSTART_NO_START_DETECTED = 0,
> > > + /*
> > > + * Start detected. The Monitor function has detected a Start event on the
> > > + * I2C bus.
> > > + */
> > > + FLEXCOMM_I2C_MONRXDAT_MONSTART_START_DETECTED = 1,
> > > +} FLEXCOMM_I2C_MONRXDAT_MONSTART_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * No repeated start detected. The Monitor function has not detected a
> > > + * Repeated Start event on the I2C bus.
> > > + */
> > > + FLEXCOMM_I2C_MONRXDAT_MONRESTART_NOT_DETECTED = 0,
> > > + /*
> > > + * Repeated start detected. The Monitor function has detected a Repeated
> > > + * Start event on the I2C bus.
> > > + */
> > > + FLEXCOMM_I2C_MONRXDAT_MONRESTART_DETECTED = 1,
> > > +} FLEXCOMM_I2C_MONRXDAT_MONRESTART_Enum;
> > > +
> > > +typedef enum {
> > > + /*
> > > + * Acknowledged. The data currently being provided by the Monitor function
> > > + * was acknowledged by at least one master or slave receiver.
> > > + */
> > > + FLEXCOMM_I2C_MONRXDAT_MONNACK_ACKNOWLEDGED = 0,
> > > + /*
> > > + * Not acknowledged. The data currently being provided by the Monitor
> > > + * function was not acknowledged by any receiver.
> > > + */
> > > + FLEXCOMM_I2C_MONRXDAT_MONNACK_NOT_ACKNOWLEDGED = 1,
> > > +} FLEXCOMM_I2C_MONRXDAT_MONNACK_Enum;
> > > +
> > > +
> > > +#define FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(_name) \
> > > + struct RegisterAccessInfo _name[FLEXCOMM_I2C_REGS_NO] = { \
> > > + [0 ... FLEXCOMM_I2C_REGS_NO - 1] = { \
> > > + .name = "", \
> > > + .addr = -1, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_CFG] = { \
> > > + .name = "CFG", \
> > > + .addr = 0x800, \
> > > + .ro = 0xFFFFFFC0, \
> > > + .reset = 0x0, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_STAT] = { \
> > > + .name = "STAT", \
> > > + .addr = 0x804, \
> > > + .ro = 0xFCF57FAF, \
> > > + .reset = 0x801, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_INTENSET] = { \
> > > + .name = "INTENSET", \
> > > + .addr = 0x808, \
> > > + .ro = 0xFCF476AE, \
> > > + .reset = 0x0, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_INTENCLR] = { \
> > > + .name = "INTENCLR", \
> > > + .addr = 0x80C, \
> > > + .ro = 0xFCF476AE, \
> > > + .reset = 0x0, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_TIMEOUT] = { \
> > > + .name = "TIMEOUT", \
> > > + .addr = 0x810, \
> > > + .ro = 0xFFFF0000, \
> > > + .reset = 0xFFFF, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_CLKDIV] = { \
> > > + .name = "CLKDIV", \
> > > + .addr = 0x814, \
> > > + .ro = 0xFFFF0000, \
> > > + .reset = 0x0, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_INTSTAT] = { \
> > > + .name = "INTSTAT", \
> > > + .addr = 0x818, \
> > > + .ro = 0xFFFFFFFF, \
> > > + .reset = 0x801, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_MSTCTL] = { \
> > > + .name = "MSTCTL", \
> > > + .addr = 0x820, \
> > > + .ro = 0xFFFFFFF0, \
> > > + .reset = 0x0, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_MSTTIME] = { \
> > > + .name = "MSTTIME", \
> > > + .addr = 0x824, \
> > > + .ro = 0xFFFFFF88, \
> > > + .reset = 0x77, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_MSTDAT] = { \
> > > + .name = "MSTDAT", \
> > > + .addr = 0x828, \
> > > + .ro = 0xFFFFFF00, \
> > > + .reset = 0x0, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_SLVCTL] = { \
> > > + .name = "SLVCTL", \
> > > + .addr = 0x840, \
> > > + .ro = 0xFFFFFCF4, \
> > > + .reset = 0x0, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_SLVDAT] = { \
> > > + .name = "SLVDAT", \
> > > + .addr = 0x844, \
> > > + .ro = 0xFFFFFF00, \
> > > + .reset = 0x0, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_SLVADR0] = { \
> > > + .name = "SLVADR0", \
> > > + .addr = 0x848, \
> > > + .ro = 0xFFFF7F00, \
> > > + .reset = 0x1, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_SLVADR1] = { \
> > > + .name = "SLVADR1", \
> > > + .addr = 0x84C, \
> > > + .ro = 0xFFFF7F00, \
> > > + .reset = 0x1, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_SLVADR2] = { \
> > > + .name = "SLVADR2", \
> > > + .addr = 0x850, \
> > > + .ro = 0xFFFF7F00, \
> > > + .reset = 0x1, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_SLVADR3] = { \
> > > + .name = "SLVADR3", \
> > > + .addr = 0x854, \
> > > + .ro = 0xFFFF7F00, \
> > > + .reset = 0x1, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_SLVQUAL0] = { \
> > > + .name = "SLVQUAL0", \
> > > + .addr = 0x858, \
> > > + .ro = 0xFFFFFF00, \
> > > + .reset = 0x0, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_MONRXDAT] = { \
> > > + .name = "MONRXDAT", \
> > > + .addr = 0x880, \
> > > + .ro = 0xFFFFFFFF, \
> > > + .reset = 0x0, \
> > > + }, \
> > > + [R_FLEXCOMM_I2C_ID] = { \
> > > + .name = "ID", \
> > > + .addr = 0xFFC, \
> > > + .ro = 0xFFFFFFFF, \
> > > + .reset = 0xE0301300, \
> > > + }, \
> > > + }
> > > diff --git a/include/hw/i2c/flexcomm_i2c.h b/include/hw/i2c/flexcomm_i2c.h
> > > new file mode 100644
> > > index 0000000000..7b27e333d7
> > > --- /dev/null
> > > +++ b/include/hw/i2c/flexcomm_i2c.h
> > > @@ -0,0 +1,40 @@
> > > +/*
> > > + * QEMU model for NXP's FLEXCOMM I2C
> > > + *
> > > + * Copyright (c) 2024 Google LLC
> > > + *
> > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > + *
> > > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > > + * See the COPYING file in the top-level directory.
> > > + */
> > > +
> > > +#ifndef HW_FLEXCOMM_I2C_H
> > > +#define HW_FLEXCOMM_I2C_H
> > > +
> > > +#include "hw/i2c/i2c.h"
> > > +#include "hw/misc/flexcomm_function.h"
> > > +
> > > +#define TYPE_FLEXCOMM_I2C "flexcomm-i2c"
> > > +OBJECT_DECLARE_TYPE(FlexcommI2cState, FlexcommI2cClass, FLEXCOMM_I2C);
> > > +
> > > +struct FlexcommI2cState {
> > > + FlexcommFunction parent_obj;
> > > +
> > > + I2CBus *bus;
> > > +};
> > > +
> > > +struct FlexcommI2cClass {
> > > + FlexcommFunctionClass parent_obj;
> > > +
> > > + FlexcommFunctionSelect select;
> > > +};
> > > +
> > > +#define MSTSTATE_IDLE 0
> > > +#define MSTSTATE_RXRDY 1
> > > +#define MSTSTATE_TXRDY 2
> > > +#define MSTSTATE_NAKADR 3
> > > +#define MSTSTATE_NAKDAT 4
> > > +
> > > +
> > > +#endif /* HW_FLEXCOMM_I2C_H */
> > > diff --git a/include/hw/misc/flexcomm.h b/include/hw/misc/flexcomm.h
> > > index 679b7ea64d..c9f1cd3890 100644
> > > --- a/include/hw/misc/flexcomm.h
> > > +++ b/include/hw/misc/flexcomm.h
> > > @@ -16,6 +16,7 @@
> > > #include "hw/arm/svd/flexcomm.h"
> > > #include "qemu/fifo32.h"
> > > #include "hw/char/flexcomm_usart.h"
> > > +#include "hw/i2c/flexcomm_i2c.h"
> > >
> > > #define FLEXCOMM_FUNC_USART 0
> > > #define FLEXCOMM_FUNC_SPI 1
> > > @@ -48,6 +49,7 @@ struct FlexcommState {
> > > Fifo32 rx_fifo;
> > > Fifo32 tx_fifo;
> > > FlexcommUsartState usart;
> > > + FlexcommI2cState i2c;
> > > };
> > >
> > > #endif /* HW_FLEXCOMM_H */
> > > diff --git a/hw/i2c/flexcomm_i2c.c b/hw/i2c/flexcomm_i2c.c
> > > new file mode 100644
> > > index 0000000000..e5341ec241
> > > --- /dev/null
> > > +++ b/hw/i2c/flexcomm_i2c.c
> > > @@ -0,0 +1,250 @@
> > > +/*
> > > + * QEMU model for NXP's FLEXCOMM I2C
> > > + *
> > > + * Copyright (c) 2024 Google LLC
> > > + *
> > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > + *
> > > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > > + * See the COPYING file in the top-level directory.
> > > + */
> > > +
> > > +#include "qemu/osdep.h"
> > > +#include "qemu/cutils.h"
> > > +#include "hw/irq.h"
> > > +#include "hw/qdev-properties.h"
> > > +#include "qemu/log.h"
> > > +#include "qemu/module.h"
> > > +#include "exec/address-spaces.h"
> > > +#include "qapi/error.h"
> > > +#include "trace.h"
> > > +#include "hw/i2c/flexcomm_i2c.h"
> > > +#include "hw/arm/svd/flexcomm_i2c.h"
> > > +
> > > +#define REG(s, reg) (s->regs[R_FLEXCOMM_I2C_##reg])
> > > +#define RF_WR(s, reg, field, val) \
> > > + ARRAY_FIELD_DP32(s->regs, FLEXCOMM_I2C_##reg, field, val)
> > > +#define RF_RD(s, reg, field) \
> > > + ARRAY_FIELD_EX32(s->regs, FLEXCOMM_I2C_##reg, field)
> > > +
> > > +static FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(reg_info);
> > > +
> > > +static void flexcomm_i2c_reset(FlexcommFunction *f)
> > > +{
> > > + for (int i = 0; i < FLEXCOMM_I2C_REGS_NO; i++) {
> > > + hwaddr addr = reg_info[i].addr;
> > > +
> > > + if (addr != -1) {
> > > + struct RegisterInfo ri = {
> > > + .data = &f->regs[addr / 4],
> > > + .data_size = 4,
> > > + .access = ®_info[i],
> > > + };
> > > +
> > > + register_reset(&ri);
> > > + }
> > > + }
> > > +}
> > > +
> > > +static void flexcomm_i2c_irq_update(FlexcommFunction *f)
> > > +{
> > > + bool enabled = RF_RD(f, CFG, MSTEN);
> > > + bool irq, per_irqs;
> > > +
> > > + REG(f, INTSTAT) = REG(f, STAT) & REG(f, INTENSET);
> > > + per_irqs = REG(f, INTSTAT) != 0;
> > > +
> > > + irq = enabled && per_irqs;
> > > +
> > > + trace_flexcomm_i2c_irq(DEVICE(f)->id, irq, per_irqs, enabled);
> > > + flexcomm_set_irq(f, irq);
> > > +}
> > > +
> > > +static MemTxResult flexcomm_i2c_reg_read(void *opaque, hwaddr addr,
> > > + uint64_t *data, unsigned size,
> > > + MemTxAttrs attrs)
> > > +{
> > > + FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
> > > + MemTxResult ret = MEMTX_OK;
> > > + const struct RegisterAccessInfo *rai = ®_info[addr / 4];
> > > +
> > > + if (size != 4) {
> > > + ret = MEMTX_ERROR;
> > > + goto out;
> > > + }
> > > +
> > > + *data = f->regs[addr / 4];
> > > +
> > > + flexcomm_i2c_irq_update(f);
> > > +
> > > +out:
> > > + trace_flexcomm_i2c_reg_read(DEVICE(f)->id, rai->name, addr, *data);
> > > + return ret;
> > > +}
> > > +
> > > +static MemTxResult flexcomm_i2c_reg_write(void *opaque, hwaddr addr,
> > > + uint64_t value, unsigned size,
> > > + MemTxAttrs attrs)
> > > +{
> > > + FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
> > > + FlexcommI2cState *s = FLEXCOMM_I2C(opaque);
> > > + const struct RegisterAccessInfo *rai = ®_info[addr / 4];
> > > + struct RegisterInfo ri = {
> > > + .data = &f->regs[addr / 4],
> > > + .data_size = 4,
> > > + .access = rai,
> > > + };
> > > +
> > > + trace_flexcomm_i2c_reg_write(DEVICE(f)->id, rai->name, addr, value);
> > > +
> > > + if (size != 4) {
> > > + return MEMTX_ERROR;
> > > + }
> > > +
> > > + switch (addr) {
> > > + case A_FLEXCOMM_I2C_CFG:
> > > + {
> > > + register_write(&ri, value, ~0, NULL, false);
> > > + if (RF_RD(f, CFG, SLVEN)) {
> > > + qemu_log_mask(LOG_GUEST_ERROR, "I2C slave not supported");
> > > + }
> > > + if (RF_RD(f, CFG, MONEN)) {
> > > + qemu_log_mask(LOG_GUEST_ERROR, "I2C monitoring not supported");
> > > + }
> > > + break;
> > > + }
> > > + case A_FLEXCOMM_I2C_INTENCLR:
> > > + {
> > > + REG(f, INTENSET) &= ~value;
> > > + break;
> > > + }
> > > + case A_FLEXCOMM_I2C_TIMEOUT:
> > > + {
> > > + register_write(&ri, value, ~0, NULL, false);
> > > + /* The bottom 4 bits are hard-wired to 0xF */
> > > + RF_WR(f, TIMEOUT, TOMIN, 0xf);
> > > + break;
> > > + }
> > > + case A_FLEXCOMM_I2C_MSTCTL:
> > > + {
> > > + register_write(&ri, value, ~0, NULL, false);
> > > + if (RF_RD(f, MSTCTL, MSTSTART)) {
> > > + uint8_t i2c_addr = RF_RD(f, MSTDAT, DATA);
> > > + bool recv = i2c_addr & 1;
> > > +
> > > + trace_flexcomm_i2c_start(DEVICE(s)->id, i2c_addr, recv);
> > > + if (i2c_start_transfer(s->bus, i2c_addr, recv)) {
> > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_NAKADR);
> > > + trace_flexcomm_i2c_nak(DEVICE(s)->id);
> > > + } else {
> > > + if (recv) {
> > > + uint8_t data = i2c_recv(s->bus);
> > > +
> > > + RF_WR(f, MSTDAT, DATA, data);
> > > + trace_flexcomm_i2c_rx(DEVICE(s)->id, data);
> > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_RXRDY);
> > > + } else {
> > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_TXRDY);
> > > + }
> > > + }
> > > + }
> > > + if (RF_RD(f, MSTCTL, MSTSTOP)) {
> > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_IDLE);
> > > + i2c_end_transfer(s->bus);
> > > + }
> > > + if (RF_RD(f, MSTCTL, MSTCONTINUE)) {
> > > + if (RF_RD(f, STAT, MSTSTATE) == MSTSTATE_TXRDY) {
> > > + uint8_t data = RF_RD(f, MSTDAT, DATA);
> > > +
> > > + trace_flexcomm_i2c_tx(DEVICE(s)->id, data);
> > > + if (i2c_send(s->bus, data)) {
> > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_NAKDAT);
> > > + }
> > > + } else if (RF_RD(f, STAT, MSTSTATE) == MSTSTATE_RXRDY) {
> > > + uint8_t data = i2c_recv(s->bus);
> > > +
> > > + RF_WR(f, MSTDAT, DATA, data);
> > > + trace_flexcomm_i2c_rx(DEVICE(s)->id, data);
> > > + }
> > > + }
> > > + break;
> > > + }
> > > + case A_FLEXCOMM_I2C_STAT:
> > > + {
> > > + /* write 1 to clear bits */
> > > + REG(f, STAT) &= ~value;
> > > + break;
> > > + }
> > > + case A_FLEXCOMM_I2C_SLVCTL:
> > > + case A_FLEXCOMM_I2C_SLVDAT:
> > > + case A_FLEXCOMM_I2C_SLVADR0:
> > > + case A_FLEXCOMM_I2C_SLVADR1:
> > > + case A_FLEXCOMM_I2C_SLVADR2:
> > > + case A_FLEXCOMM_I2C_SLVADR3:
> > > + case A_FLEXCOMM_I2C_SLVQUAL0:
> > > + {
> > > + qemu_log_mask(LOG_GUEST_ERROR, "I2C slave not supported\n");
> > > + break;
> > > + }
> > > + default:
> > > + register_write(&ri, value, ~0, NULL, false);
> > > + break;
> > > + }
> > > +
> > > + flexcomm_i2c_irq_update(f);
> > > +
> > > + return MEMTX_OK;
> > > +}
> > > +
> > > +static void flexcomm_i2c_select(FlexcommFunction *f, bool selected)
> > > +{
> > > + FlexcommI2cClass *ic = FLEXCOMM_I2C_GET_CLASS(f);
> > > +
> > > + if (selected) {
> > > + flexcomm_i2c_reset(f);
> > > + }
> > > + ic->select(f, selected);
> > > +}
> > > +
> > > +static const MemoryRegionOps flexcomm_i2c_ops = {
> > > + .read_with_attrs = flexcomm_i2c_reg_read,
> > > + .write_with_attrs = flexcomm_i2c_reg_write,
> > > + .endianness = DEVICE_NATIVE_ENDIAN,
> > > + .valid = {
> > > + .min_access_size = 4,
> > > + .max_access_size = 4,
> > > + .unaligned = false,
> > > + },
> > > +};
> > > +
> > > +static void flexcomm_i2c_realize(DeviceState *dev, Error **errp)
> > > +{
> > > + FlexcommI2cState *s = FLEXCOMM_I2C(dev);
> > > +
> > > + s->bus = i2c_init_bus(DEVICE(s), "bus");
> > > +}
> > > +
> > > +static void flexcomm_i2c_class_init(ObjectClass *klass, void *data)
> > > +{
> > > + DeviceClass *dc = DEVICE_CLASS(klass);
> > > + FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_CLASS(klass);
> > > + FlexcommI2cClass *ic = FLEXCOMM_I2C_CLASS(klass);
> > > +
> > > + dc->realize = flexcomm_i2c_realize;
> > > + ic->select = fc->select;
> > > + fc->select = flexcomm_i2c_select;
> > > + fc->name = "i2c";
> > > + fc->mmio_ops = &flexcomm_i2c_ops;
> > > +}
> > > +
> > > +static const TypeInfo flexcomm_i2c_types[] = {
> > > + {
> > > + .name = TYPE_FLEXCOMM_I2C,
> > > + .parent = TYPE_FLEXCOMM_FUNCTION,
> > > + .instance_size = sizeof(FlexcommI2cState),
> > > + .class_init = flexcomm_i2c_class_init,
> > > + .class_size = sizeof(FlexcommI2cClass),
> > > + },
> > > +};
> > > +
> > > +DEFINE_TYPES(flexcomm_i2c_types);
> > > diff --git a/hw/misc/flexcomm.c b/hw/misc/flexcomm.c
> > > index a291148f27..b1a2f01acf 100644
> > > --- a/hw/misc/flexcomm.c
> > > +++ b/hw/misc/flexcomm.c
> > > @@ -24,6 +24,7 @@
> > > #include "hw/misc/flexcomm.h"
> > > #include "hw/arm/svd/flexcomm_usart.h"
> > > #include "hw/char/flexcomm_usart.h"
> > > +#include "hw/i2c/flexcomm_i2c.h"
> > >
> > > #define REG(s, reg) (s->regs[R_FLEXCOMM_##reg])
> > > #define RF_WR(s, reg, field, val) \
> > > @@ -220,6 +221,7 @@ static void flexcomm_init(Object *obj)
> > > sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container);
> > > sysbus_init_irq(sbd, &s->irq);
> > > object_initialize_child(obj, "usart", &s->usart, TYPE_FLEXCOMM_USART);
> > > + object_initialize_child(obj, "i2c", &s->i2c, TYPE_FLEXCOMM_I2C);
> > > }
> > >
> > > static void flexcomm_finalize(Object *obj)
> > > @@ -250,6 +252,7 @@ static void flexcomm_realize(DeviceState *dev, Error **errp)
> > >
> > > memory_region_add_subregion_overlap(&s->container, 0, &s->mmio, -1);
> > > flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->usart), errp);
> > > + flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->i2c), errp);
> > > }
> > >
> > > static const VMStateDescription vmstate_flexcomm = {
> > > diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build
> > > index 2bde34d15b..417491cd5c 100644
> > > --- a/hw/arm/svd/meson.build
> > > +++ b/hw/arm/svd/meson.build
> > > @@ -7,4 +7,7 @@ if get_option('mcux-soc-svd')
> > > run_target('svd-flexcomm-usart', command: svd_gen_header +
> > > [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_usart.h',
> > > '-p', 'USART0', '-t', 'FLEXCOMM_USART'])
> > > + run_target('svd-flexcomm-i2c', command: svd_gen_header +
> > > + [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_i2c.h',
> > > + '-p', 'I2C0', '-t', 'FLEXCOMM_I2C'])
> > > endif
> > > diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build
> > > index c459adcb59..e7d79e6938 100644
> > > --- a/hw/i2c/meson.build
> > > +++ b/hw/i2c/meson.build
> > > @@ -18,4 +18,5 @@ i2c_ss.add(when: 'CONFIG_PPC4XX', if_true: files('ppc4xx_i2c.c'))
> > > i2c_ss.add(when: 'CONFIG_PCA954X', if_true: files('i2c_mux_pca954x.c'))
> > > i2c_ss.add(when: 'CONFIG_PMBUS', if_true: files('pmbus_device.c'))
> > > i2c_ss.add(when: 'CONFIG_BCM2835_I2C', if_true: files('bcm2835_i2c.c'))
> > > +i2c_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm_i2c.c'))
> > > system_ss.add_all(when: 'CONFIG_I2C', if_true: i2c_ss)
> > > diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
> > > index 6900e06eda..9f0175fab7 100644
> > > --- a/hw/i2c/trace-events
> > > +++ b/hw/i2c/trace-events
> > > @@ -51,3 +51,13 @@ npcm7xx_smbus_recv_fifo(const char *id, uint8_t received, uint8_t expected) "%s
> > >
> > > pca954x_write_bytes(uint8_t value) "PCA954X write data: 0x%02x"
> > > pca954x_read_data(uint8_t value) "PCA954X read data: 0x%02x"
> > > +
> > > +# flexcomm_i2c.c
> > > +
> > > +flexcomm_i2c_reg_read(const char *id, const char *reg_name, uint32_t addr, uint32_t val) " %s: %s[0x%04x] -> 0x%08x"
> > > +flexcomm_i2c_reg_write(const char *id, const char *reg_name, uint32_t addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x"
> > > +flexcomm_i2c_start(const char *id, uint8_t addr, uint8_t recv) "%s: 0x%02x %d"
> > > +flexcomm_i2c_rx(const char *id, uint8_t data) "%s: <- 0x%02x"
> > > +flexcomm_i2c_tx(const char *id, uint8_t data) "%s: -> 0x%02x"
> > > +flexcomm_i2c_nak(const char *id) "%s: <- nak"
> > > +flexcomm_i2c_irq(const char *id, bool irq, bool perirqs, bool enabled) "%s: %d %d %d"
> > > diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
> > > index 14167ae9e8..9a244fa01d 100644
> > > --- a/hw/misc/Kconfig
> > > +++ b/hw/misc/Kconfig
> > > @@ -215,5 +215,6 @@ config XLNX_VERSAL_TRNG
> > >
> > > config FLEXCOMM
> > > bool
> > > + select I2C
> > >
> > > source macio/Kconfig
> > > --
> > > 2.46.0.662.g92d0881bb0-goog
> > >
> > >
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 08/25] hw/i2c: add support for flexcomm i2c
2024-09-18 21:31 ` Corey Minyard
@ 2024-09-18 22:25 ` Octavian Purdila
2024-09-19 9:36 ` Peter Maydell
1 sibling, 0 replies; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 22:25 UTC (permalink / raw)
To: corey
Cc: qemu-devel, qemu-arm, stefanst, pbonzini, peter.maydell,
marcandre.lureau, berrange, eduardo, luc, damien.hedde, alistair,
thuth, philmd, jsnow, crosa, lvivier
On Wed, Sep 18, 2024 at 2:31 PM Corey Minyard <corey@minyard.net> wrote:
>
> On Wed, Sep 18, 2024 at 02:04:58PM -0700, Octavian Purdila wrote:
> > On Wed, Sep 18, 2024 at 1:17???PM Corey Minyard <corey@minyard.net> wrote:
> > >
> > > On Wed, Sep 18, 2024 at 12:22:36PM -0700, Octavian Purdila wrote:
> > > > Add support for NXP's flexcomm i2c. It does not support slave mode or
> > > > DMA.
> > > >
> > > > The patch includes an automatically generated header which contains
> > > > the register layout and helpers.
> > > >
> > > > The header can be regenerated with the svd-flexcomm-i2c target when
> > > > the build is configured with --enable-mcux-soc-svd.
> > > >
> > > > Signed-off-by: Octavian Purdila <tavip@google.com>
> > > > ---
> > > > include/hw/arm/svd/flexcomm_i2c.h | 1190 +++++++++++++++++++++++++++++
> > > > include/hw/i2c/flexcomm_i2c.h | 40 +
> > > > include/hw/misc/flexcomm.h | 2 +
> > > > hw/i2c/flexcomm_i2c.c | 250 ++++++
> > > > hw/misc/flexcomm.c | 3 +
> > > > hw/arm/svd/meson.build | 3 +
> > > > hw/i2c/meson.build | 1 +
> > > > hw/i2c/trace-events | 10 +
> > > > hw/misc/Kconfig | 1 +
> > > > 9 files changed, 1500 insertions(+)
> > > > create mode 100644 include/hw/arm/svd/flexcomm_i2c.h
> > > > create mode 100644 include/hw/i2c/flexcomm_i2c.h
> > > > create mode 100644 hw/i2c/flexcomm_i2c.c
> > > >
> > > > diff --git a/include/hw/arm/svd/flexcomm_i2c.h b/include/hw/arm/svd/flexcomm_i2c.h
> > > > new file mode 100644
> > > > index 0000000000..9017d48446
> > > > --- /dev/null
> > > > +++ b/include/hw/arm/svd/flexcomm_i2c.h
> > > > @@ -0,0 +1,1190 @@
> > > > +/*
> > > > + * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
> > > > + *
> > > > + * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
> > > > + */
> > > > +#pragma once
> > > > +
> > > > +#include "hw/register.h"
> > > > +
> > > > +/* I2C Bus Interface */
> > > > +#define FLEXCOMM_I2C_REGS_NO (1024)
> > > > +
> > > > +/* Configuration Register */
> > > > +REG32(FLEXCOMM_I2C_CFG, 2048);
> > > > +/* Master Enable */
> > > > +FIELD(FLEXCOMM_I2C_CFG, MSTEN, 0, 1);
> > > > +/* Slave Enable */
> > > > +FIELD(FLEXCOMM_I2C_CFG, SLVEN, 1, 1);
> > > > +/* Monitor Enable */
> > > > +FIELD(FLEXCOMM_I2C_CFG, MONEN, 2, 1);
> > > > +/* I2C bus Time-out Enable */
> > > > +FIELD(FLEXCOMM_I2C_CFG, TIMEOUTEN, 3, 1);
> > > > +/* Monitor function Clock Stretching */
> > > > +FIELD(FLEXCOMM_I2C_CFG, MONCLKSTR, 4, 1);
> > > > +/* High Speed mode Capable enable */
> > > > +FIELD(FLEXCOMM_I2C_CFG, HSCAPABLE, 5, 1);
> > > > +
> > > > +/* Status Register */
> > > > +REG32(FLEXCOMM_I2C_STAT, 2052);
> > > > +/* Master Pending */
> > > > +FIELD(FLEXCOMM_I2C_STAT, MSTPENDING, 0, 1);
> > > > +/* Master State code */
> > > > +FIELD(FLEXCOMM_I2C_STAT, MSTSTATE, 1, 3);
> > > > +/* Master Arbitration Loss flag */
> > > > +FIELD(FLEXCOMM_I2C_STAT, MSTARBLOSS, 4, 1);
> > > > +/* Master Start/Stop Error flag */
> > > > +FIELD(FLEXCOMM_I2C_STAT, MSTSTSTPERR, 6, 1);
> > > > +/* Slave Pending */
> > > > +FIELD(FLEXCOMM_I2C_STAT, SLVPENDING, 8, 1);
> > > > +/* Slave State */
> > > > +FIELD(FLEXCOMM_I2C_STAT, SLVSTATE, 9, 2);
> > > > +/* Slave Not Stretching */
> > > > +FIELD(FLEXCOMM_I2C_STAT, SLVNOTSTR, 11, 1);
> > > > +/* Slave address match Index T */
> > > > +FIELD(FLEXCOMM_I2C_STAT, SLVIDX, 12, 2);
> > > > +/* Slave selected flag */
> > > > +FIELD(FLEXCOMM_I2C_STAT, SLVSEL, 14, 1);
> > > > +/* Slave Deselected flag */
> > > > +FIELD(FLEXCOMM_I2C_STAT, SLVDESEL, 15, 1);
> > > > +/* Monitor Ready */
> > > > +FIELD(FLEXCOMM_I2C_STAT, MONRDY, 16, 1);
> > > > +/* Monitor Overflow flag */
> > > > +FIELD(FLEXCOMM_I2C_STAT, MONOV, 17, 1);
> > > > +/* Monitor Active flag */
> > > > +FIELD(FLEXCOMM_I2C_STAT, MONACTIVE, 18, 1);
> > > > +/* Monitor Idle flag */
> > > > +FIELD(FLEXCOMM_I2C_STAT, MONIDLE, 19, 1);
> > > > +/* Event Time-out Interrupt flag */
> > > > +FIELD(FLEXCOMM_I2C_STAT, EVENTTIMEOUT, 24, 1);
> > > > +/* SCL Time-out Interrupt flag */
> > > > +FIELD(FLEXCOMM_I2C_STAT, SCLTIMEOUT, 25, 1);
> > > > +
> > > > +/* Interrupt Enable Set Register */
> > > > +REG32(FLEXCOMM_I2C_INTENSET, 2056);
> > > > +/* Master Pending interrupt Enable */
> > > > +FIELD(FLEXCOMM_I2C_INTENSET, MSTPENDINGEN, 0, 1);
> > > > +/* Master Arbitration Loss interrupt Enable */
> > > > +FIELD(FLEXCOMM_I2C_INTENSET, MSTARBLOSSEN, 4, 1);
> > > > +/* Master Start/Stop Error interrupt Enable */
> > > > +FIELD(FLEXCOMM_I2C_INTENSET, MSTSTSTPERREN, 6, 1);
> > > > +/* Slave Pending interrupt Enable */
> > > > +FIELD(FLEXCOMM_I2C_INTENSET, SLVPENDINGEN, 8, 1);
> > > > +/* Slave Not Stretching interrupt Enable */
> > > > +FIELD(FLEXCOMM_I2C_INTENSET, SLVNOTSTREN, 11, 1);
> > > > +/* Slave Deselect interrupt Enable */
> > > > +FIELD(FLEXCOMM_I2C_INTENSET, SLVDESELEN, 15, 1);
> > > > +/* Monitor data Ready interrupt Enable */
> > > > +FIELD(FLEXCOMM_I2C_INTENSET, MONRDYEN, 16, 1);
> > > > +/* Monitor Overrun interrupt Enable */
> > > > +FIELD(FLEXCOMM_I2C_INTENSET, MONOVEN, 17, 1);
> > > > +/* Monitor Idle interrupt Enable */
> > > > +FIELD(FLEXCOMM_I2C_INTENSET, MONIDLEEN, 19, 1);
> > > > +/* Event Time-out interrupt Enable */
> > > > +FIELD(FLEXCOMM_I2C_INTENSET, EVENTTIMEOUTEN, 24, 1);
> > > > +/* SCL Time-out interrupt Enable */
> > > > +FIELD(FLEXCOMM_I2C_INTENSET, SCLTIMEOUTEN, 25, 1);
> > > > +
> > > > +/* Interrupt Enable Clear Register */
> > > > +REG32(FLEXCOMM_I2C_INTENCLR, 2060);
> > > > +/* Master Pending interrupt clear */
> > > > +FIELD(FLEXCOMM_I2C_INTENCLR, MSTPENDINGCLR, 0, 1);
> > > > +/* Master Arbitration Loss interrupt clear */
> > > > +FIELD(FLEXCOMM_I2C_INTENCLR, MSTARBLOSSCLR, 4, 1);
> > > > +/* Master Start/Stop Error interrupt clear */
> > > > +FIELD(FLEXCOMM_I2C_INTENCLR, MSTSTSTPERRCLR, 6, 1);
> > > > +/* Slave Pending interrupt clear */
> > > > +FIELD(FLEXCOMM_I2C_INTENCLR, SLVPENDINGCLR, 8, 1);
> > > > +/* Slave Not Stretching interrupt clear */
> > > > +FIELD(FLEXCOMM_I2C_INTENCLR, SLVNOTSTRCLR, 11, 1);
> > > > +/* Slave Deselect interrupt clear */
> > > > +FIELD(FLEXCOMM_I2C_INTENCLR, SLVDESELCLR, 15, 1);
> > > > +/* Monitor data Ready interrupt clear */
> > > > +FIELD(FLEXCOMM_I2C_INTENCLR, MONRDYCLR, 16, 1);
> > > > +/* Monitor Overrun interrupt clear */
> > > > +FIELD(FLEXCOMM_I2C_INTENCLR, MONOVCLR, 17, 1);
> > > > +/* Monitor Idle interrupt clear */
> > > > +FIELD(FLEXCOMM_I2C_INTENCLR, MONIDLECLR, 19, 1);
> > > > +/* Event time-out interrupt clear */
> > > > +FIELD(FLEXCOMM_I2C_INTENCLR, EVENTTIMEOUTCLR, 24, 1);
> > > > +/* SCL time-out interrupt clear */
> > > > +FIELD(FLEXCOMM_I2C_INTENCLR, SCLTIMEOUTCLR, 25, 1);
> > > > +
> > > > +/* Time-out Register */
> > > > +REG32(FLEXCOMM_I2C_TIMEOUT, 2064);
> > > > +/* Time-out time value, the bottom 4 bits */
> > > > +FIELD(FLEXCOMM_I2C_TIMEOUT, TOMIN, 0, 4);
> > > > +/* Time-out time value */
> > > > +FIELD(FLEXCOMM_I2C_TIMEOUT, TO, 4, 12);
> > > > +
> > > > +/* Clock Divider Register */
> > > > +REG32(FLEXCOMM_I2C_CLKDIV, 2068);
> > > > +/* Divider Value */
> > > > +FIELD(FLEXCOMM_I2C_CLKDIV, DIVVAL, 0, 16);
> > > > +
> > > > +/* Interrupt Status Register */
> > > > +REG32(FLEXCOMM_I2C_INTSTAT, 2072);
> > > > +/* Master Pending */
> > > > +FIELD(FLEXCOMM_I2C_INTSTAT, MSTPENDING, 0, 1);
> > > > +/* Master Arbitration Loss flag */
> > > > +FIELD(FLEXCOMM_I2C_INTSTAT, MSTARBLOSS, 4, 1);
> > > > +/* Master Start/Stop Error flag */
> > > > +FIELD(FLEXCOMM_I2C_INTSTAT, MSTSTSTPERR, 6, 1);
> > > > +/* Slave Pending */
> > > > +FIELD(FLEXCOMM_I2C_INTSTAT, SLVPENDING, 8, 1);
> > > > +/* Slave Not Stretching status */
> > > > +FIELD(FLEXCOMM_I2C_INTSTAT, SLVNOTSTR, 11, 1);
> > > > +/* Slave Deselected flag */
> > > > +FIELD(FLEXCOMM_I2C_INTSTAT, SLVDESEL, 15, 1);
> > > > +/* Monitor Ready */
> > > > +FIELD(FLEXCOMM_I2C_INTSTAT, MONRDY, 16, 1);
> > > > +/* Monitor Overflow flag */
> > > > +FIELD(FLEXCOMM_I2C_INTSTAT, MONOV, 17, 1);
> > > > +/* Monitor Idle flag */
> > > > +FIELD(FLEXCOMM_I2C_INTSTAT, MONIDLE, 19, 1);
> > > > +/* Event Time-out Interrupt flag */
> > > > +FIELD(FLEXCOMM_I2C_INTSTAT, EVENTTIMEOUT, 24, 1);
> > > > +/* SCL Time-out Interrupt flag */
> > > > +FIELD(FLEXCOMM_I2C_INTSTAT, SCLTIMEOUT, 25, 1);
> > > > +
> > > > +/* Master Control Register */
> > > > +REG32(FLEXCOMM_I2C_MSTCTL, 2080);
> > > > +/* Master Continue(write-only) */
> > > > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTCONTINUE, 0, 1);
> > > > +/* Master Start control(write-only) */
> > > > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTART, 1, 1);
> > > > +/* Master Stop control(write-only) */
> > > > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTOP, 2, 1);
> > > > +/* Master DMA enable */
> > > > +FIELD(FLEXCOMM_I2C_MSTCTL, MSTDMA, 3, 1);
> > > > +
> > > > +/* Master Timing Register */
> > > > +REG32(FLEXCOMM_I2C_MSTTIME, 2084);
> > > > +/* Master SCL Low time */
> > > > +FIELD(FLEXCOMM_I2C_MSTTIME, MSTSCLLOW, 0, 3);
> > > > +/* Master SCL High time */
> > > > +FIELD(FLEXCOMM_I2C_MSTTIME, MSTSCLHIGH, 4, 3);
> > > > +
> > > > +/* Master Data Register */
> > > > +REG32(FLEXCOMM_I2C_MSTDAT, 2088);
> > > > +/* Master function data register */
> > > > +FIELD(FLEXCOMM_I2C_MSTDAT, DATA, 0, 8);
> > > > +
> > > > +/* Slave Control Register */
> > > > +REG32(FLEXCOMM_I2C_SLVCTL, 2112);
> > > > +/* Slave Continue */
> > > > +FIELD(FLEXCOMM_I2C_SLVCTL, SLVCONTINUE, 0, 1);
> > > > +/* Slave NACK */
> > > > +FIELD(FLEXCOMM_I2C_SLVCTL, SLVNACK, 1, 1);
> > > > +/* Slave DMA enable */
> > > > +FIELD(FLEXCOMM_I2C_SLVCTL, SLVDMA, 3, 1);
> > > > +/* Automatic Acknowledge */
> > > > +FIELD(FLEXCOMM_I2C_SLVCTL, AUTOACK, 8, 1);
> > > > +/* Automatic Match Read */
> > > > +FIELD(FLEXCOMM_I2C_SLVCTL, AUTOMATCHREAD, 9, 1);
> > > > +
> > > > +/* Slave Data Register */
> > > > +REG32(FLEXCOMM_I2C_SLVDAT, 2116);
> > > > +/* Slave function data register */
> > > > +FIELD(FLEXCOMM_I2C_SLVDAT, DATA, 0, 8);
> > > > +
> > > > +/* Slave Address Register */
> > > > +REG32(FLEXCOMM_I2C_SLVADR0, 2120);
> > > > +/* Slave Address n Disable */
> > > > +FIELD(FLEXCOMM_I2C_SLVADR0, SADISABLE, 0, 1);
> > > > +/* Slave Address. */
> > > > +FIELD(FLEXCOMM_I2C_SLVADR0, SLVADR, 1, 7);
> > > > +/* Automatic NACK operation */
> > > > +FIELD(FLEXCOMM_I2C_SLVADR0, AUTONACK, 15, 1);
> > > > +
> > > > +/* Slave Address Register */
> > > > +REG32(FLEXCOMM_I2C_SLVADR1, 2124);
> > > > +/* Slave Address n Disable */
> > > > +FIELD(FLEXCOMM_I2C_SLVADR1, SADISABLE, 0, 1);
> > > > +/* Slave Address. */
> > > > +FIELD(FLEXCOMM_I2C_SLVADR1, SLVADR, 1, 7);
> > > > +/* Automatic NACK operation */
> > > > +FIELD(FLEXCOMM_I2C_SLVADR1, AUTONACK, 15, 1);
> > > > +
> > > > +/* Slave Address Register */
> > > > +REG32(FLEXCOMM_I2C_SLVADR2, 2128);
> > > > +/* Slave Address n Disable */
> > > > +FIELD(FLEXCOMM_I2C_SLVADR2, SADISABLE, 0, 1);
> > > > +/* Slave Address. */
> > > > +FIELD(FLEXCOMM_I2C_SLVADR2, SLVADR, 1, 7);
> > > > +/* Automatic NACK operation */
> > > > +FIELD(FLEXCOMM_I2C_SLVADR2, AUTONACK, 15, 1);
> > > > +
> > > > +/* Slave Address Register */
> > > > +REG32(FLEXCOMM_I2C_SLVADR3, 2132);
> > > > +/* Slave Address n Disable */
> > > > +FIELD(FLEXCOMM_I2C_SLVADR3, SADISABLE, 0, 1);
> > > > +/* Slave Address. */
> > > > +FIELD(FLEXCOMM_I2C_SLVADR3, SLVADR, 1, 7);
> > > > +/* Automatic NACK operation */
> > > > +FIELD(FLEXCOMM_I2C_SLVADR3, AUTONACK, 15, 1);
> > > > +
> > > > +/* Slave Qualification for Address 0 Register */
> > > > +REG32(FLEXCOMM_I2C_SLVQUAL0, 2136);
> > > > +/* Qualify mode for slave address 0 */
> > > > +FIELD(FLEXCOMM_I2C_SLVQUAL0, QUALMODE0, 0, 1);
> > > > +/* Slave address Qualifier for address 0 */
> > > > +FIELD(FLEXCOMM_I2C_SLVQUAL0, SLVQUAL0, 1, 7);
> > > > +
> > > > +/* Monitor Receiver Data Register */
> > > > +REG32(FLEXCOMM_I2C_MONRXDAT, 2176);
> > > > +/* Monitor function Receiver Data */
> > > > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONRXDAT, 0, 8);
> > > > +/* Monitor Received Start */
> > > > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONSTART, 8, 1);
> > > > +/* Monitor Received Repeated Start */
> > > > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONRESTART, 9, 1);
> > > > +/* Monitor Received NACK */
> > > > +FIELD(FLEXCOMM_I2C_MONRXDAT, MONNACK, 10, 1);
> > > > +
> > > > +/* Peripheral Identification Register */
> > > > +REG32(FLEXCOMM_I2C_ID, 4092);
> > > > +/* Aperture */
> > > > +FIELD(FLEXCOMM_I2C_ID, APERTURE, 0, 8);
> > > > +/* Minor revision of module implementation */
> > > > +FIELD(FLEXCOMM_I2C_ID, MINOR_REV, 8, 4);
> > > > +/* Major revision of module implementation */
> > > > +FIELD(FLEXCOMM_I2C_ID, MAJOR_REV, 12, 4);
> > > > +/* Module identifier for the selected function */
> > > > +FIELD(FLEXCOMM_I2C_ID, ID, 16, 16);
> > > > +
> > >
> > > Are any of the below enums even used? Or for that matter, most of the
> > > above fields?
> > >
> > > If these are just here for documentation, I would prefer English text;
> > > it's more dense and easier to read. It's very difficult to tie all this
> > > together into a cohesive view of the device registers.
> > >
> >
> > Since this is autogenerated for the full set of the device registers
> > there will be fields that are not used either because the emulation is
> > incomplete or because they don't have effect for emulation.
> >
> > I think it is still valuable to have this generated automatically
> > instead of doing it by hand.
> >
> > Would adding options to only generate certain definitions help? As
> > long as we are reasonable with the granularity (e.g. register level) I
> > think it could trim *most* of the unused generated code without
> > becoming too tedious on how to instruct the tool to generate the code.
> > However, I expect to still have *some* unused generated code.
>
> Generally it's frowned upon to have a ton of extra stuff that's not
> used. I would think some is ok, like defining bits in registers that
> aren't used yet, but I have no idea how all the enums below here
> actually tie into anything. I'm guessing these are just bitmasks into
> registers, but really, it's a lot easier to read if you have something
> like:
>
> /*
> * The I2C Master function enable. When disabled, the Master
> * configuration settings are not changed, but the Master function is
> * internally reset.
> */
> #define FLEXCOMM_I2C_CFG_MSTEN (1 << 4)
>
> and them have them grouped together with the register they belong to. I
> don't know how you would even use these enums. AFAICT, none of them are
> used.
>
Ah, I see. You are right, it is not useful for 1 bit fields, I'll fix
the generator to skip these for bits.
The purpose of the enums is for the case where a certain field can
have more than two options. To give an example that is used:
typedef enum {
FLEXCOMM_I2C_STAT_MSTSTATE_IDLE = 0,
FLEXCOMM_I2C_STAT_MSTSTATE_RECEIVE_READY = 1,
FLEXCOMM_I2C_STAT_MSTSTATE_TRANSMIT_READY = 2,
FLEXCOMM_I2C_STAT_MSTSTATE_NACK_ADDRESS = 3,
FLEXCOMM_I2C_STAT_MSTSTATE_NACK_DATA = 4,
} FLEXCOMM_I2C_STAT_MSTSTATE_Enum;
> And the whole idea of this is to make the code more readable. So if
> you define these things, you should use them. Look around through the
> code of other devices to get a feel of how things are done.
>
Thanks for the review and sorry for the rough edges, I should have
caught the bits enums thing.
> -corey
>
> >
> >
> > > The .c file itself seems ok.
> > >
> > > -corey
> > >
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * Disabled. The I2C Master function is disabled. When disabled, the Master
> > > > + * configuration settings are not changed, but the Master function is
> > > > + * internally reset.
> > > > + */
> > > > + FLEXCOMM_I2C_CFG_MSTEN_DISABLED = 0,
> > > > + /* Enabled. The I2C Master function is enabled. */
> > > > + FLEXCOMM_I2C_CFG_MSTEN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_CFG_MSTEN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * Disabled. The I2C slave function is disabled. When disabled, the Slave
> > > > + * configuration settings are not changed, but the Slave function is
> > > > + * internally reset.
> > > > + */
> > > > + FLEXCOMM_I2C_CFG_SLVEN_DISABLED = 0,
> > > > + /* Enabled. The I2C slave function is enabled. */
> > > > + FLEXCOMM_I2C_CFG_SLVEN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_CFG_SLVEN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * Disabled. The I2C Monitor function is disabled. When disabled, the
> > > > + * Monitor function configuration settings are not changed, but the Monitor
> > > > + * function is internally reset.
> > > > + */
> > > > + FLEXCOMM_I2C_CFG_MONEN_DISABLED = 0,
> > > > + /* Enabled. The I2C Monitor function is enabled. */
> > > > + FLEXCOMM_I2C_CFG_MONEN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_CFG_MONEN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * Disabled. The time-out function is disabled. When disabled, the time-out
> > > > + * function is internally reset.
> > > > + */
> > > > + FLEXCOMM_I2C_CFG_TIMEOUTEN_DISABLED = 0,
> > > > + /*
> > > > + * Enabled. The time-out function is enabled. Both types of time-out flags
> > > > + * will be generated and will cause interrupts if those flags are enabled.
> > > > + * Typically, only one time-out flag will be used in a system.
> > > > + */
> > > > + FLEXCOMM_I2C_CFG_TIMEOUTEN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_CFG_TIMEOUTEN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * Disabled. The Monitor function will not perform clock stretching.
> > > > + * Software or DMA may not always be able to read data provided by the
> > > > + * Monitor function before it (the data) is overwritten. This mode can be
> > > > + * used when non-invasive monitoring is critical.
> > > > + */
> > > > + FLEXCOMM_I2C_CFG_MONCLKSTR_DISABLED = 0,
> > > > + /*
> > > > + * Enabled. The Monitor function will perform clock stretching, to ensure
> > > > + * that the software or DMA can read all incoming data supplied by the
> > > > + * Monitor function.
> > > > + */
> > > > + FLEXCOMM_I2C_CFG_MONCLKSTR_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_CFG_MONCLKSTR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Fast mode Plus enable */
> > > > + FLEXCOMM_I2C_CFG_HSCAPABLE_FAST_MODE_PLUS = 0,
> > > > + /* High Speed mode enable */
> > > > + FLEXCOMM_I2C_CFG_HSCAPABLE_HIGH_SPEED = 1,
> > > > +} FLEXCOMM_I2C_CFG_HSCAPABLE_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * In progress. Communication is in progress and the Master function is
> > > > + * busy and cannot currently accept a command.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_MSTPENDING_IN_PROGRESS = 0,
> > > > + /*
> > > > + * Pending. The Master function needs software service or is in the idle
> > > > + * state. If the master is not in the idle state, then the master is
> > > > + * waiting to receive or transmit data, or is waiting for the NACK bit.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_MSTPENDING_PENDING = 1,
> > > > +} FLEXCOMM_I2C_STAT_MSTPENDING_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * Idle. The Master function is available to be used for a new transaction.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_MSTSTATE_IDLE = 0,
> > > > + /*
> > > > + * Receive ready. Received data is available (in Master Receiver mode).
> > > > + * Address plus Read was previously sent and Acknowledged by a slave.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_MSTSTATE_RECEIVE_READY = 1,
> > > > + /*
> > > > + * Transmit ready. Data can be transmitted (in Master Transmitter mode).
> > > > + * Address plus Write was previously sent and Acknowledged by a slave.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_MSTSTATE_TRANSMIT_READY = 2,
> > > > + /* NACK Address. Slave NACKed address. */
> > > > + FLEXCOMM_I2C_STAT_MSTSTATE_NACK_ADDRESS = 3,
> > > > + /* NACK Data. Slave NACKed transmitted data. */
> > > > + FLEXCOMM_I2C_STAT_MSTSTATE_NACK_DATA = 4,
> > > > +} FLEXCOMM_I2C_STAT_MSTSTATE_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No Arbitration Loss has occurred */
> > > > + FLEXCOMM_I2C_STAT_MSTARBLOSS_NO_LOSS = 0,
> > > > + /*
> > > > + * Arbitration loss. The Master function has experienced an Arbitration
> > > > + * Loss. At this point, the Master function has already stopped driving the
> > > > + * bus and has gone into an idle state. Software can respond by doing
> > > > + * nothing, or by sending a Start (to attempt to gain control of the bus
> > > > + * when the bus next becomes idle).
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_MSTARBLOSS_ARBITRATION_LOSS = 1,
> > > > +} FLEXCOMM_I2C_STAT_MSTARBLOSS_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No Start/Stop Error has occurred. */
> > > > + FLEXCOMM_I2C_STAT_MSTSTSTPERR_NO_ERROR = 0,
> > > > + /*
> > > > + * The Master function has experienced a Start/Stop Error. A Start or Stop
> > > > + * was detected at a time when Start or Stop is not allowed by the I2C
> > > > + * specification. The Master interface has stopped driving the bus and gone
> > > > + * into an idle state; no action is required. A request for a Start could
> > > > + * be made, or software could attempt to make sure that the bus has not
> > > > + * stalled.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_MSTSTSTPERR_ERROR = 1,
> > > > +} FLEXCOMM_I2C_STAT_MSTSTSTPERR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * In progress. The Slave function does not currently need software
> > > > + * service.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_SLVPENDING_IN_PROGRESS = 0,
> > > > + /*
> > > > + * Pending. The Slave function needs software service. Information about
> > > > + * what is needed is in the Slave state field (SLVSTATE).
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_SLVPENDING_PENDING = 1,
> > > > +} FLEXCOMM_I2C_STAT_SLVPENDING_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * Slave address. Address plus R/W received. At least one of the 4 slave
> > > > + * addresses has been matched by hardware.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_ADDRESS = 0,
> > > > + /* Slave receive. Received data is available (in Slave Receiver mode). */
> > > > + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_RECEIVE = 1,
> > > > + /* Slave transmit. Data can be transmitted (in Slave Transmitter mode). */
> > > > + FLEXCOMM_I2C_STAT_SLVSTATE_SLAVE_TRANSMIT = 2,
> > > > +} FLEXCOMM_I2C_STAT_SLVSTATE_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * Stretching. The slave function is currently stretching the I2C bus
> > > > + * clock. Deep-Sleepmode cannot be entered at this time.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_SLVNOTSTR_STRETCHING = 0,
> > > > + /*
> > > > + * Not stretching. The slave function is not currently stretching the I2C
> > > > + * bus clock. Deep-sleep mode can be entered at this time.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_SLVNOTSTR_NOT_STRETCHING = 1,
> > > > +} FLEXCOMM_I2C_STAT_SLVNOTSTR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Address 0. Slave address 0 was matched. */
> > > > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS0 = 0,
> > > > + /* Address 1. Slave address 1 was matched. */
> > > > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS1 = 1,
> > > > + /* Address 2. Slave address 2 was matched. */
> > > > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS2 = 2,
> > > > + /* Address 3. Slave address 3 was matched. */
> > > > + FLEXCOMM_I2C_STAT_SLVIDX_ADDRESS3 = 3,
> > > > +} FLEXCOMM_I2C_STAT_SLVIDX_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Not selected. The Slave function is not currently selected. */
> > > > + FLEXCOMM_I2C_STAT_SLVSEL_NOT_SELECTED = 0,
> > > > + /* Selected. The Slave function is currently selected. */
> > > > + FLEXCOMM_I2C_STAT_SLVSEL_SELECTED = 1,
> > > > +} FLEXCOMM_I2C_STAT_SLVSEL_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * Not deselected. The Slave function has not become deselected. This does
> > > > + * not mean that the Slave is currently selected. That information is in
> > > > + * the SLVSEL flag.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_SLVDESEL_NOT_DESELECTED = 0,
> > > > + /*
> > > > + * Deselected. The Slave function has become deselected. This is
> > > > + * specifically caused by the SLVSEL flag changing from 1 to 0. See SLVSEL
> > > > + * for details about when that event occurs.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_SLVDESEL_DESELECTED = 1,
> > > > +} FLEXCOMM_I2C_STAT_SLVDESEL_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No data. The Monitor function does not currently have data available. */
> > > > + FLEXCOMM_I2C_STAT_MONRDY_NO_DATA = 0,
> > > > + /* Data waiting. The Monitor function has data waiting to be read. */
> > > > + FLEXCOMM_I2C_STAT_MONRDY_DATA_WAITING = 1,
> > > > +} FLEXCOMM_I2C_STAT_MONRDY_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No overrun. Monitor data has not overrun. */
> > > > + FLEXCOMM_I2C_STAT_MONOV_NO_OVERRUN = 0,
> > > > + /*
> > > > + * Overrun. A Monitor data overrun has occurred. An overrun can only happen
> > > > + * when Monitor clock stretching not enabled via the CFG[MONCLKSTR] bit.
> > > > + * Writing 1 to MONOV bit clears the MONOV flag.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_MONOV_OVERRUN = 1,
> > > > +} FLEXCOMM_I2C_STAT_MONOV_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Inactive. The Monitor function considers the I2C bus to be inactive. */
> > > > + FLEXCOMM_I2C_STAT_MONACTIVE_INACTIVE = 0,
> > > > + /* Active. The Monitor function considers the I2C bus to be active. */
> > > > + FLEXCOMM_I2C_STAT_MONACTIVE_ACTIVE = 1,
> > > > +} FLEXCOMM_I2C_STAT_MONACTIVE_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * Not idle. The I2C bus is not idle, or MONIDLE flag has been cleared by
> > > > + * software.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_MONIDLE_NOT_IDLE = 0,
> > > > + /*
> > > > + * Idle. The I2C bus has gone idle at least once, since the last time
> > > > + * MONIDLE flag was cleared by software.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_MONIDLE_IDLE = 1,
> > > > +} FLEXCOMM_I2C_STAT_MONIDLE_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No time-out. I2C bus events have not caused a time-out. */
> > > > + FLEXCOMM_I2C_STAT_EVENTTIMEOUT_NO_TIMEOUT = 0,
> > > > + /*
> > > > + * Event time-out. The time between I2C bus events has been longer than the
> > > > + * time specified by the TIMEOUT register.
> > > > + */
> > > > + FLEXCOMM_I2C_STAT_EVENTTIMEOUT_EVEN_TIMEOUT = 1,
> > > > +} FLEXCOMM_I2C_STAT_EVENTTIMEOUT_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No time-out. SCL low time has not caused a time-out. */
> > > > + FLEXCOMM_I2C_STAT_SCLTIMEOUT_NO_TIMEOUT = 0,
> > > > + /* Time-out. SCL low time has caused a time-out. */
> > > > + FLEXCOMM_I2C_STAT_SCLTIMEOUT_TIMEOUT = 1,
> > > > +} FLEXCOMM_I2C_STAT_SCLTIMEOUT_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Disabled. The MstPending interrupt is disabled. */
> > > > + FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_DISABLED = 0,
> > > > + /* Enabled. The MstPending interrupt is enabled. */
> > > > + FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_INTENSET_MSTPENDINGEN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Disabled. The MstArbLoss interrupt is disabled. */
> > > > + FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_DISABLED = 0,
> > > > + /* Enabled. The MstArbLoss interrupt is enabled. */
> > > > + FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_INTENSET_MSTARBLOSSEN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Disabled. The MstStStpErr interrupt is disabled. */
> > > > + FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_DISABLED = 0,
> > > > + /* Enabled. The MstStStpErr interrupt is enabled. */
> > > > + FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_INTENSET_MSTSTSTPERREN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Disabled. The SlvPending interrupt is disabled. */
> > > > + FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_DISABLED = 0,
> > > > + /* Enabled. The SlvPending interrupt is enabled. */
> > > > + FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_INTENSET_SLVPENDINGEN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Disabled. The SlvNotStr interrupt is disabled. */
> > > > + FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_DISABLED = 0,
> > > > + /* Enabled. The SlvNotStr interrupt is enabled. */
> > > > + FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_INTENSET_SLVNOTSTREN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Disabled. The SlvDeSel interrupt is disabled. */
> > > > + FLEXCOMM_I2C_INTENSET_SLVDESELEN_DISABLED = 0,
> > > > + /* Enabled. The SlvDeSel interrupt is enabled. */
> > > > + FLEXCOMM_I2C_INTENSET_SLVDESELEN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_INTENSET_SLVDESELEN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Disabled. The MonRdy interrupt is disabled. */
> > > > + FLEXCOMM_I2C_INTENSET_MONRDYEN_DISABLED = 0,
> > > > + /* Enabled. The MonRdy interrupt is enabled. */
> > > > + FLEXCOMM_I2C_INTENSET_MONRDYEN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_INTENSET_MONRDYEN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Disabled. The MonOv interrupt is disabled. */
> > > > + FLEXCOMM_I2C_INTENSET_MONOVEN_DISABLED = 0,
> > > > + /* Enabled. The MonOv interrupt is enabled. */
> > > > + FLEXCOMM_I2C_INTENSET_MONOVEN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_INTENSET_MONOVEN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Disabled. The MonIdle interrupt is disabled. */
> > > > + FLEXCOMM_I2C_INTENSET_MONIDLEEN_DISABLED = 0,
> > > > + /* Enabled. The MonIdle interrupt is enabled. */
> > > > + FLEXCOMM_I2C_INTENSET_MONIDLEEN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_INTENSET_MONIDLEEN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Disabled. The Event time-out interrupt is disabled. */
> > > > + FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_DISABLED = 0,
> > > > + /* Enabled. The Event time-out interrupt is enabled. */
> > > > + FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_INTENSET_EVENTTIMEOUTEN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Disabled. The SCL time-out interrupt is disabled. */
> > > > + FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_DISABLED = 0,
> > > > + /* Enabled. The SCL time-out interrupt is enabled. */
> > > > + FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_INTENSET_SCLTIMEOUTEN_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect on interrupt */
> > > > + FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_NO_EFFECT = 0,
> > > > + /* Clears the interrupt bit in INTENSET register */
> > > > + FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_CLEAR_MSTPENDING = 1,
> > > > +} FLEXCOMM_I2C_INTENCLR_MSTPENDINGCLR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect on interrupt */
> > > > + FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_NO_EFFECT = 0,
> > > > + /* Clears the interrupt bit in INTENSET register */
> > > > + FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_CLEAR_MSTARBLOSS = 1,
> > > > +} FLEXCOMM_I2C_INTENCLR_MSTARBLOSSCLR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect on interrupt */
> > > > + FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_NO_EFFECT = 0,
> > > > + /* Clears the interrupt bit in INTENSET register */
> > > > + FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_CLEAR_MSTSTSTPERR = 1,
> > > > +} FLEXCOMM_I2C_INTENCLR_MSTSTSTPERRCLR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect on interrupt */
> > > > + FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_NO_EFFECT = 0,
> > > > + /* Clears the interrupt bit in INTENSET register */
> > > > + FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_CLEAR_SLVPENDING = 1,
> > > > +} FLEXCOMM_I2C_INTENCLR_SLVPENDINGCLR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect on interrupt */
> > > > + FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_NO_EFFECT = 0,
> > > > + /* Clears the interrupt bit in INTENSET register */
> > > > + FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_CLEAR_SLVNOTSTR = 1,
> > > > +} FLEXCOMM_I2C_INTENCLR_SLVNOTSTRCLR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect on interrupt */
> > > > + FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_NO_EFFECT = 0,
> > > > + /* Clears the interrupt bit in INTENSET register */
> > > > + FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_CLEAR_SLVDESEL = 1,
> > > > +} FLEXCOMM_I2C_INTENCLR_SLVDESELCLR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect on interrupt */
> > > > + FLEXCOMM_I2C_INTENCLR_MONRDYCLR_NO_EFFECT = 0,
> > > > + /* Clears the interrupt bit in INTENSET register */
> > > > + FLEXCOMM_I2C_INTENCLR_MONRDYCLR_CLEAR_MONRDY = 1,
> > > > +} FLEXCOMM_I2C_INTENCLR_MONRDYCLR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect on interrupt */
> > > > + FLEXCOMM_I2C_INTENCLR_MONOVCLR_NO_EFFECT = 0,
> > > > + /* Clears the interrupt bit in INTENSET register */
> > > > + FLEXCOMM_I2C_INTENCLR_MONOVCLR_CLEAR_MONOV = 1,
> > > > +} FLEXCOMM_I2C_INTENCLR_MONOVCLR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect on interrupt */
> > > > + FLEXCOMM_I2C_INTENCLR_MONIDLECLR_NO_EFFECT = 0,
> > > > + /* Clears the interrupt bit in INTENSET register */
> > > > + FLEXCOMM_I2C_INTENCLR_MONIDLECLR_CLEAR_MONIDLE = 1,
> > > > +} FLEXCOMM_I2C_INTENCLR_MONIDLECLR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect on interrupt */
> > > > + FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_NO_EFFECT = 0,
> > > > + /* Clears the interrupt bit in INTENSET register */
> > > > + FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_CLEAR_EVENTTIMEOUT = 1,
> > > > +} FLEXCOMM_I2C_INTENCLR_EVENTTIMEOUTCLR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect on interrupt */
> > > > + FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_NO_EFFECT = 0,
> > > > + /* Clears the interrupt bit in INTENSET register */
> > > > + FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_CLEAR_SCLTIMEOUT = 1,
> > > > +} FLEXCOMM_I2C_INTENCLR_SCLTIMEOUTCLR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* A time-out will occur after 16 counts of the I2C function clock. */
> > > > + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT16 = 0,
> > > > + /* A time-out will occur after 32 counts of the I2C function clock. */
> > > > + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT32 = 1,
> > > > + /* A time-out will occur after 65,536 counts of the I2C function clock. */
> > > > + FLEXCOMM_I2C_TIMEOUT_TO_TIMEOUT65K = 4095,
> > > > +} FLEXCOMM_I2C_TIMEOUT_TO_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* FCLK is used directly by the I2C. */
> > > > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKUNDIVIDED = 0,
> > > > + /* FCLK is divided by 2 before being used by the I2C. */
> > > > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV2 = 1,
> > > > + /* FCLK is divided by 3 before being used by the I2C. */
> > > > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV3 = 2,
> > > > + /* FCLK is divided by 65,536 before being used by the I2C. */
> > > > + FLEXCOMM_I2C_CLKDIV_DIVVAL_FCLKDIV65K = 65535,
> > > > +} FLEXCOMM_I2C_CLKDIV_DIVVAL_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Not active */
> > > > + FLEXCOMM_I2C_INTSTAT_MSTPENDING_MSTPENDING_ISNOTACTIVE = 0,
> > > > + /* Active */
> > > > + FLEXCOMM_I2C_INTSTAT_MSTPENDING_MSTPENDING_ISACTIVE = 1,
> > > > +} FLEXCOMM_I2C_INTSTAT_MSTPENDING_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Not active */
> > > > + FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_MSTARBLOSS_ISNOTACTIVE = 0,
> > > > + /* Active */
> > > > + FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_MSTARBLOSS_ISACTIVE = 1,
> > > > +} FLEXCOMM_I2C_INTSTAT_MSTARBLOSS_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Not active */
> > > > + FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_MSTSTSTPERR_ISNOTACTIVE = 0,
> > > > + /* Active */
> > > > + FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_MSTSTSTPERR_ISACTIVE = 1,
> > > > +} FLEXCOMM_I2C_INTSTAT_MSTSTSTPERR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Not active */
> > > > + FLEXCOMM_I2C_INTSTAT_SLVPENDING_SLVPENDING_ISNOTACTIVE = 0,
> > > > + /* Active */
> > > > + FLEXCOMM_I2C_INTSTAT_SLVPENDING_SLVPENDING_ISACTIVE = 1,
> > > > +} FLEXCOMM_I2C_INTSTAT_SLVPENDING_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Not active */
> > > > + FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_SLVNOTSTR_ISNOTACTIVE = 0,
> > > > + /* Active */
> > > > + FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_SLVNOTSTR_ISACTIVE = 1,
> > > > +} FLEXCOMM_I2C_INTSTAT_SLVNOTSTR_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Not active */
> > > > + FLEXCOMM_I2C_INTSTAT_SLVDESEL_SLVDESEL_ISNOTACTIVE = 0,
> > > > + /* Active */
> > > > + FLEXCOMM_I2C_INTSTAT_SLVDESEL_SLVDESEL_ISACTIVE = 1,
> > > > +} FLEXCOMM_I2C_INTSTAT_SLVDESEL_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Not active */
> > > > + FLEXCOMM_I2C_INTSTAT_MONRDY_MONRDY_ISNOTACTIVE = 0,
> > > > + /* Active */
> > > > + FLEXCOMM_I2C_INTSTAT_MONRDY_MONRDY_ISACTIVE = 1,
> > > > +} FLEXCOMM_I2C_INTSTAT_MONRDY_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Not active */
> > > > + FLEXCOMM_I2C_INTSTAT_MONOV_MONOV_ISNOTACTIVE = 0,
> > > > + /* Active */
> > > > + FLEXCOMM_I2C_INTSTAT_MONOV_MONOV_ISACTIVE = 1,
> > > > +} FLEXCOMM_I2C_INTSTAT_MONOV_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Not active */
> > > > + FLEXCOMM_I2C_INTSTAT_MONIDLE_MONIDLE_ISNOTACTIVE = 0,
> > > > + /* Active */
> > > > + FLEXCOMM_I2C_INTSTAT_MONIDLE_MONIDLE_ISACTIVE = 1,
> > > > +} FLEXCOMM_I2C_INTSTAT_MONIDLE_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Not active */
> > > > + FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_EVENTTIMEOUT_ISNOTACTIVE = 0,
> > > > + /* Active */
> > > > + FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_EVENTTIMEOUT_ISACTIVE = 1,
> > > > +} FLEXCOMM_I2C_INTSTAT_EVENTTIMEOUT_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Not active */
> > > > + FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_SCLTIMEOUT_ISNOTACTIVE = 0,
> > > > + /* Active */
> > > > + FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_SCLTIMEOUT_ISACTIVE = 1,
> > > > +} FLEXCOMM_I2C_INTSTAT_SCLTIMEOUT_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect */
> > > > + FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_NO_EFFECT = 0,
> > > > + /*
> > > > + * Continue. Informs the Master function to continue to the next operation.
> > > > + * This action must done after writing transmit data, reading received
> > > > + * data, or any other housekeeping related to the next bus operation.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_CONTINUE = 1,
> > > > +} FLEXCOMM_I2C_MSTCTL_MSTCONTINUE_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect */
> > > > + FLEXCOMM_I2C_MSTCTL_MSTSTART_NO_EFFECT = 0,
> > > > + /*
> > > > + * Start. A Start will be generated on the I2C bus at the next allowed
> > > > + * time.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTCTL_MSTSTART_START = 1,
> > > > +} FLEXCOMM_I2C_MSTCTL_MSTSTART_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect */
> > > > + FLEXCOMM_I2C_MSTCTL_MSTSTOP_NO_EFFECT = 0,
> > > > + /*
> > > > + * Stop. A Stop will be generated on the I2C bus at the next allowed time,
> > > > + * preceded by a NACK to the slave if the master is receiving data from the
> > > > + * slave (in Master Receiver mode).
> > > > + */
> > > > + FLEXCOMM_I2C_MSTCTL_MSTSTOP_STOP = 1,
> > > > +} FLEXCOMM_I2C_MSTCTL_MSTSTOP_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Disable. No DMA requests are generated for master operation. */
> > > > + FLEXCOMM_I2C_MSTCTL_MSTDMA_DISABLED = 0,
> > > > + /*
> > > > + * Enable. A DMA request is generated for I2C master data operations. When
> > > > + * this I2C master is generating Acknowledge bits in Master Receiver mode,
> > > > + * the acknowledge is generated automatically.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTCTL_MSTDMA_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_MSTCTL_MSTDMA_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * 2 clocks. Minimum SCL low time is 2 clocks of the I2C clock pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_2CLOCKS = 0,
> > > > + /*
> > > > + * 3 clocks. Minimum SCL low time is 3 clocks of the I2C clock pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_3CLOCKS = 1,
> > > > + /*
> > > > + * 4 clocks. Minimum SCL low time is 4 clocks of the I2C clock pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_4CLOCKS = 2,
> > > > + /*
> > > > + * 5 clocks. Minimum SCL low time is 5 clocks of the I2C clock pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_5CLOCKS = 3,
> > > > + /*
> > > > + * 6 clocks. Minimum SCL low time is 6 clocks of the I2C clock pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_6CLOCKS = 4,
> > > > + /*
> > > > + * 7 clocks. Minimum SCL low time is 7 clocks of the I2C clock pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_7CLOCKS = 5,
> > > > + /*
> > > > + * 8 clocks. Minimum SCL low time is 8 clocks of the I2C clock pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_8CLOCKS = 6,
> > > > + /*
> > > > + * 9 clocks. Minimum SCL low time is 9 clocks of the I2C clock pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_MSTSCLLOW_9CLOCKS = 7,
> > > > +} FLEXCOMM_I2C_MSTTIME_MSTSCLLOW_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * 2 clocks. Minimum SCL high time is 2 clocks of the I2C clock
> > > > + * pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_2CLOCKS = 0,
> > > > + /*
> > > > + * 3 clocks. Minimum SCL high time is 3 clocks of the I2C clock pre-divider
> > > > + * .
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_3CLOCKS = 1,
> > > > + /*
> > > > + * 4 clocks. Minimum SCL high time is 4 clocks of the I2C clock
> > > > + * pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_4CLOCKS = 2,
> > > > + /*
> > > > + * 5 clocks. Minimum SCL high time is 5 clocks of the I2C clock
> > > > + * pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_5CLOCKS = 3,
> > > > + /*
> > > > + * 6 clocks. Minimum SCL high time is 6 clocks of the I2C clock
> > > > + * pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_6CLOCKS = 4,
> > > > + /*
> > > > + * 7 clocks. Minimum SCL high time is 7 clocks of the I2C clock
> > > > + * pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_7CLOCKS = 5,
> > > > + /*
> > > > + * 8 clocks. Minimum SCL high time is 8 clocks of the I2C clock
> > > > + * pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_8CLOCKS = 6,
> > > > + /*
> > > > + * 9 clocks. Minimum SCL high time is 9 clocks of the I2C clock
> > > > + * pre-divider.
> > > > + */
> > > > + FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_MSTSCLHIGH_9CLOCKS = 7,
> > > > +} FLEXCOMM_I2C_MSTTIME_MSTSCLHIGH_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect */
> > > > + FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_NO_EFFECT = 0,
> > > > + /*
> > > > + * Continue. Informs the Slave function to continue to the next operation,
> > > > + * by clearing the STAT[SLVPENDING] flag. This must be done after writing
> > > > + * transmit data, reading received data, or any other housekeeping related
> > > > + * to the next bus operation. Automatic Operation has different
> > > > + * requirements. SLVCONTINUE should not be set unless SLVPENDING = 1.
> > > > + */
> > > > + FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_CONTINUE = 1,
> > > > +} FLEXCOMM_I2C_SLVCTL_SLVCONTINUE_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* No effect */
> > > > + FLEXCOMM_I2C_SLVCTL_SLVNACK_NO_EFFECT = 0,
> > > > + /*
> > > > + * NACK. Causes the Slave function to NACK the master when the slave is
> > > > + * receiving data from the master (in Slave Receiver mode).
> > > > + */
> > > > + FLEXCOMM_I2C_SLVCTL_SLVNACK_NACK = 1,
> > > > +} FLEXCOMM_I2C_SLVCTL_SLVNACK_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Disabled. No DMA requests are issued for Slave mode operation. */
> > > > + FLEXCOMM_I2C_SLVCTL_SLVDMA_DISABLED = 0,
> > > > + /*
> > > > + * Enabled. DMA requests are issued for I2C slave data transmission and
> > > > + * reception.
> > > > + */
> > > > + FLEXCOMM_I2C_SLVCTL_SLVDMA_ENABLED = 1,
> > > > +} FLEXCOMM_I2C_SLVCTL_SLVDMA_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * Normal, non-automatic operation. If AUTONACK = 0, then a SlvPending
> > > > + * interrupt is generated when a matching address is received. If AUTONACK
> > > > + * = 1, then received addresses are NACKed (ignored).
> > > > + */
> > > > + FLEXCOMM_I2C_SLVCTL_AUTOACK_NORMAL = 0,
> > > > + /*
> > > > + * A header with matching SLVADR0 and matching direction as set by
> > > > + * AUTOMATCHREAD will be ACKed immediately, allowing the master to move on
> > > > + * to the data bytes. If the address matches SLVADR0, but the direction
> > > > + * does not match AUTOMATCHREAD, then the behavior will depend on the
> > > > + * SLVADR0[AUTONACK] bit: if AUTONACK is set, then it will be Nacked; if
> > > > + * AUTONACK is clear, then a SlvPending interrupt is generated.
> > > > + */
> > > > + FLEXCOMM_I2C_SLVCTL_AUTOACK_AUTOMATIC_ACK = 1,
> > > > +} FLEXCOMM_I2C_SLVCTL_AUTOACK_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* In Automatic Mode, the expected next operation is an I2C write. */
> > > > + FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_I2C_WRITE = 0,
> > > > + /* In Automatic Mode, the expected next operation is an I2C read. */
> > > > + FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_I2C_READ = 1,
> > > > +} FLEXCOMM_I2C_SLVCTL_AUTOMATCHREAD_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Enabled. Slave Address n is enabled. */
> > > > + FLEXCOMM_I2C_SLVADR0_SADISABLE_ENABLED = 0,
> > > > + /* Ignored. Slave Address n is ignored. */
> > > > + FLEXCOMM_I2C_SLVADR0_SADISABLE_DISABLED = 1,
> > > > +} FLEXCOMM_I2C_SLVADR0_SADISABLE_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Normal operation, matching I2C addresses are not ignored. */
> > > > + FLEXCOMM_I2C_SLVADR0_AUTONACK_NORMAL = 0,
> > > > + /*
> > > > + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> > > > + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> > > > + * matches the direction.
> > > > + */
> > > > + FLEXCOMM_I2C_SLVADR0_AUTONACK_AUTOMATIC = 1,
> > > > +} FLEXCOMM_I2C_SLVADR0_AUTONACK_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Enabled. Slave Address n is enabled. */
> > > > + FLEXCOMM_I2C_SLVADR1_SADISABLE_ENABLED = 0,
> > > > + /* Ignored. Slave Address n is ignored. */
> > > > + FLEXCOMM_I2C_SLVADR1_SADISABLE_DISABLED = 1,
> > > > +} FLEXCOMM_I2C_SLVADR1_SADISABLE_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Normal operation, matching I2C addresses are not ignored. */
> > > > + FLEXCOMM_I2C_SLVADR1_AUTONACK_NORMAL = 0,
> > > > + /*
> > > > + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> > > > + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> > > > + * matches the direction.
> > > > + */
> > > > + FLEXCOMM_I2C_SLVADR1_AUTONACK_AUTOMATIC = 1,
> > > > +} FLEXCOMM_I2C_SLVADR1_AUTONACK_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Enabled. Slave Address n is enabled. */
> > > > + FLEXCOMM_I2C_SLVADR2_SADISABLE_ENABLED = 0,
> > > > + /* Ignored. Slave Address n is ignored. */
> > > > + FLEXCOMM_I2C_SLVADR2_SADISABLE_DISABLED = 1,
> > > > +} FLEXCOMM_I2C_SLVADR2_SADISABLE_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Normal operation, matching I2C addresses are not ignored. */
> > > > + FLEXCOMM_I2C_SLVADR2_AUTONACK_NORMAL = 0,
> > > > + /*
> > > > + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> > > > + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> > > > + * matches the direction.
> > > > + */
> > > > + FLEXCOMM_I2C_SLVADR2_AUTONACK_AUTOMATIC = 1,
> > > > +} FLEXCOMM_I2C_SLVADR2_AUTONACK_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Enabled. Slave Address n is enabled. */
> > > > + FLEXCOMM_I2C_SLVADR3_SADISABLE_ENABLED = 0,
> > > > + /* Ignored. Slave Address n is ignored. */
> > > > + FLEXCOMM_I2C_SLVADR3_SADISABLE_DISABLED = 1,
> > > > +} FLEXCOMM_I2C_SLVADR3_SADISABLE_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /* Normal operation, matching I2C addresses are not ignored. */
> > > > + FLEXCOMM_I2C_SLVADR3_AUTONACK_NORMAL = 0,
> > > > + /*
> > > > + * Automatic-only mode. All incoming addresses are ignored (NACKed), unless
> > > > + * AUTOACK is set, and the address matches SLVADRn, and AUTOMATCHREAD
> > > > + * matches the direction.
> > > > + */
> > > > + FLEXCOMM_I2C_SLVADR3_AUTONACK_AUTOMATIC = 1,
> > > > +} FLEXCOMM_I2C_SLVADR3_AUTONACK_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * Mask. The SLVQUAL0 field is used as a logical mask for matching address
> > > > + * 0.
> > > > + */
> > > > + FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_MASK = 0,
> > > > + /*
> > > > + * Extend. The SLVQUAL0 field is used to extend address 0 matching in a
> > > > + * range of addresses.
> > > > + */
> > > > + FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_EXTEND = 1,
> > > > +} FLEXCOMM_I2C_SLVQUAL0_QUALMODE0_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * No start detected. The Monitor function has not detected a Start event
> > > > + * on the I2C bus.
> > > > + */
> > > > + FLEXCOMM_I2C_MONRXDAT_MONSTART_NO_START_DETECTED = 0,
> > > > + /*
> > > > + * Start detected. The Monitor function has detected a Start event on the
> > > > + * I2C bus.
> > > > + */
> > > > + FLEXCOMM_I2C_MONRXDAT_MONSTART_START_DETECTED = 1,
> > > > +} FLEXCOMM_I2C_MONRXDAT_MONSTART_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * No repeated start detected. The Monitor function has not detected a
> > > > + * Repeated Start event on the I2C bus.
> > > > + */
> > > > + FLEXCOMM_I2C_MONRXDAT_MONRESTART_NOT_DETECTED = 0,
> > > > + /*
> > > > + * Repeated start detected. The Monitor function has detected a Repeated
> > > > + * Start event on the I2C bus.
> > > > + */
> > > > + FLEXCOMM_I2C_MONRXDAT_MONRESTART_DETECTED = 1,
> > > > +} FLEXCOMM_I2C_MONRXDAT_MONRESTART_Enum;
> > > > +
> > > > +typedef enum {
> > > > + /*
> > > > + * Acknowledged. The data currently being provided by the Monitor function
> > > > + * was acknowledged by at least one master or slave receiver.
> > > > + */
> > > > + FLEXCOMM_I2C_MONRXDAT_MONNACK_ACKNOWLEDGED = 0,
> > > > + /*
> > > > + * Not acknowledged. The data currently being provided by the Monitor
> > > > + * function was not acknowledged by any receiver.
> > > > + */
> > > > + FLEXCOMM_I2C_MONRXDAT_MONNACK_NOT_ACKNOWLEDGED = 1,
> > > > +} FLEXCOMM_I2C_MONRXDAT_MONNACK_Enum;
> > > > +
> > > > +
> > > > +#define FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(_name) \
> > > > + struct RegisterAccessInfo _name[FLEXCOMM_I2C_REGS_NO] = { \
> > > > + [0 ... FLEXCOMM_I2C_REGS_NO - 1] = { \
> > > > + .name = "", \
> > > > + .addr = -1, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_CFG] = { \
> > > > + .name = "CFG", \
> > > > + .addr = 0x800, \
> > > > + .ro = 0xFFFFFFC0, \
> > > > + .reset = 0x0, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_STAT] = { \
> > > > + .name = "STAT", \
> > > > + .addr = 0x804, \
> > > > + .ro = 0xFCF57FAF, \
> > > > + .reset = 0x801, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_INTENSET] = { \
> > > > + .name = "INTENSET", \
> > > > + .addr = 0x808, \
> > > > + .ro = 0xFCF476AE, \
> > > > + .reset = 0x0, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_INTENCLR] = { \
> > > > + .name = "INTENCLR", \
> > > > + .addr = 0x80C, \
> > > > + .ro = 0xFCF476AE, \
> > > > + .reset = 0x0, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_TIMEOUT] = { \
> > > > + .name = "TIMEOUT", \
> > > > + .addr = 0x810, \
> > > > + .ro = 0xFFFF0000, \
> > > > + .reset = 0xFFFF, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_CLKDIV] = { \
> > > > + .name = "CLKDIV", \
> > > > + .addr = 0x814, \
> > > > + .ro = 0xFFFF0000, \
> > > > + .reset = 0x0, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_INTSTAT] = { \
> > > > + .name = "INTSTAT", \
> > > > + .addr = 0x818, \
> > > > + .ro = 0xFFFFFFFF, \
> > > > + .reset = 0x801, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_MSTCTL] = { \
> > > > + .name = "MSTCTL", \
> > > > + .addr = 0x820, \
> > > > + .ro = 0xFFFFFFF0, \
> > > > + .reset = 0x0, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_MSTTIME] = { \
> > > > + .name = "MSTTIME", \
> > > > + .addr = 0x824, \
> > > > + .ro = 0xFFFFFF88, \
> > > > + .reset = 0x77, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_MSTDAT] = { \
> > > > + .name = "MSTDAT", \
> > > > + .addr = 0x828, \
> > > > + .ro = 0xFFFFFF00, \
> > > > + .reset = 0x0, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_SLVCTL] = { \
> > > > + .name = "SLVCTL", \
> > > > + .addr = 0x840, \
> > > > + .ro = 0xFFFFFCF4, \
> > > > + .reset = 0x0, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_SLVDAT] = { \
> > > > + .name = "SLVDAT", \
> > > > + .addr = 0x844, \
> > > > + .ro = 0xFFFFFF00, \
> > > > + .reset = 0x0, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_SLVADR0] = { \
> > > > + .name = "SLVADR0", \
> > > > + .addr = 0x848, \
> > > > + .ro = 0xFFFF7F00, \
> > > > + .reset = 0x1, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_SLVADR1] = { \
> > > > + .name = "SLVADR1", \
> > > > + .addr = 0x84C, \
> > > > + .ro = 0xFFFF7F00, \
> > > > + .reset = 0x1, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_SLVADR2] = { \
> > > > + .name = "SLVADR2", \
> > > > + .addr = 0x850, \
> > > > + .ro = 0xFFFF7F00, \
> > > > + .reset = 0x1, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_SLVADR3] = { \
> > > > + .name = "SLVADR3", \
> > > > + .addr = 0x854, \
> > > > + .ro = 0xFFFF7F00, \
> > > > + .reset = 0x1, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_SLVQUAL0] = { \
> > > > + .name = "SLVQUAL0", \
> > > > + .addr = 0x858, \
> > > > + .ro = 0xFFFFFF00, \
> > > > + .reset = 0x0, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_MONRXDAT] = { \
> > > > + .name = "MONRXDAT", \
> > > > + .addr = 0x880, \
> > > > + .ro = 0xFFFFFFFF, \
> > > > + .reset = 0x0, \
> > > > + }, \
> > > > + [R_FLEXCOMM_I2C_ID] = { \
> > > > + .name = "ID", \
> > > > + .addr = 0xFFC, \
> > > > + .ro = 0xFFFFFFFF, \
> > > > + .reset = 0xE0301300, \
> > > > + }, \
> > > > + }
> > > > diff --git a/include/hw/i2c/flexcomm_i2c.h b/include/hw/i2c/flexcomm_i2c.h
> > > > new file mode 100644
> > > > index 0000000000..7b27e333d7
> > > > --- /dev/null
> > > > +++ b/include/hw/i2c/flexcomm_i2c.h
> > > > @@ -0,0 +1,40 @@
> > > > +/*
> > > > + * QEMU model for NXP's FLEXCOMM I2C
> > > > + *
> > > > + * Copyright (c) 2024 Google LLC
> > > > + *
> > > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > > + *
> > > > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > > > + * See the COPYING file in the top-level directory.
> > > > + */
> > > > +
> > > > +#ifndef HW_FLEXCOMM_I2C_H
> > > > +#define HW_FLEXCOMM_I2C_H
> > > > +
> > > > +#include "hw/i2c/i2c.h"
> > > > +#include "hw/misc/flexcomm_function.h"
> > > > +
> > > > +#define TYPE_FLEXCOMM_I2C "flexcomm-i2c"
> > > > +OBJECT_DECLARE_TYPE(FlexcommI2cState, FlexcommI2cClass, FLEXCOMM_I2C);
> > > > +
> > > > +struct FlexcommI2cState {
> > > > + FlexcommFunction parent_obj;
> > > > +
> > > > + I2CBus *bus;
> > > > +};
> > > > +
> > > > +struct FlexcommI2cClass {
> > > > + FlexcommFunctionClass parent_obj;
> > > > +
> > > > + FlexcommFunctionSelect select;
> > > > +};
> > > > +
> > > > +#define MSTSTATE_IDLE 0
> > > > +#define MSTSTATE_RXRDY 1
> > > > +#define MSTSTATE_TXRDY 2
> > > > +#define MSTSTATE_NAKADR 3
> > > > +#define MSTSTATE_NAKDAT 4
> > > > +
> > > > +
> > > > +#endif /* HW_FLEXCOMM_I2C_H */
> > > > diff --git a/include/hw/misc/flexcomm.h b/include/hw/misc/flexcomm.h
> > > > index 679b7ea64d..c9f1cd3890 100644
> > > > --- a/include/hw/misc/flexcomm.h
> > > > +++ b/include/hw/misc/flexcomm.h
> > > > @@ -16,6 +16,7 @@
> > > > #include "hw/arm/svd/flexcomm.h"
> > > > #include "qemu/fifo32.h"
> > > > #include "hw/char/flexcomm_usart.h"
> > > > +#include "hw/i2c/flexcomm_i2c.h"
> > > >
> > > > #define FLEXCOMM_FUNC_USART 0
> > > > #define FLEXCOMM_FUNC_SPI 1
> > > > @@ -48,6 +49,7 @@ struct FlexcommState {
> > > > Fifo32 rx_fifo;
> > > > Fifo32 tx_fifo;
> > > > FlexcommUsartState usart;
> > > > + FlexcommI2cState i2c;
> > > > };
> > > >
> > > > #endif /* HW_FLEXCOMM_H */
> > > > diff --git a/hw/i2c/flexcomm_i2c.c b/hw/i2c/flexcomm_i2c.c
> > > > new file mode 100644
> > > > index 0000000000..e5341ec241
> > > > --- /dev/null
> > > > +++ b/hw/i2c/flexcomm_i2c.c
> > > > @@ -0,0 +1,250 @@
> > > > +/*
> > > > + * QEMU model for NXP's FLEXCOMM I2C
> > > > + *
> > > > + * Copyright (c) 2024 Google LLC
> > > > + *
> > > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > > + *
> > > > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > > > + * See the COPYING file in the top-level directory.
> > > > + */
> > > > +
> > > > +#include "qemu/osdep.h"
> > > > +#include "qemu/cutils.h"
> > > > +#include "hw/irq.h"
> > > > +#include "hw/qdev-properties.h"
> > > > +#include "qemu/log.h"
> > > > +#include "qemu/module.h"
> > > > +#include "exec/address-spaces.h"
> > > > +#include "qapi/error.h"
> > > > +#include "trace.h"
> > > > +#include "hw/i2c/flexcomm_i2c.h"
> > > > +#include "hw/arm/svd/flexcomm_i2c.h"
> > > > +
> > > > +#define REG(s, reg) (s->regs[R_FLEXCOMM_I2C_##reg])
> > > > +#define RF_WR(s, reg, field, val) \
> > > > + ARRAY_FIELD_DP32(s->regs, FLEXCOMM_I2C_##reg, field, val)
> > > > +#define RF_RD(s, reg, field) \
> > > > + ARRAY_FIELD_EX32(s->regs, FLEXCOMM_I2C_##reg, field)
> > > > +
> > > > +static FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(reg_info);
> > > > +
> > > > +static void flexcomm_i2c_reset(FlexcommFunction *f)
> > > > +{
> > > > + for (int i = 0; i < FLEXCOMM_I2C_REGS_NO; i++) {
> > > > + hwaddr addr = reg_info[i].addr;
> > > > +
> > > > + if (addr != -1) {
> > > > + struct RegisterInfo ri = {
> > > > + .data = &f->regs[addr / 4],
> > > > + .data_size = 4,
> > > > + .access = ®_info[i],
> > > > + };
> > > > +
> > > > + register_reset(&ri);
> > > > + }
> > > > + }
> > > > +}
> > > > +
> > > > +static void flexcomm_i2c_irq_update(FlexcommFunction *f)
> > > > +{
> > > > + bool enabled = RF_RD(f, CFG, MSTEN);
> > > > + bool irq, per_irqs;
> > > > +
> > > > + REG(f, INTSTAT) = REG(f, STAT) & REG(f, INTENSET);
> > > > + per_irqs = REG(f, INTSTAT) != 0;
> > > > +
> > > > + irq = enabled && per_irqs;
> > > > +
> > > > + trace_flexcomm_i2c_irq(DEVICE(f)->id, irq, per_irqs, enabled);
> > > > + flexcomm_set_irq(f, irq);
> > > > +}
> > > > +
> > > > +static MemTxResult flexcomm_i2c_reg_read(void *opaque, hwaddr addr,
> > > > + uint64_t *data, unsigned size,
> > > > + MemTxAttrs attrs)
> > > > +{
> > > > + FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
> > > > + MemTxResult ret = MEMTX_OK;
> > > > + const struct RegisterAccessInfo *rai = ®_info[addr / 4];
> > > > +
> > > > + if (size != 4) {
> > > > + ret = MEMTX_ERROR;
> > > > + goto out;
> > > > + }
> > > > +
> > > > + *data = f->regs[addr / 4];
> > > > +
> > > > + flexcomm_i2c_irq_update(f);
> > > > +
> > > > +out:
> > > > + trace_flexcomm_i2c_reg_read(DEVICE(f)->id, rai->name, addr, *data);
> > > > + return ret;
> > > > +}
> > > > +
> > > > +static MemTxResult flexcomm_i2c_reg_write(void *opaque, hwaddr addr,
> > > > + uint64_t value, unsigned size,
> > > > + MemTxAttrs attrs)
> > > > +{
> > > > + FlexcommFunction *f = FLEXCOMM_FUNCTION(opaque);
> > > > + FlexcommI2cState *s = FLEXCOMM_I2C(opaque);
> > > > + const struct RegisterAccessInfo *rai = ®_info[addr / 4];
> > > > + struct RegisterInfo ri = {
> > > > + .data = &f->regs[addr / 4],
> > > > + .data_size = 4,
> > > > + .access = rai,
> > > > + };
> > > > +
> > > > + trace_flexcomm_i2c_reg_write(DEVICE(f)->id, rai->name, addr, value);
> > > > +
> > > > + if (size != 4) {
> > > > + return MEMTX_ERROR;
> > > > + }
> > > > +
> > > > + switch (addr) {
> > > > + case A_FLEXCOMM_I2C_CFG:
> > > > + {
> > > > + register_write(&ri, value, ~0, NULL, false);
> > > > + if (RF_RD(f, CFG, SLVEN)) {
> > > > + qemu_log_mask(LOG_GUEST_ERROR, "I2C slave not supported");
> > > > + }
> > > > + if (RF_RD(f, CFG, MONEN)) {
> > > > + qemu_log_mask(LOG_GUEST_ERROR, "I2C monitoring not supported");
> > > > + }
> > > > + break;
> > > > + }
> > > > + case A_FLEXCOMM_I2C_INTENCLR:
> > > > + {
> > > > + REG(f, INTENSET) &= ~value;
> > > > + break;
> > > > + }
> > > > + case A_FLEXCOMM_I2C_TIMEOUT:
> > > > + {
> > > > + register_write(&ri, value, ~0, NULL, false);
> > > > + /* The bottom 4 bits are hard-wired to 0xF */
> > > > + RF_WR(f, TIMEOUT, TOMIN, 0xf);
> > > > + break;
> > > > + }
> > > > + case A_FLEXCOMM_I2C_MSTCTL:
> > > > + {
> > > > + register_write(&ri, value, ~0, NULL, false);
> > > > + if (RF_RD(f, MSTCTL, MSTSTART)) {
> > > > + uint8_t i2c_addr = RF_RD(f, MSTDAT, DATA);
> > > > + bool recv = i2c_addr & 1;
> > > > +
> > > > + trace_flexcomm_i2c_start(DEVICE(s)->id, i2c_addr, recv);
> > > > + if (i2c_start_transfer(s->bus, i2c_addr, recv)) {
> > > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_NAKADR);
> > > > + trace_flexcomm_i2c_nak(DEVICE(s)->id);
> > > > + } else {
> > > > + if (recv) {
> > > > + uint8_t data = i2c_recv(s->bus);
> > > > +
> > > > + RF_WR(f, MSTDAT, DATA, data);
> > > > + trace_flexcomm_i2c_rx(DEVICE(s)->id, data);
> > > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_RXRDY);
> > > > + } else {
> > > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_TXRDY);
> > > > + }
> > > > + }
> > > > + }
> > > > + if (RF_RD(f, MSTCTL, MSTSTOP)) {
> > > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_IDLE);
> > > > + i2c_end_transfer(s->bus);
> > > > + }
> > > > + if (RF_RD(f, MSTCTL, MSTCONTINUE)) {
> > > > + if (RF_RD(f, STAT, MSTSTATE) == MSTSTATE_TXRDY) {
> > > > + uint8_t data = RF_RD(f, MSTDAT, DATA);
> > > > +
> > > > + trace_flexcomm_i2c_tx(DEVICE(s)->id, data);
> > > > + if (i2c_send(s->bus, data)) {
> > > > + RF_WR(f, STAT, MSTSTATE, MSTSTATE_NAKDAT);
> > > > + }
> > > > + } else if (RF_RD(f, STAT, MSTSTATE) == MSTSTATE_RXRDY) {
> > > > + uint8_t data = i2c_recv(s->bus);
> > > > +
> > > > + RF_WR(f, MSTDAT, DATA, data);
> > > > + trace_flexcomm_i2c_rx(DEVICE(s)->id, data);
> > > > + }
> > > > + }
> > > > + break;
> > > > + }
> > > > + case A_FLEXCOMM_I2C_STAT:
> > > > + {
> > > > + /* write 1 to clear bits */
> > > > + REG(f, STAT) &= ~value;
> > > > + break;
> > > > + }
> > > > + case A_FLEXCOMM_I2C_SLVCTL:
> > > > + case A_FLEXCOMM_I2C_SLVDAT:
> > > > + case A_FLEXCOMM_I2C_SLVADR0:
> > > > + case A_FLEXCOMM_I2C_SLVADR1:
> > > > + case A_FLEXCOMM_I2C_SLVADR2:
> > > > + case A_FLEXCOMM_I2C_SLVADR3:
> > > > + case A_FLEXCOMM_I2C_SLVQUAL0:
> > > > + {
> > > > + qemu_log_mask(LOG_GUEST_ERROR, "I2C slave not supported\n");
> > > > + break;
> > > > + }
> > > > + default:
> > > > + register_write(&ri, value, ~0, NULL, false);
> > > > + break;
> > > > + }
> > > > +
> > > > + flexcomm_i2c_irq_update(f);
> > > > +
> > > > + return MEMTX_OK;
> > > > +}
> > > > +
> > > > +static void flexcomm_i2c_select(FlexcommFunction *f, bool selected)
> > > > +{
> > > > + FlexcommI2cClass *ic = FLEXCOMM_I2C_GET_CLASS(f);
> > > > +
> > > > + if (selected) {
> > > > + flexcomm_i2c_reset(f);
> > > > + }
> > > > + ic->select(f, selected);
> > > > +}
> > > > +
> > > > +static const MemoryRegionOps flexcomm_i2c_ops = {
> > > > + .read_with_attrs = flexcomm_i2c_reg_read,
> > > > + .write_with_attrs = flexcomm_i2c_reg_write,
> > > > + .endianness = DEVICE_NATIVE_ENDIAN,
> > > > + .valid = {
> > > > + .min_access_size = 4,
> > > > + .max_access_size = 4,
> > > > + .unaligned = false,
> > > > + },
> > > > +};
> > > > +
> > > > +static void flexcomm_i2c_realize(DeviceState *dev, Error **errp)
> > > > +{
> > > > + FlexcommI2cState *s = FLEXCOMM_I2C(dev);
> > > > +
> > > > + s->bus = i2c_init_bus(DEVICE(s), "bus");
> > > > +}
> > > > +
> > > > +static void flexcomm_i2c_class_init(ObjectClass *klass, void *data)
> > > > +{
> > > > + DeviceClass *dc = DEVICE_CLASS(klass);
> > > > + FlexcommFunctionClass *fc = FLEXCOMM_FUNCTION_CLASS(klass);
> > > > + FlexcommI2cClass *ic = FLEXCOMM_I2C_CLASS(klass);
> > > > +
> > > > + dc->realize = flexcomm_i2c_realize;
> > > > + ic->select = fc->select;
> > > > + fc->select = flexcomm_i2c_select;
> > > > + fc->name = "i2c";
> > > > + fc->mmio_ops = &flexcomm_i2c_ops;
> > > > +}
> > > > +
> > > > +static const TypeInfo flexcomm_i2c_types[] = {
> > > > + {
> > > > + .name = TYPE_FLEXCOMM_I2C,
> > > > + .parent = TYPE_FLEXCOMM_FUNCTION,
> > > > + .instance_size = sizeof(FlexcommI2cState),
> > > > + .class_init = flexcomm_i2c_class_init,
> > > > + .class_size = sizeof(FlexcommI2cClass),
> > > > + },
> > > > +};
> > > > +
> > > > +DEFINE_TYPES(flexcomm_i2c_types);
> > > > diff --git a/hw/misc/flexcomm.c b/hw/misc/flexcomm.c
> > > > index a291148f27..b1a2f01acf 100644
> > > > --- a/hw/misc/flexcomm.c
> > > > +++ b/hw/misc/flexcomm.c
> > > > @@ -24,6 +24,7 @@
> > > > #include "hw/misc/flexcomm.h"
> > > > #include "hw/arm/svd/flexcomm_usart.h"
> > > > #include "hw/char/flexcomm_usart.h"
> > > > +#include "hw/i2c/flexcomm_i2c.h"
> > > >
> > > > #define REG(s, reg) (s->regs[R_FLEXCOMM_##reg])
> > > > #define RF_WR(s, reg, field, val) \
> > > > @@ -220,6 +221,7 @@ static void flexcomm_init(Object *obj)
> > > > sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container);
> > > > sysbus_init_irq(sbd, &s->irq);
> > > > object_initialize_child(obj, "usart", &s->usart, TYPE_FLEXCOMM_USART);
> > > > + object_initialize_child(obj, "i2c", &s->i2c, TYPE_FLEXCOMM_I2C);
> > > > }
> > > >
> > > > static void flexcomm_finalize(Object *obj)
> > > > @@ -250,6 +252,7 @@ static void flexcomm_realize(DeviceState *dev, Error **errp)
> > > >
> > > > memory_region_add_subregion_overlap(&s->container, 0, &s->mmio, -1);
> > > > flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->usart), errp);
> > > > + flexcomm_func_realize_and_unref(FLEXCOMM_FUNCTION(&s->i2c), errp);
> > > > }
> > > >
> > > > static const VMStateDescription vmstate_flexcomm = {
> > > > diff --git a/hw/arm/svd/meson.build b/hw/arm/svd/meson.build
> > > > index 2bde34d15b..417491cd5c 100644
> > > > --- a/hw/arm/svd/meson.build
> > > > +++ b/hw/arm/svd/meson.build
> > > > @@ -7,4 +7,7 @@ if get_option('mcux-soc-svd')
> > > > run_target('svd-flexcomm-usart', command: svd_gen_header +
> > > > [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_usart.h',
> > > > '-p', 'USART0', '-t', 'FLEXCOMM_USART'])
> > > > + run_target('svd-flexcomm-i2c', command: svd_gen_header +
> > > > + [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_i2c.h',
> > > > + '-p', 'I2C0', '-t', 'FLEXCOMM_I2C'])
> > > > endif
> > > > diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build
> > > > index c459adcb59..e7d79e6938 100644
> > > > --- a/hw/i2c/meson.build
> > > > +++ b/hw/i2c/meson.build
> > > > @@ -18,4 +18,5 @@ i2c_ss.add(when: 'CONFIG_PPC4XX', if_true: files('ppc4xx_i2c.c'))
> > > > i2c_ss.add(when: 'CONFIG_PCA954X', if_true: files('i2c_mux_pca954x.c'))
> > > > i2c_ss.add(when: 'CONFIG_PMBUS', if_true: files('pmbus_device.c'))
> > > > i2c_ss.add(when: 'CONFIG_BCM2835_I2C', if_true: files('bcm2835_i2c.c'))
> > > > +i2c_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm_i2c.c'))
> > > > system_ss.add_all(when: 'CONFIG_I2C', if_true: i2c_ss)
> > > > diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
> > > > index 6900e06eda..9f0175fab7 100644
> > > > --- a/hw/i2c/trace-events
> > > > +++ b/hw/i2c/trace-events
> > > > @@ -51,3 +51,13 @@ npcm7xx_smbus_recv_fifo(const char *id, uint8_t received, uint8_t expected) "%s
> > > >
> > > > pca954x_write_bytes(uint8_t value) "PCA954X write data: 0x%02x"
> > > > pca954x_read_data(uint8_t value) "PCA954X read data: 0x%02x"
> > > > +
> > > > +# flexcomm_i2c.c
> > > > +
> > > > +flexcomm_i2c_reg_read(const char *id, const char *reg_name, uint32_t addr, uint32_t val) " %s: %s[0x%04x] -> 0x%08x"
> > > > +flexcomm_i2c_reg_write(const char *id, const char *reg_name, uint32_t addr, uint32_t val) "%s: %s[0x%04x] <- 0x%08x"
> > > > +flexcomm_i2c_start(const char *id, uint8_t addr, uint8_t recv) "%s: 0x%02x %d"
> > > > +flexcomm_i2c_rx(const char *id, uint8_t data) "%s: <- 0x%02x"
> > > > +flexcomm_i2c_tx(const char *id, uint8_t data) "%s: -> 0x%02x"
> > > > +flexcomm_i2c_nak(const char *id) "%s: <- nak"
> > > > +flexcomm_i2c_irq(const char *id, bool irq, bool perirqs, bool enabled) "%s: %d %d %d"
> > > > diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
> > > > index 14167ae9e8..9a244fa01d 100644
> > > > --- a/hw/misc/Kconfig
> > > > +++ b/hw/misc/Kconfig
> > > > @@ -215,5 +215,6 @@ config XLNX_VERSAL_TRNG
> > > >
> > > > config FLEXCOMM
> > > > bool
> > > > + select I2C
> > > >
> > > > source macio/Kconfig
> > > > --
> > > > 2.46.0.662.g92d0881bb0-goog
> > > >
> > > >
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 19/25] hw/misc: add i2c-tester
2024-09-18 20:05 ` Corey Minyard
@ 2024-09-18 23:03 ` Octavian Purdila
2024-09-18 23:52 ` Corey Minyard
0 siblings, 1 reply; 36+ messages in thread
From: Octavian Purdila @ 2024-09-18 23:03 UTC (permalink / raw)
To: corey
Cc: qemu-devel, qemu-arm, stefanst, pbonzini, peter.maydell,
marcandre.lureau, berrange, eduardo, luc, damien.hedde, alistair,
thuth, philmd, jsnow, crosa, lvivier
On Wed, Sep 18, 2024 at 1:06 PM Corey Minyard <corey@minyard.net> wrote:
>
> On Wed, Sep 18, 2024 at 12:22:47PM -0700, Octavian Purdila wrote:
> > Add a simple i2c peripheral to be used for testing I2C device
> > models. The peripheral has a fixed number of registers that can be
> > read and written.
>
> Why is this better than just using the eeprom device?
>
The main reason for adding it is that, AFAICT, there is no i2c slave
device that responds with I2C_NACK during a transaction.
Also, having a dedicated device for testing purposes makes it easier
to add new features than adding it to a real device where it might not
always be possible. I tried to add the NACK functionality but I did
not find one where the datasheet would confirm the behaviour I was
looking for.
> This has some uncommon attributes compared to most i2c devices. For
> instance, most i2c devices take their address as the first bytes of a
> write operation, then auto-increment after that for reads and writes.
> This seems to take one address on a write after a system reset, then use
> that forever.
>
> Anyway, unless there is a compelling reason to use this over the eeprom
> device, I'm going to recommend against it.
>
> -corey
>
> >
> > Signed-off-by: Octavian Purdila <tavip@google.com>
> > ---
> > include/hw/misc/i2c_tester.h | 30 ++++++++++
> > hw/misc/i2c_tester.c | 109 +++++++++++++++++++++++++++++++++++
> > hw/misc/Kconfig | 5 ++
> > hw/misc/meson.build | 2 +
> > 4 files changed, 146 insertions(+)
> > create mode 100644 include/hw/misc/i2c_tester.h
> > create mode 100644 hw/misc/i2c_tester.c
> >
> > diff --git a/include/hw/misc/i2c_tester.h b/include/hw/misc/i2c_tester.h
> > new file mode 100644
> > index 0000000000..f6b6491008
> > --- /dev/null
> > +++ b/include/hw/misc/i2c_tester.h
> > @@ -0,0 +1,30 @@
> > +/*
> > + *
> > + * Copyright (c) 2024 Google LLC
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + */
> > +
> > +#ifndef HW_I2C_TESTER_H
> > +#define HW_I2C_TESTER_H
> > +
> > +#include "qemu/osdep.h"
> > +#include "hw/i2c/i2c.h"
> > +#include "hw/irq.h"
> > +
> > +#define I2C_TESTER_NUM_REGS 0x31
> > +
> > +#define TYPE_I2C_TESTER "i2c-tester"
> > +#define I2C_TESTER(obj) OBJECT_CHECK(I2cTesterState, (obj), TYPE_I2C_TESTER)
> > +
> > +typedef struct {
> > + I2CSlave i2c;
> > + bool set_reg_idx;
> > + uint8_t reg_idx;
> > + uint8_t regs[I2C_TESTER_NUM_REGS];
> > +} I2cTesterState;
> > +
> > +#endif /* HW_I2C_TESTER_H */
> > diff --git a/hw/misc/i2c_tester.c b/hw/misc/i2c_tester.c
> > new file mode 100644
> > index 0000000000..77ce8bf91a
> > --- /dev/null
> > +++ b/hw/misc/i2c_tester.c
> > @@ -0,0 +1,109 @@
> > +/*
> > + * Simple I2C peripheral for testing I2C device models.
> > + *
> > + * Copyright (c) 2024 Google LLC
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + */
> > +
> > +#include "hw/misc/i2c_tester.h"
> > +
> > +#include "qemu/log.h"
> > +#include "qemu/module.h"
> > +#include "migration/vmstate.h"
> > +
> > +static void i2c_tester_reset_enter(Object *o, ResetType type)
> > +{
> > + I2cTesterState *s = I2C_TESTER(o);
> > +
> > + s->set_reg_idx = false;
> > + s->reg_idx = 0;
> > + memset(s->regs, 0, I2C_TESTER_NUM_REGS);
> > +}
> > +
> > +static int i2c_tester_event(I2CSlave *i2c, enum i2c_event event)
> > +{
> > + I2cTesterState *s = I2C_TESTER(i2c);
> > +
> > + if (event == I2C_START_SEND) {
> > + s->set_reg_idx = true;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static uint8_t i2c_tester_rx(I2CSlave *i2c)
> > +{
> > + I2cTesterState *s = I2C_TESTER(i2c);
> > +
> > + if (s->reg_idx >= I2C_TESTER_NUM_REGS) {
> > + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid reg 0x%02x\n", __func__,
> > + s->reg_idx);
> > + return I2C_NACK;
> > + }
> > +
> > + return s->regs[s->reg_idx];
> > +}
> > +
> > +static int i2c_tester_tx(I2CSlave *i2c, uint8_t data)
> > +{
> > + I2cTesterState *s = I2C_TESTER(i2c);
> > +
> > + if (s->set_reg_idx) {
> > + /* Setting the register in which the operation will be done. */
> > + s->reg_idx = data;
> > + s->set_reg_idx = false;
> > + return 0;
> > + }
> > +
> > + if (s->reg_idx >= I2C_TESTER_NUM_REGS) {
> > + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid reg 0x%02x\n", __func__,
> > + s->reg_idx);
> > + return I2C_NACK;
> > + }
> > +
> > + /* Write reg data. */
> > + s->regs[s->reg_idx] = data;
> > +
> > + return 0;
> > +}
> > +
> > +static const VMStateDescription vmstate_i2c_tester = {
> > + .name = "i2c-tester",
> > + .version_id = 1,
> > + .minimum_version_id = 1,
> > + .fields = (const VMStateField[]) {
> > + VMSTATE_I2C_SLAVE(i2c, I2cTesterState),
> > + VMSTATE_BOOL(set_reg_idx, I2cTesterState),
> > + VMSTATE_UINT8(reg_idx, I2cTesterState),
> > + VMSTATE_UINT8_ARRAY(regs, I2cTesterState, I2C_TESTER_NUM_REGS),
> > + VMSTATE_END_OF_LIST()
> > + }
> > +};
> > +
> > +static void i2c_tester_class_init(ObjectClass *oc, void *data)
> > +{
> > + DeviceClass *dc = DEVICE_CLASS(oc);
> > + ResettableClass *rc = RESETTABLE_CLASS(oc);
> > + I2CSlaveClass *isc = I2C_SLAVE_CLASS(oc);
> > +
> > + rc->phases.enter = i2c_tester_reset_enter;
> > + dc->vmsd = &vmstate_i2c_tester;
> > + isc->event = i2c_tester_event;
> > + isc->recv = i2c_tester_rx;
> > + isc->send = i2c_tester_tx;
> > +}
> > +
> > +static const TypeInfo i2c_tester_types[] = {
> > + {
> > + .name = TYPE_I2C_TESTER,
> > + .parent = TYPE_I2C_SLAVE,
> > + .instance_size = sizeof(I2cTesterState),
> > + .class_init = i2c_tester_class_init
> > + },
> > +};
> > +
> > +DEFINE_TYPES(i2c_tester_types);
> > diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
> > index 4b688aead2..3e93c12c8e 100644
> > --- a/hw/misc/Kconfig
> > +++ b/hw/misc/Kconfig
> > @@ -213,6 +213,11 @@ config IOSB
> > config XLNX_VERSAL_TRNG
> > bool
> >
> > +config I2C_TESTER
> > + bool
> > + default y if TEST_DEVICES
> > + depends on I2C
> > +
> > config FLEXCOMM
> > bool
> > select I2C
> > diff --git a/hw/misc/meson.build b/hw/misc/meson.build
> > index faaf2671ba..4f22231fa3 100644
> > --- a/hw/misc/meson.build
> > +++ b/hw/misc/meson.build
> > @@ -158,6 +158,8 @@ system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c'))
> > # HPPA devices
> > system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c'))
> >
> > +system_ss.add(when: 'CONFIG_I2C_TESTER', if_true: files('i2c_tester.c'))
> > +
> > system_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm.c'))
> > system_ss.add(when: 'CONFIG_RT500_CLKCTL', if_true: files('rt500_clkctl0.c', 'rt500_clkctl1.c'))
> > system_ss.add(when: 'CONFIG_RT500_RSTCTL', if_true: files('rt500_rstctl.c'))
> > --
> > 2.46.0.662.g92d0881bb0-goog
> >
> >
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 19/25] hw/misc: add i2c-tester
2024-09-18 23:03 ` Octavian Purdila
@ 2024-09-18 23:52 ` Corey Minyard
0 siblings, 0 replies; 36+ messages in thread
From: Corey Minyard @ 2024-09-18 23:52 UTC (permalink / raw)
To: Octavian Purdila
Cc: qemu-devel, qemu-arm, stefanst, pbonzini, peter.maydell,
marcandre.lureau, berrange, eduardo, luc, damien.hedde, alistair,
thuth, philmd, jsnow, crosa, lvivier
On Wed, Sep 18, 2024 at 04:03:12PM -0700, Octavian Purdila wrote:
> On Wed, Sep 18, 2024 at 1:06 PM Corey Minyard <corey@minyard.net> wrote:
> >
> > On Wed, Sep 18, 2024 at 12:22:47PM -0700, Octavian Purdila wrote:
> > > Add a simple i2c peripheral to be used for testing I2C device
> > > models. The peripheral has a fixed number of registers that can be
> > > read and written.
> >
> > Why is this better than just using the eeprom device?
> >
>
> The main reason for adding it is that, AFAICT, there is no i2c slave
> device that responds with I2C_NACK during a transaction.
>
> Also, having a dedicated device for testing purposes makes it easier
> to add new features than adding it to a real device where it might not
> always be possible. I tried to add the NACK functionality but I did
> not find one where the datasheet would confirm the behaviour I was
> looking for.
SMBUS devices (like the eeprom) use NACKs as part of the protocol, to
mark the end of a transfer, but that's probably not what you are looking
for. You are using it to signal an error, which I don't think any
existing device will do. Real devices, in general, don't NACK anything
for errors, but the protocol allows it.
Somehow in my previous look I completely missed i2c_tester_event(), so
this works like a normal I2C device, except that most of them
auto-increment the index register. But some don't, so it's fine.
If you could document the rationale for this, it would help a lot, for
others that might want to use it. Also, I would expect people might
add their own test code to this. I'm not sure what you can do at the
moment about that, but just a heads up that people will probably hack on
this in the future.
So this is good.
-corey
>
> > This has some uncommon attributes compared to most i2c devices. For
> > instance, most i2c devices take their address as the first bytes of a
> > write operation, then auto-increment after that for reads and writes.
> > This seems to take one address on a write after a system reset, then use
> > that forever.
> >
> > Anyway, unless there is a compelling reason to use this over the eeprom
> > device, I'm going to recommend against it.
> >
>
>
> > -corey
> >
> > >
> > > Signed-off-by: Octavian Purdila <tavip@google.com>
> > > ---
> > > include/hw/misc/i2c_tester.h | 30 ++++++++++
> > > hw/misc/i2c_tester.c | 109 +++++++++++++++++++++++++++++++++++
> > > hw/misc/Kconfig | 5 ++
> > > hw/misc/meson.build | 2 +
> > > 4 files changed, 146 insertions(+)
> > > create mode 100644 include/hw/misc/i2c_tester.h
> > > create mode 100644 hw/misc/i2c_tester.c
> > >
> > > diff --git a/include/hw/misc/i2c_tester.h b/include/hw/misc/i2c_tester.h
> > > new file mode 100644
> > > index 0000000000..f6b6491008
> > > --- /dev/null
> > > +++ b/include/hw/misc/i2c_tester.h
> > > @@ -0,0 +1,30 @@
> > > +/*
> > > + *
> > > + * Copyright (c) 2024 Google LLC
> > > + *
> > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > + *
> > > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > > + * See the COPYING file in the top-level directory.
> > > + */
> > > +
> > > +#ifndef HW_I2C_TESTER_H
> > > +#define HW_I2C_TESTER_H
> > > +
> > > +#include "qemu/osdep.h"
> > > +#include "hw/i2c/i2c.h"
> > > +#include "hw/irq.h"
> > > +
> > > +#define I2C_TESTER_NUM_REGS 0x31
> > > +
> > > +#define TYPE_I2C_TESTER "i2c-tester"
> > > +#define I2C_TESTER(obj) OBJECT_CHECK(I2cTesterState, (obj), TYPE_I2C_TESTER)
> > > +
> > > +typedef struct {
> > > + I2CSlave i2c;
> > > + bool set_reg_idx;
> > > + uint8_t reg_idx;
> > > + uint8_t regs[I2C_TESTER_NUM_REGS];
> > > +} I2cTesterState;
> > > +
> > > +#endif /* HW_I2C_TESTER_H */
> > > diff --git a/hw/misc/i2c_tester.c b/hw/misc/i2c_tester.c
> > > new file mode 100644
> > > index 0000000000..77ce8bf91a
> > > --- /dev/null
> > > +++ b/hw/misc/i2c_tester.c
> > > @@ -0,0 +1,109 @@
> > > +/*
> > > + * Simple I2C peripheral for testing I2C device models.
> > > + *
> > > + * Copyright (c) 2024 Google LLC
> > > + *
> > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > + *
> > > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > > + * See the COPYING file in the top-level directory.
> > > + */
> > > +
> > > +#include "hw/misc/i2c_tester.h"
> > > +
> > > +#include "qemu/log.h"
> > > +#include "qemu/module.h"
> > > +#include "migration/vmstate.h"
> > > +
> > > +static void i2c_tester_reset_enter(Object *o, ResetType type)
> > > +{
> > > + I2cTesterState *s = I2C_TESTER(o);
> > > +
> > > + s->set_reg_idx = false;
> > > + s->reg_idx = 0;
> > > + memset(s->regs, 0, I2C_TESTER_NUM_REGS);
> > > +}
> > > +
> > > +static int i2c_tester_event(I2CSlave *i2c, enum i2c_event event)
> > > +{
> > > + I2cTesterState *s = I2C_TESTER(i2c);
> > > +
> > > + if (event == I2C_START_SEND) {
> > > + s->set_reg_idx = true;
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static uint8_t i2c_tester_rx(I2CSlave *i2c)
> > > +{
> > > + I2cTesterState *s = I2C_TESTER(i2c);
> > > +
> > > + if (s->reg_idx >= I2C_TESTER_NUM_REGS) {
> > > + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid reg 0x%02x\n", __func__,
> > > + s->reg_idx);
> > > + return I2C_NACK;
> > > + }
> > > +
> > > + return s->regs[s->reg_idx];
> > > +}
> > > +
> > > +static int i2c_tester_tx(I2CSlave *i2c, uint8_t data)
> > > +{
> > > + I2cTesterState *s = I2C_TESTER(i2c);
> > > +
> > > + if (s->set_reg_idx) {
> > > + /* Setting the register in which the operation will be done. */
> > > + s->reg_idx = data;
> > > + s->set_reg_idx = false;
> > > + return 0;
> > > + }
> > > +
> > > + if (s->reg_idx >= I2C_TESTER_NUM_REGS) {
> > > + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid reg 0x%02x\n", __func__,
> > > + s->reg_idx);
> > > + return I2C_NACK;
> > > + }
> > > +
> > > + /* Write reg data. */
> > > + s->regs[s->reg_idx] = data;
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static const VMStateDescription vmstate_i2c_tester = {
> > > + .name = "i2c-tester",
> > > + .version_id = 1,
> > > + .minimum_version_id = 1,
> > > + .fields = (const VMStateField[]) {
> > > + VMSTATE_I2C_SLAVE(i2c, I2cTesterState),
> > > + VMSTATE_BOOL(set_reg_idx, I2cTesterState),
> > > + VMSTATE_UINT8(reg_idx, I2cTesterState),
> > > + VMSTATE_UINT8_ARRAY(regs, I2cTesterState, I2C_TESTER_NUM_REGS),
> > > + VMSTATE_END_OF_LIST()
> > > + }
> > > +};
> > > +
> > > +static void i2c_tester_class_init(ObjectClass *oc, void *data)
> > > +{
> > > + DeviceClass *dc = DEVICE_CLASS(oc);
> > > + ResettableClass *rc = RESETTABLE_CLASS(oc);
> > > + I2CSlaveClass *isc = I2C_SLAVE_CLASS(oc);
> > > +
> > > + rc->phases.enter = i2c_tester_reset_enter;
> > > + dc->vmsd = &vmstate_i2c_tester;
> > > + isc->event = i2c_tester_event;
> > > + isc->recv = i2c_tester_rx;
> > > + isc->send = i2c_tester_tx;
> > > +}
> > > +
> > > +static const TypeInfo i2c_tester_types[] = {
> > > + {
> > > + .name = TYPE_I2C_TESTER,
> > > + .parent = TYPE_I2C_SLAVE,
> > > + .instance_size = sizeof(I2cTesterState),
> > > + .class_init = i2c_tester_class_init
> > > + },
> > > +};
> > > +
> > > +DEFINE_TYPES(i2c_tester_types);
> > > diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
> > > index 4b688aead2..3e93c12c8e 100644
> > > --- a/hw/misc/Kconfig
> > > +++ b/hw/misc/Kconfig
> > > @@ -213,6 +213,11 @@ config IOSB
> > > config XLNX_VERSAL_TRNG
> > > bool
> > >
> > > +config I2C_TESTER
> > > + bool
> > > + default y if TEST_DEVICES
> > > + depends on I2C
> > > +
> > > config FLEXCOMM
> > > bool
> > > select I2C
> > > diff --git a/hw/misc/meson.build b/hw/misc/meson.build
> > > index faaf2671ba..4f22231fa3 100644
> > > --- a/hw/misc/meson.build
> > > +++ b/hw/misc/meson.build
> > > @@ -158,6 +158,8 @@ system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c'))
> > > # HPPA devices
> > > system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c'))
> > >
> > > +system_ss.add(when: 'CONFIG_I2C_TESTER', if_true: files('i2c_tester.c'))
> > > +
> > > system_ss.add(when: 'CONFIG_FLEXCOMM', if_true: files('flexcomm.c'))
> > > system_ss.add(when: 'CONFIG_RT500_CLKCTL', if_true: files('rt500_clkctl0.c', 'rt500_clkctl1.c'))
> > > system_ss.add(when: 'CONFIG_RT500_RSTCTL', if_true: files('rt500_rstctl.c'))
> > > --
> > > 2.46.0.662.g92d0881bb0-goog
> > >
> > >
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 08/25] hw/i2c: add support for flexcomm i2c
2024-09-18 21:31 ` Corey Minyard
2024-09-18 22:25 ` Octavian Purdila
@ 2024-09-19 9:36 ` Peter Maydell
2024-09-20 18:02 ` Octavian Purdila
1 sibling, 1 reply; 36+ messages in thread
From: Peter Maydell @ 2024-09-19 9:36 UTC (permalink / raw)
To: corey
Cc: Octavian Purdila, qemu-devel, qemu-arm, stefanst, pbonzini,
marcandre.lureau, berrange, eduardo, luc, damien.hedde, alistair,
thuth, philmd, jsnow, crosa, lvivier
On Wed, 18 Sept 2024 at 22:31, Corey Minyard <corey@minyard.net> wrote:
> Generally it's frowned upon to have a ton of extra stuff that's not
> used. I would think some is ok, like defining bits in registers that
> aren't used yet, but I have no idea how all the enums below here
> actually tie into anything. I'm guessing these are just bitmasks into
> registers, but really, it's a lot easier to read if you have something
> like:
>
> /*
> * The I2C Master function enable. When disabled, the Master
> * configuration settings are not changed, but the Master function is
> * internally reset.
> */
> #define FLEXCOMM_I2C_CFG_MSTEN (1 << 4)
The FIELD macro already gives you that:
FIELD(FLEXCOMM_I2C_CFG, MSTEN, startbit, len);
will define an R_FLEXCOMM_I2C_CFG_MSTEN_MASK (which is
(1 << startbit) for the 'len == 1' case).
You can also set and read a 1 bit field the same as
any other, with the FIELD_DP32/FIELD_EX32 macros, so
you don't often need to directly use the MASK macro:
s->cfg = FIELD_DP32(s->cfg, CFG, MSTEN, 1);
and
if (FIELD_EX32(s->cfg, CFG, MSTEN)) {
...
}
The FIELD() macros are a bit unwieldy sometimes but the
advantage over ad-hoc #defines is that they're consistent
for every field in every register.
I agree that providing enums for the possible values for 1-bit
fields is a bit superfluous.
thanks
-- PMM
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 08/25] hw/i2c: add support for flexcomm i2c
2024-09-19 9:36 ` Peter Maydell
@ 2024-09-20 18:02 ` Octavian Purdila
2024-09-20 18:09 ` Corey Minyard
0 siblings, 1 reply; 36+ messages in thread
From: Octavian Purdila @ 2024-09-20 18:02 UTC (permalink / raw)
To: corey
Cc: qemu-devel, qemu-arm, stefanst, pbonzini, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier, Peter Maydell
On Thu, Sep 19, 2024 at 2:36 AM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Wed, 18 Sept 2024 at 22:31, Corey Minyard <corey@minyard.net> wrote:
> > Generally it's frowned upon to have a ton of extra stuff that's not
> > used. I would think some is ok, like defining bits in registers that
> > aren't used yet, but I have no idea how all the enums below here
> > actually tie into anything. I'm guessing these are just bitmasks into
> > registers, but really, it's a lot easier to read if you have something
> > like:
> >
> > /*
> > * The I2C Master function enable. When disabled, the Master
> > * configuration settings are not changed, but the Master function is
> > * internally reset.
> > */
> > #define FLEXCOMM_I2C_CFG_MSTEN (1 << 4)
>
> The FIELD macro already gives you that:
> FIELD(FLEXCOMM_I2C_CFG, MSTEN, startbit, len);
> will define an R_FLEXCOMM_I2C_CFG_MSTEN_MASK (which is
> (1 << startbit) for the 'len == 1' case).
>
> You can also set and read a 1 bit field the same as
> any other, with the FIELD_DP32/FIELD_EX32 macros, so
> you don't often need to directly use the MASK macro:
> s->cfg = FIELD_DP32(s->cfg, CFG, MSTEN, 1);
> and
> if (FIELD_EX32(s->cfg, CFG, MSTEN)) {
> ...
> }
>
> The FIELD() macros are a bit unwieldy sometimes but the
> advantage over ad-hoc #defines is that they're consistent
> for every field in every register.
>
> I agree that providing enums for the possible values for 1-bit
> fields is a bit superfluous.
>
I went ahead and removed those 1-bit enum values and added support to
filter register/fields when generating the code. Also converted the
enums to defines to make these a little bit more compact as I don't
think we have any advantage over the enums?
So with the following invocation:
run_target('svd-flexcomm-i2c', command: svd_gen_header +
[ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_i2c.h',
'-p', 'I2C0', '-t', 'FLEXCOMM_I2C',
'--fields', 'CFG TIMEOUT:TOMIN MSTCTL MSTDAT
STAT:MSTPENDING,MSTSTATE INT*:MSTPENDING* SLV*:'])
I am getting the below generated file. Note that the register info is
generated for all registers because this information is used to
initialize the reset values, mask writes appropriately in registers
and trace register access.
Please let me know if this looks good or if there are any other tweaks
I could make.
/*
* Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
*
* Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
*/
#pragma once
#include "hw/register.h"
/* I2C Bus Interface */
#define FLEXCOMM_I2C_REGS_NO (1024)
/* Configuration Register */
REG32(FLEXCOMM_I2C_CFG, 0x800);
/* Master Enable */
FIELD(FLEXCOMM_I2C_CFG, MSTEN, 0, 1);
/* Slave Enable */
FIELD(FLEXCOMM_I2C_CFG, SLVEN, 1, 1);
/* Monitor Enable */
FIELD(FLEXCOMM_I2C_CFG, MONEN, 2, 1);
/* I2C bus Time-out Enable */
FIELD(FLEXCOMM_I2C_CFG, TIMEOUTEN, 3, 1);
/* Monitor function Clock Stretching */
FIELD(FLEXCOMM_I2C_CFG, MONCLKSTR, 4, 1);
/* High Speed mode Capable enable */
FIELD(FLEXCOMM_I2C_CFG, HSCAPABLE, 5, 1);
/* Status Register */
REG32(FLEXCOMM_I2C_STAT, 0x804);
/* Master Pending */
FIELD(FLEXCOMM_I2C_STAT, MSTPENDING, 0, 1);
/* Master State code */
FIELD(FLEXCOMM_I2C_STAT, MSTSTATE, 1, 3);
/* Idle. The Master function is available to be used for a new transaction. */
#define FLEXCOMM_I2C_STAT_MSTSTATE_IDLE 0
/*
* Receive ready. Received data is available (in Master Receiver mode). Address
* plus Read was previously sent and Acknowledged by a slave.
*/
#define FLEXCOMM_I2C_STAT_MSTSTATE_RECEIVE_READY 1
/*
* Transmit ready. Data can be transmitted (in Master Transmitter mode).
* Address plus Write was previously sent and Acknowledged by a slave.
*/
#define FLEXCOMM_I2C_STAT_MSTSTATE_TRANSMIT_READY 2
/* NACK Address. Slave NACKed address. */
#define FLEXCOMM_I2C_STAT_MSTSTATE_NACK_ADDRESS 3
/* NACK Data. Slave NACKed transmitted data. */
#define FLEXCOMM_I2C_STAT_MSTSTATE_NACK_DATA 4
/* Interrupt Enable Set Register */
REG32(FLEXCOMM_I2C_INTENSET, 0x808);
/* Master Pending interrupt Enable */
FIELD(FLEXCOMM_I2C_INTENSET, MSTPENDINGEN, 0, 1);
/* Interrupt Enable Clear Register */
REG32(FLEXCOMM_I2C_INTENCLR, 0x80C);
/* Master Pending interrupt clear */
FIELD(FLEXCOMM_I2C_INTENCLR, MSTPENDINGCLR, 0, 1);
/* Time-out Register */
REG32(FLEXCOMM_I2C_TIMEOUT, 0x810);
/* Time-out time value, the bottom 4 bits */
FIELD(FLEXCOMM_I2C_TIMEOUT, TOMIN, 0, 4);
/* Interrupt Status Register */
REG32(FLEXCOMM_I2C_INTSTAT, 0x818);
/* Master Pending */
FIELD(FLEXCOMM_I2C_INTSTAT, MSTPENDING, 0, 1);
/* Master Control Register */
REG32(FLEXCOMM_I2C_MSTCTL, 0x820);
/* Master Continue(write-only) */
FIELD(FLEXCOMM_I2C_MSTCTL, MSTCONTINUE, 0, 1);
/* Master Start control(write-only) */
FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTART, 1, 1);
/* Master Stop control(write-only) */
FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTOP, 2, 1);
/* Master DMA enable */
FIELD(FLEXCOMM_I2C_MSTCTL, MSTDMA, 3, 1);
/* Master Data Register */
REG32(FLEXCOMM_I2C_MSTDAT, 0x828);
/* Master function data register */
FIELD(FLEXCOMM_I2C_MSTDAT, DATA, 0, 8);
/* Slave Control Register */
REG32(FLEXCOMM_I2C_SLVCTL, 0x840);
/* Slave Data Register */
REG32(FLEXCOMM_I2C_SLVDAT, 0x844);
/* Slave Address Register */
REG32(FLEXCOMM_I2C_SLVADR0, 0x848);
/* Slave Address Register */
REG32(FLEXCOMM_I2C_SLVADR1, 0x84C);
/* Slave Address Register */
REG32(FLEXCOMM_I2C_SLVADR2, 0x850);
/* Slave Address Register */
REG32(FLEXCOMM_I2C_SLVADR3, 0x854);
/* Slave Qualification for Address 0 Register */
REG32(FLEXCOMM_I2C_SLVQUAL0, 0x858);
#define FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(_name) \
struct RegisterAccessInfo _name[FLEXCOMM_I2C_REGS_NO] = { \
[0 ... FLEXCOMM_I2C_REGS_NO - 1] = { \
.name = "", \
.addr = -1, \
}, \
[0x200] = { \
.name = "CFG", \
.addr = 0x800, \
.ro = 0xFFFFFFC0, \
.reset = 0x0, \
}, \
[0x201] = { \
.name = "STAT", \
.addr = 0x804, \
.ro = 0xFCF57FAF, \
.reset = 0x801, \
}, \
[0x202] = { \
.name = "INTENSET", \
.addr = 0x808, \
.ro = 0xFCF476AE, \
.reset = 0x0, \
}, \
[0x203] = { \
.name = "INTENCLR", \
.addr = 0x80C, \
.ro = 0xFCF476AE, \
.reset = 0x0, \
}, \
[0x204] = { \
.name = "TIMEOUT", \
.addr = 0x810, \
.ro = 0xFFFF0000, \
.reset = 0xFFFF, \
}, \
[0x205] = { \
.name = "CLKDIV", \
.addr = 0x814, \
.ro = 0xFFFF0000, \
.reset = 0x0, \
}, \
[0x206] = { \
.name = "INTSTAT", \
.addr = 0x818, \
.ro = 0xFFFFFFFF, \
.reset = 0x801, \
}, \
[0x208] = { \
.name = "MSTCTL", \
.addr = 0x820, \
.ro = 0xFFFFFFF0, \
.reset = 0x0, \
}, \
[0x209] = { \
.name = "MSTTIME", \
.addr = 0x824, \
.ro = 0xFFFFFF88, \
.reset = 0x77, \
}, \
[0x20A] = { \
.name = "MSTDAT", \
.addr = 0x828, \
.ro = 0xFFFFFF00, \
.reset = 0x0, \
}, \
[0x210] = { \
.name = "SLVCTL", \
.addr = 0x840, \
.ro = 0xFFFFFCF4, \
.reset = 0x0, \
}, \
[0x211] = { \
.name = "SLVDAT", \
.addr = 0x844, \
.ro = 0xFFFFFF00, \
.reset = 0x0, \
}, \
[0x212] = { \
.name = "SLVADR0", \
.addr = 0x848, \
.ro = 0xFFFF7F00, \
.reset = 0x1, \
}, \
[0x213] = { \
.name = "SLVADR1", \
.addr = 0x84C, \
.ro = 0xFFFF7F00, \
.reset = 0x1, \
}, \
[0x214] = { \
.name = "SLVADR2", \
.addr = 0x850, \
.ro = 0xFFFF7F00, \
.reset = 0x1, \
}, \
[0x215] = { \
.name = "SLVADR3", \
.addr = 0x854, \
.ro = 0xFFFF7F00, \
.reset = 0x1, \
}, \
[0x216] = { \
.name = "SLVQUAL0", \
.addr = 0x858, \
.ro = 0xFFFFFF00, \
.reset = 0x0, \
}, \
[0x220] = { \
.name = "MONRXDAT", \
.addr = 0x880, \
.ro = 0xFFFFFFFF, \
.reset = 0x0, \
}, \
[0x3FF] = { \
.name = "ID", \
.addr = 0xFFC, \
.ro = 0xFFFFFFFF, \
.reset = 0xE0301300, \
}, \
}
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 08/25] hw/i2c: add support for flexcomm i2c
2024-09-20 18:02 ` Octavian Purdila
@ 2024-09-20 18:09 ` Corey Minyard
0 siblings, 0 replies; 36+ messages in thread
From: Corey Minyard @ 2024-09-20 18:09 UTC (permalink / raw)
To: Octavian Purdila
Cc: qemu-devel, qemu-arm, stefanst, pbonzini, marcandre.lureau,
berrange, eduardo, luc, damien.hedde, alistair, thuth, philmd,
jsnow, crosa, lvivier, Peter Maydell
Thanks, this all looks good to me. And FIELD() is the right way to
go, as Peter said.
-corey
On Fri, Sep 20, 2024 at 1:03 PM Octavian Purdila <tavip@google.com> wrote:
>
> On Thu, Sep 19, 2024 at 2:36 AM Peter Maydell <peter.maydell@linaro.org> wrote:
> >
> > On Wed, 18 Sept 2024 at 22:31, Corey Minyard <corey@minyard.net> wrote:
> > > Generally it's frowned upon to have a ton of extra stuff that's not
> > > used. I would think some is ok, like defining bits in registers that
> > > aren't used yet, but I have no idea how all the enums below here
> > > actually tie into anything. I'm guessing these are just bitmasks into
> > > registers, but really, it's a lot easier to read if you have something
> > > like:
> > >
> > > /*
> > > * The I2C Master function enable. When disabled, the Master
> > > * configuration settings are not changed, but the Master function is
> > > * internally reset.
> > > */
> > > #define FLEXCOMM_I2C_CFG_MSTEN (1 << 4)
> >
> > The FIELD macro already gives you that:
> > FIELD(FLEXCOMM_I2C_CFG, MSTEN, startbit, len);
> > will define an R_FLEXCOMM_I2C_CFG_MSTEN_MASK (which is
> > (1 << startbit) for the 'len == 1' case).
> >
> > You can also set and read a 1 bit field the same as
> > any other, with the FIELD_DP32/FIELD_EX32 macros, so
> > you don't often need to directly use the MASK macro:
> > s->cfg = FIELD_DP32(s->cfg, CFG, MSTEN, 1);
> > and
> > if (FIELD_EX32(s->cfg, CFG, MSTEN)) {
> > ...
> > }
> >
> > The FIELD() macros are a bit unwieldy sometimes but the
> > advantage over ad-hoc #defines is that they're consistent
> > for every field in every register.
> >
> > I agree that providing enums for the possible values for 1-bit
> > fields is a bit superfluous.
> >
>
> I went ahead and removed those 1-bit enum values and added support to
> filter register/fields when generating the code. Also converted the
> enums to defines to make these a little bit more compact as I don't
> think we have any advantage over the enums?
>
> So with the following invocation:
>
> run_target('svd-flexcomm-i2c', command: svd_gen_header +
> [ '-i', rt595, '-o', '@SOURCE_ROOT@/include/hw/arm/svd/flexcomm_i2c.h',
> '-p', 'I2C0', '-t', 'FLEXCOMM_I2C',
> '--fields', 'CFG TIMEOUT:TOMIN MSTCTL MSTDAT
> STAT:MSTPENDING,MSTSTATE INT*:MSTPENDING* SLV*:'])
>
> I am getting the below generated file. Note that the register info is
> generated for all registers because this information is used to
> initialize the reset values, mask writes appropriately in registers
> and trace register access.
>
> Please let me know if this looks good or if there are any other tweaks
> I could make.
>
> /*
> * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
> *
> * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
> */
> #pragma once
>
> #include "hw/register.h"
>
> /* I2C Bus Interface */
> #define FLEXCOMM_I2C_REGS_NO (1024)
>
> /* Configuration Register */
> REG32(FLEXCOMM_I2C_CFG, 0x800);
> /* Master Enable */
> FIELD(FLEXCOMM_I2C_CFG, MSTEN, 0, 1);
> /* Slave Enable */
> FIELD(FLEXCOMM_I2C_CFG, SLVEN, 1, 1);
> /* Monitor Enable */
> FIELD(FLEXCOMM_I2C_CFG, MONEN, 2, 1);
> /* I2C bus Time-out Enable */
> FIELD(FLEXCOMM_I2C_CFG, TIMEOUTEN, 3, 1);
> /* Monitor function Clock Stretching */
> FIELD(FLEXCOMM_I2C_CFG, MONCLKSTR, 4, 1);
> /* High Speed mode Capable enable */
> FIELD(FLEXCOMM_I2C_CFG, HSCAPABLE, 5, 1);
>
> /* Status Register */
> REG32(FLEXCOMM_I2C_STAT, 0x804);
> /* Master Pending */
> FIELD(FLEXCOMM_I2C_STAT, MSTPENDING, 0, 1);
> /* Master State code */
> FIELD(FLEXCOMM_I2C_STAT, MSTSTATE, 1, 3);
> /* Idle. The Master function is available to be used for a new transaction. */
> #define FLEXCOMM_I2C_STAT_MSTSTATE_IDLE 0
> /*
> * Receive ready. Received data is available (in Master Receiver mode). Address
> * plus Read was previously sent and Acknowledged by a slave.
> */
> #define FLEXCOMM_I2C_STAT_MSTSTATE_RECEIVE_READY 1
> /*
> * Transmit ready. Data can be transmitted (in Master Transmitter mode).
> * Address plus Write was previously sent and Acknowledged by a slave.
> */
> #define FLEXCOMM_I2C_STAT_MSTSTATE_TRANSMIT_READY 2
> /* NACK Address. Slave NACKed address. */
> #define FLEXCOMM_I2C_STAT_MSTSTATE_NACK_ADDRESS 3
> /* NACK Data. Slave NACKed transmitted data. */
> #define FLEXCOMM_I2C_STAT_MSTSTATE_NACK_DATA 4
>
> /* Interrupt Enable Set Register */
> REG32(FLEXCOMM_I2C_INTENSET, 0x808);
> /* Master Pending interrupt Enable */
> FIELD(FLEXCOMM_I2C_INTENSET, MSTPENDINGEN, 0, 1);
>
> /* Interrupt Enable Clear Register */
> REG32(FLEXCOMM_I2C_INTENCLR, 0x80C);
> /* Master Pending interrupt clear */
> FIELD(FLEXCOMM_I2C_INTENCLR, MSTPENDINGCLR, 0, 1);
>
> /* Time-out Register */
> REG32(FLEXCOMM_I2C_TIMEOUT, 0x810);
> /* Time-out time value, the bottom 4 bits */
> FIELD(FLEXCOMM_I2C_TIMEOUT, TOMIN, 0, 4);
>
> /* Interrupt Status Register */
> REG32(FLEXCOMM_I2C_INTSTAT, 0x818);
> /* Master Pending */
> FIELD(FLEXCOMM_I2C_INTSTAT, MSTPENDING, 0, 1);
>
> /* Master Control Register */
> REG32(FLEXCOMM_I2C_MSTCTL, 0x820);
> /* Master Continue(write-only) */
> FIELD(FLEXCOMM_I2C_MSTCTL, MSTCONTINUE, 0, 1);
> /* Master Start control(write-only) */
> FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTART, 1, 1);
> /* Master Stop control(write-only) */
> FIELD(FLEXCOMM_I2C_MSTCTL, MSTSTOP, 2, 1);
> /* Master DMA enable */
> FIELD(FLEXCOMM_I2C_MSTCTL, MSTDMA, 3, 1);
>
> /* Master Data Register */
> REG32(FLEXCOMM_I2C_MSTDAT, 0x828);
> /* Master function data register */
> FIELD(FLEXCOMM_I2C_MSTDAT, DATA, 0, 8);
>
> /* Slave Control Register */
> REG32(FLEXCOMM_I2C_SLVCTL, 0x840);
>
> /* Slave Data Register */
> REG32(FLEXCOMM_I2C_SLVDAT, 0x844);
>
> /* Slave Address Register */
> REG32(FLEXCOMM_I2C_SLVADR0, 0x848);
>
> /* Slave Address Register */
> REG32(FLEXCOMM_I2C_SLVADR1, 0x84C);
>
> /* Slave Address Register */
> REG32(FLEXCOMM_I2C_SLVADR2, 0x850);
>
> /* Slave Address Register */
> REG32(FLEXCOMM_I2C_SLVADR3, 0x854);
>
> /* Slave Qualification for Address 0 Register */
> REG32(FLEXCOMM_I2C_SLVQUAL0, 0x858);
>
>
> #define FLEXCOMM_I2C_REGISTER_ACCESS_INFO_ARRAY(_name) \
> struct RegisterAccessInfo _name[FLEXCOMM_I2C_REGS_NO] = { \
> [0 ... FLEXCOMM_I2C_REGS_NO - 1] = { \
> .name = "", \
> .addr = -1, \
> }, \
> [0x200] = { \
> .name = "CFG", \
> .addr = 0x800, \
> .ro = 0xFFFFFFC0, \
> .reset = 0x0, \
> }, \
> [0x201] = { \
> .name = "STAT", \
> .addr = 0x804, \
> .ro = 0xFCF57FAF, \
> .reset = 0x801, \
> }, \
> [0x202] = { \
> .name = "INTENSET", \
> .addr = 0x808, \
> .ro = 0xFCF476AE, \
> .reset = 0x0, \
> }, \
> [0x203] = { \
> .name = "INTENCLR", \
> .addr = 0x80C, \
> .ro = 0xFCF476AE, \
> .reset = 0x0, \
> }, \
> [0x204] = { \
> .name = "TIMEOUT", \
> .addr = 0x810, \
> .ro = 0xFFFF0000, \
> .reset = 0xFFFF, \
> }, \
> [0x205] = { \
> .name = "CLKDIV", \
> .addr = 0x814, \
> .ro = 0xFFFF0000, \
> .reset = 0x0, \
> }, \
> [0x206] = { \
> .name = "INTSTAT", \
> .addr = 0x818, \
> .ro = 0xFFFFFFFF, \
> .reset = 0x801, \
> }, \
> [0x208] = { \
> .name = "MSTCTL", \
> .addr = 0x820, \
> .ro = 0xFFFFFFF0, \
> .reset = 0x0, \
> }, \
> [0x209] = { \
> .name = "MSTTIME", \
> .addr = 0x824, \
> .ro = 0xFFFFFF88, \
> .reset = 0x77, \
> }, \
> [0x20A] = { \
> .name = "MSTDAT", \
> .addr = 0x828, \
> .ro = 0xFFFFFF00, \
> .reset = 0x0, \
> }, \
> [0x210] = { \
> .name = "SLVCTL", \
> .addr = 0x840, \
> .ro = 0xFFFFFCF4, \
> .reset = 0x0, \
> }, \
> [0x211] = { \
> .name = "SLVDAT", \
> .addr = 0x844, \
> .ro = 0xFFFFFF00, \
> .reset = 0x0, \
> }, \
> [0x212] = { \
> .name = "SLVADR0", \
> .addr = 0x848, \
> .ro = 0xFFFF7F00, \
> .reset = 0x1, \
> }, \
> [0x213] = { \
> .name = "SLVADR1", \
> .addr = 0x84C, \
> .ro = 0xFFFF7F00, \
> .reset = 0x1, \
> }, \
> [0x214] = { \
> .name = "SLVADR2", \
> .addr = 0x850, \
> .ro = 0xFFFF7F00, \
> .reset = 0x1, \
> }, \
> [0x215] = { \
> .name = "SLVADR3", \
> .addr = 0x854, \
> .ro = 0xFFFF7F00, \
> .reset = 0x1, \
> }, \
> [0x216] = { \
> .name = "SLVQUAL0", \
> .addr = 0x858, \
> .ro = 0xFFFFFF00, \
> .reset = 0x0, \
> }, \
> [0x220] = { \
> .name = "MONRXDAT", \
> .addr = 0x880, \
> .ro = 0xFFFFFFFF, \
> .reset = 0x0, \
> }, \
> [0x3FF] = { \
> .name = "ID", \
> .addr = 0xFFC, \
> .ro = 0xFFFFFFFF, \
> .reset = 0xE0301300, \
> }, \
> }
^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2024-09-20 18:10 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-18 19:22 [PATCH 00/25] NXP i.MX RT595 Octavian Purdila
2024-09-18 19:22 ` [PATCH 01/25] fifo32: add peek function Octavian Purdila
2024-09-18 19:22 ` [PATCH 02/25] tests/unit: add fifo32 tests Octavian Purdila
2024-09-18 19:22 ` [PATCH 03/25] scripts: add script to generate C header files from SVD XML files Octavian Purdila
2024-09-18 19:22 ` [PATCH 04/25] Add mcux-soc-svd subproject Octavian Purdila
2024-09-18 19:22 ` [PATCH 05/25] hw/misc: add support for flexcomm Octavian Purdila
2024-09-18 19:22 ` [PATCH 06/25] hw/misc/flexcomm.c: add common fifo functionality Octavian Purdila
2024-09-18 19:22 ` [PATCH 07/25] hw/char: add support for flexcomm usart Octavian Purdila
2024-09-18 19:22 ` [PATCH 08/25] hw/i2c: add support for flexcomm i2c Octavian Purdila
2024-09-18 20:17 ` Corey Minyard
2024-09-18 21:04 ` Octavian Purdila
2024-09-18 21:31 ` Corey Minyard
2024-09-18 22:25 ` Octavian Purdila
2024-09-19 9:36 ` Peter Maydell
2024-09-20 18:02 ` Octavian Purdila
2024-09-20 18:09 ` Corey Minyard
2024-09-18 19:22 ` [PATCH 09/25] hw/ssi: add support for flexcomm spi Octavian Purdila
2024-09-18 19:22 ` [PATCH 10/25] hw/misc: add support for RT500's clock controller Octavian Purdila
2024-09-18 19:22 ` [PATCH 11/25] hw/ssi: add support for flexspi Octavian Purdila
2024-09-18 19:22 ` [PATCH 12/25] hw/misc: add support for RT500's reset controller Octavian Purdila
2024-09-18 19:22 ` [PATCH 13/25] hw/arm: add basic support for the RT500 SoC Octavian Purdila
2024-09-18 19:22 ` [PATCH 14/25] hw/arm: add RT595-EVK board Octavian Purdila
2024-09-18 19:22 ` [PATCH 15/25] tests/qtest: add register access macros and functions Octavian Purdila
2024-09-18 19:22 ` [PATCH 16/25] system/qtest: add APIS to check for memory access failures Octavian Purdila
2024-09-18 19:22 ` [PATCH 17/25] tests/qtest: add flexcomm tests Octavian Purdila
2024-09-18 19:22 ` [PATCH 18/25] tests/qtest: add flexcomm usart tests Octavian Purdila
2024-09-18 19:22 ` [PATCH 19/25] hw/misc: add i2c-tester Octavian Purdila
2024-09-18 20:05 ` Corey Minyard
2024-09-18 23:03 ` Octavian Purdila
2024-09-18 23:52 ` Corey Minyard
2024-09-18 19:22 ` [PATCH 20/25] tests/qtest: add tests for flexcomm i2c Octavian Purdila
2024-09-18 19:22 ` [PATCH 21/25] hw/ssi: allow NULL realize callbacks for peripherals Octavian Purdila
2024-09-18 19:22 ` [PATCH 22/25] hw/misc: add spi-tester Octavian Purdila
2024-09-18 19:22 ` [PATCH 23/25] tests/qtest: add tests for flexcomm spi Octavian Purdila
2024-09-18 19:22 ` [PATCH 24/25] systems/qtest: add device clock APIs Octavian Purdila
2024-09-18 19:22 ` [PATCH 25/25] tests/qtest: add tests for RT500's clock controller Octavian Purdila
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).