Browse Source
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>pull/90277/head
8 changed files with 265 additions and 0 deletions
@ -0,0 +1,10 @@
@@ -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 |
||||
) |
@ -0,0 +1,9 @@
@@ -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. |
@ -0,0 +1,118 @@
@@ -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); |
@ -0,0 +1,31 @@
@@ -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 @@
@@ -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 |
@ -0,0 +1,15 @@
@@ -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…
Reference in new issue