drivers: misc: Add nxp,rtxxx-dsp-ctrl
Add the nxp,rtxxx-dsp-ctrl driver. Responsibility of this driver is to load code executed by Xtensa-family cores on NXP i.MX RTxxx microcontrollers and to control their run. Signed-off-by: Vit Stanicek <vit.stanicek@nxp.com>
This commit is contained in:
parent
50e0123d47
commit
37ec78f3dc
8 changed files with 265 additions and 0 deletions
|
@ -11,4 +11,6 @@ add_subdirectory_ifdef(CONFIG_DEVMUX devmux)
|
|||
add_subdirectory_ifdef(CONFIG_NORDIC_VPR_LAUNCHER nordic_vpr_launcher)
|
||||
add_subdirectory_ifdef(CONFIG_MCUX_FLEXIO mcux_flexio)
|
||||
add_subdirectory_ifdef(CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT renesas_ra_external_interrupt)
|
||||
add_subdirectory_ifdef(CONFIG_NXP_RTXXX_DSP_CTRL nxp_rtxxx_dsp_ctrl)
|
||||
|
||||
add_subdirectory(coresight)
|
||||
|
|
|
@ -16,5 +16,6 @@ source "drivers/misc/nordic_vpr_launcher/Kconfig"
|
|||
source "drivers/misc/mcux_flexio/Kconfig"
|
||||
source "drivers/misc/coresight/Kconfig"
|
||||
source "drivers/misc/renesas_ra_external_interrupt/Kconfig"
|
||||
source "drivers/misc/nxp_rtxxx_dsp_ctrl/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
10
drivers/misc/nxp_rtxxx_dsp_ctrl/CMakeLists.txt
Normal file
10
drivers/misc/nxp_rtxxx_dsp_ctrl/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright 2025 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/misc/nxp_rtxxx_dsp_ctrl/nxp_rtxxx_dsp_ctrl.h)
|
||||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_NXP_RTXXX_DSP_CTRL
|
||||
nxp_rtxxx_dsp_ctrl.c
|
||||
)
|
9
drivers/misc/nxp_rtxxx_dsp_ctrl/Kconfig
Normal file
9
drivers/misc/nxp_rtxxx_dsp_ctrl/Kconfig
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright 2025 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config NXP_RTXXX_DSP_CTRL
|
||||
bool "NXP i.MX RTxxx DSP control"
|
||||
depends on DT_HAS_NXP_RTXXX_DSP_CTRL_ENABLED
|
||||
default y
|
||||
help
|
||||
Enables a DSP control driver for NXP i.MX RTxxx devices.
|
118
drivers/misc/nxp_rtxxx_dsp_ctrl/nxp_rtxxx_dsp_ctrl.c
Normal file
118
drivers/misc/nxp_rtxxx_dsp_ctrl/nxp_rtxxx_dsp_ctrl.c
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright 2025 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT nxp_rtxxx_dsp_ctrl
|
||||
|
||||
#include <zephyr/drivers/misc/nxp_rtxxx_dsp_ctrl/nxp_rtxxx_dsp_ctrl.h>
|
||||
#include <zephyr/dt-bindings/misc/nxp_rtxxx_dsp_ctrl.h>
|
||||
|
||||
#include <fsl_device_registers.h>
|
||||
#include <fsl_dsp.h>
|
||||
#include <fsl_clock.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <zephyr/init.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
|
||||
struct nxp_rtxxx_dsp_ctrl_region {
|
||||
void *base;
|
||||
int32_t length;
|
||||
};
|
||||
|
||||
struct nxp_rtxxx_dsp_ctrl_config {
|
||||
SYSCTL0_Type *sysctl;
|
||||
struct nxp_rtxxx_dsp_ctrl_region regions[NXP_RTXXX_DSP_REGION_MAX];
|
||||
};
|
||||
|
||||
static void dsp_ctrl_enable(const struct device *dev)
|
||||
{
|
||||
SYSCTL0_Type *sysctl = ((struct nxp_rtxxx_dsp_ctrl_config *)dev->config)->sysctl;
|
||||
|
||||
sysctl->DSPSTALL = 0;
|
||||
}
|
||||
|
||||
static void dsp_ctrl_disable(const struct device *dev)
|
||||
{
|
||||
SYSCTL0_Type *sysctl = ((struct nxp_rtxxx_dsp_ctrl_config *)dev->config)->sysctl;
|
||||
|
||||
sysctl->DSPSTALL = 1;
|
||||
}
|
||||
|
||||
static int dsp_ctrl_load_section(const struct device *dev, const void *base, size_t length,
|
||||
enum nxp_rtxxx_dsp_ctrl_section_type section)
|
||||
{
|
||||
if (section >= NXP_RTXXX_DSP_REGION_MAX) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
const struct nxp_rtxxx_dsp_ctrl_config *cfg =
|
||||
(const struct nxp_rtxxx_dsp_ctrl_config *)dev->config;
|
||||
|
||||
if (cfg->regions[section].base == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (length > cfg->regions[section].length) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom memcpy implementation is needed because the DSP TCMs can be accessed
|
||||
* only by 32 bits.
|
||||
*/
|
||||
const uint32_t *src = (const uint32_t *)base;
|
||||
uint32_t *dst = cfg->regions[section].base;
|
||||
|
||||
for (size_t remaining = length; remaining > 0; remaining -= sizeof(uint32_t)) {
|
||||
*dst++ = *src++;
|
||||
|
||||
if (remaining < sizeof(uint32_t)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nxp_rtxxx_dsp_ctrl_init(const struct device *dev)
|
||||
{
|
||||
/*
|
||||
* Initialize clocks associated with the DSP.
|
||||
* Taken from DSP examples for the MIMXRT685-EVK in the MCUXpresso SDK.
|
||||
*/
|
||||
CLOCK_InitSysPfd(kCLOCK_Pfd1, 16);
|
||||
CLOCK_AttachClk(kDSP_PLL_to_DSP_MAIN_CLK);
|
||||
CLOCK_SetClkDiv(kCLOCK_DivDspCpuClk, 1);
|
||||
CLOCK_SetClkDiv(kCLOCK_DivDspRamClk, 2);
|
||||
|
||||
DSP_Init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct nxp_rtxxx_dsp_ctrl_api nxp_rtxxx_dsp_ctrl_api = {
|
||||
.load_section = dsp_ctrl_load_section,
|
||||
.enable = dsp_ctrl_enable,
|
||||
.disable = dsp_ctrl_disable
|
||||
};
|
||||
|
||||
#define NXP_RTXXX_DSP_SECTION(child_node_id, n) \
|
||||
[DT_PROP(child_node_id, type)] = { \
|
||||
.base = (void *)DT_REG_ADDR(child_node_id), \
|
||||
.length = DT_REG_SIZE(child_node_id) \
|
||||
},
|
||||
|
||||
#define NXP_RTXXX_DSP_CTRL(n) \
|
||||
static const struct nxp_rtxxx_dsp_ctrl_config nxp_rtxxx_dsp_ctrl_##n##_config = { \
|
||||
.sysctl = (SYSCTL0_Type *)DT_REG_ADDR(DT_INST_PHANDLE(n, sysctl)), \
|
||||
.regions = {DT_INST_FOREACH_CHILD_VARGS(n, NXP_RTXXX_DSP_SECTION, n)}}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, nxp_rtxxx_dsp_ctrl_init, NULL, NULL, \
|
||||
&nxp_rtxxx_dsp_ctrl_##n##_config, PRE_KERNEL_1, \
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &nxp_rtxxx_dsp_ctrl_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(NXP_RTXXX_DSP_CTRL);
|
31
dts/bindings/misc/nxp,rtxxx-dsp-ctrl.yaml
Normal file
31
dts/bindings/misc/nxp,rtxxx-dsp-ctrl.yaml
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Copyright (c) 2025 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
include: [base.yaml]
|
||||
|
||||
compatible: "nxp,rtxxx-dsp-ctrl"
|
||||
description: NXP i.MX RTxxx DSP control driver
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
"#size-cells":
|
||||
const: 1
|
||||
sysctl:
|
||||
required: true
|
||||
type: phandle
|
||||
description: phandle to a SYSCTL node
|
||||
|
||||
child-binding:
|
||||
description: Memory region definition
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
type: array
|
||||
description: Base address and length of a memory region
|
||||
|
||||
type:
|
||||
required: true
|
||||
type: int
|
||||
description: Memory region type (NXP_RTXXX_DSP_REGION_*)
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright 2025 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/dt-bindings/misc/nxp_rtxxx_dsp_ctrl.h>
|
||||
|
||||
#ifndef __NXP_RTXXX_DSP_CTRL_H__
|
||||
#define __NXP_RTXXX_DSP_CTRL_H__
|
||||
|
||||
/**
|
||||
* @brief Describes an image section type selection.
|
||||
*/
|
||||
enum nxp_rtxxx_dsp_ctrl_section_type {
|
||||
NXP_RTXXX_DSP_CTRL_SECTION_RESET = NXP_RTXXX_DSP_REGION_RESET,
|
||||
NXP_RTXXX_DSP_CTRL_SECTION_TEXT = NXP_RTXXX_DSP_REGION_TEXT,
|
||||
NXP_RTXXX_DSP_CTRL_SECTION_DATA = NXP_RTXXX_DSP_REGION_DATA
|
||||
};
|
||||
|
||||
typedef int (*nxp_rtxxx_dsp_ctrl_api_load_section)(
|
||||
const struct device *,
|
||||
const void *,
|
||||
size_t,
|
||||
enum nxp_rtxxx_dsp_ctrl_section_type
|
||||
);
|
||||
typedef void (*nxp_rtxxx_dsp_ctrl_api_enable)(const struct device *dev);
|
||||
typedef void (*nxp_rtxxx_dsp_ctrl_api_disable)(const struct device *dev);
|
||||
|
||||
struct nxp_rtxxx_dsp_ctrl_api {
|
||||
nxp_rtxxx_dsp_ctrl_api_load_section load_section;
|
||||
nxp_rtxxx_dsp_ctrl_api_enable enable;
|
||||
nxp_rtxxx_dsp_ctrl_api_disable disable;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Loads a specified image representing a specified section to a particular region in the
|
||||
* DSP's memory.
|
||||
*
|
||||
* @param dev DSP device
|
||||
* @param base Base pointer of the image to load
|
||||
* @param length Length of the image
|
||||
* @param section Section type which specified image represents
|
||||
* @return int 0 on success, -EINVAL for invalid parameters, -ENOMEM for image bigger than the
|
||||
* target region
|
||||
*/
|
||||
static inline int nxp_rtxxx_dsp_ctrl_load_section(
|
||||
const struct device *dev,
|
||||
const void *base,
|
||||
size_t length,
|
||||
enum nxp_rtxxx_dsp_ctrl_section_type section
|
||||
)
|
||||
{
|
||||
return ((struct nxp_rtxxx_dsp_ctrl_api *)dev->api)
|
||||
->load_section(dev, base, length, section);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts (unstalls) the DSP.
|
||||
*
|
||||
* @param dev DSP device
|
||||
*/
|
||||
static inline void nxp_rtxxx_dsp_ctrl_enable(const struct device *dev)
|
||||
{
|
||||
((struct nxp_rtxxx_dsp_ctrl_api *)dev->api)->enable(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops (stalls) the DSP.
|
||||
*
|
||||
* @param dev DSP device
|
||||
*/
|
||||
static inline void nxp_rtxxx_dsp_ctrl_disable(const struct device *dev)
|
||||
{
|
||||
((struct nxp_rtxxx_dsp_ctrl_api *)dev->api)->disable(dev);
|
||||
}
|
||||
|
||||
#endif
|
15
include/zephyr/dt-bindings/misc/nxp_rtxxx_dsp_ctrl.h
Normal file
15
include/zephyr/dt-bindings/misc/nxp_rtxxx_dsp_ctrl.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright 2025 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __NXP_RTXXX_DSP_CTRL_DT_CONST_H__
|
||||
#define __NXP_RTXXX_DSP_CTRL_DT_CONST_H__
|
||||
|
||||
#define NXP_RTXXX_DSP_REGION_RESET 0
|
||||
#define NXP_RTXXX_DSP_REGION_TEXT 1
|
||||
#define NXP_RTXXX_DSP_REGION_DATA 2
|
||||
#define NXP_RTXXX_DSP_REGION_MAX 3
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue