From b2f1f64f57574eb89f155f92079b93e9aed5a29f Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Fri, 10 Mar 2023 17:58:41 +0200 Subject: [PATCH] boards: xtensa: nxp_adsp_imx8m: Add UART support for the ADSP from i.MX8MP Enable UART on the DSP from the i.MX8MP target: - add corresponding nodes in dtsi and dts; - create a dts overlay for uart; - add a config fragment for uart and console configuration. So, in order to compile an application and enable UART a user must run west build using DTC_OVERLAY_FILE and CONF_FILE. Here's an example for hello_world: west build -p always -b nxp_adsp_imx8m samples/hello_world/ -DDTC_OVERLAY_FILE="boards/xtensa/nxp_adsp_imx8m/ nxp_adsp_imx8m_uart.overlay" -DCONF_FILE="boards/xtensa/nxp_adsp_imx8m/ nxp_adsp_imx8m_uart.conf" For other applications, like SOF, where we don't need UART, we simply run: west build -p always -b nxp_adsp_imx8m ../modules/audio/sof/ -- -DTOOLCHAIN=/opt/zephyr-sdk-0.15.2/xtensa-nxp_imx8m_adsp_zephyr-elf/ bin/xtensa-nxp_imx8m_adsp_zephyr-elf -DINIT_CONFIG=imx8m_defconfig The nxp_adsp_imx8m is using the nxp_imx_iuart driver. For now, is used in poll mode. Next step is to enable the interrupt controller in DSP and use the interrupt driver UART. Signed-off-by: Iuliana Prodan --- .../xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.dts | 13 +++ .../xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml | 2 + .../nxp_adsp_imx8m/nxp_adsp_imx8m_uart.conf | 7 ++ .../nxp_adsp_imx8m_uart.overlay | 19 +++++ dts/xtensa/nxp/nxp_imx8m.dtsi | 30 +++++++ modules/Kconfig.mcux | 2 +- soc/xtensa/nxp_adsp/imx8m/Kconfig.soc | 4 + .../nxp_adsp/imx8m/include/pinctrl_soc.h | 83 +++++++++++++++++++ 8 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m_uart.conf create mode 100644 boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m_uart.overlay create mode 100644 soc/xtensa/nxp_adsp/imx8m/include/pinctrl_soc.h diff --git a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.dts b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.dts index ae1b38ba379..2bef950b764 100644 --- a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.dts +++ b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.dts @@ -7,6 +7,7 @@ /dts-v1/; #include +#include / { model = "nxp_adsp_imx8m"; @@ -16,3 +17,15 @@ zephyr,sram = &sram0; }; }; + +&pinctrl { + /omit-if-no-ref/ uart4_default: uart4_default { + group0 { + pinmux = <&iomuxc_uart4_rxd_uart_rx_uart4_rx>, + <&iomuxc_uart4_txd_uart_tx_uart4_tx>; + bias-pull-up; + slew-rate = "slow"; + drive-strength = "x1"; + }; + }; +}; diff --git a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml index 195747a280f..517073dda94 100644 --- a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml +++ b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m.yaml @@ -8,3 +8,5 @@ testing: only_tags: - kernel - sof +supported: + - uart diff --git a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m_uart.conf b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m_uart.conf new file mode 100644 index 00000000000..e662fa1f4b7 --- /dev/null +++ b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m_uart.conf @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CLOCK_CONTROL=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_PINCTRL=y diff --git a/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m_uart.overlay b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m_uart.overlay new file mode 100644 index 00000000000..1aa2656e512 --- /dev/null +++ b/boards/xtensa/nxp_adsp_imx8m/nxp_adsp_imx8m_uart.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,console = &uart4; + zephyr,shell-uart = &uart4; + }; +}; + +&uart4 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart4_default>; + pinctrl-names = "default"; +}; diff --git a/dts/xtensa/nxp/nxp_imx8m.dtsi b/dts/xtensa/nxp/nxp_imx8m.dtsi index 06b38e1bbee..badbd5ac858 100644 --- a/dts/xtensa/nxp/nxp_imx8m.dtsi +++ b/dts/xtensa/nxp/nxp_imx8m.dtsi @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include @@ -30,4 +31,33 @@ compatible = "mmio-sram"; reg = <0x92c00000 DT_SIZE_K(512)>; }; + + soc { + ccm: ccm@30380000 { + compatible = "nxp,imx-ccm"; + reg = <0x30380000 DT_SIZE_K(64)>; + #clock-cells = <3>; + }; + + iomuxc: iomuxc@30330000 { + compatible = "nxp,imx-iomuxc"; + reg = <0x30330000 DT_SIZE_K(64)>; + status = "okay"; + pinctrl: pinctrl { + status = "okay"; + compatible = "nxp,imx8mp-pinctrl"; + }; + }; + + /* + * For now only UART4 is supported and + * tested with the serial driver + */ + uart4: uart@30a60000 { + compatible = "nxp,imx-iuart"; + reg = <0x30a60000 0x10000>; + clocks = <&ccm IMX_CCM_UART4_CLK 0x6c 24>; + status = "disabled"; + }; + }; }; diff --git a/modules/Kconfig.mcux b/modules/Kconfig.mcux index fdd1a5806b1..25c51146333 100644 --- a/modules/Kconfig.mcux +++ b/modules/Kconfig.mcux @@ -6,7 +6,7 @@ config HAS_MCUX bool select HAS_CMSIS_CORE - depends on SOC_FAMILY_KINETIS || SOC_FAMILY_IMX || SOC_FAMILY_LPC + depends on SOC_FAMILY_KINETIS || SOC_FAMILY_IMX || SOC_FAMILY_LPC || SOC_FAMILY_NXP_ADSP if HAS_MCUX diff --git a/soc/xtensa/nxp_adsp/imx8m/Kconfig.soc b/soc/xtensa/nxp_adsp/imx8m/Kconfig.soc index f2752cf2b29..5ad3c1b9b1e 100644 --- a/soc/xtensa/nxp_adsp/imx8m/Kconfig.soc +++ b/soc/xtensa/nxp_adsp/imx8m/Kconfig.soc @@ -7,6 +7,10 @@ choice config SOC_MIMX8M_ADSP bool "NXP i.MX8MP Audio DSP" + select HAS_MCUX if CLOCK_CONTROL + select HAS_MCUX_CCM if CLOCK_CONTROL + select HAS_MCUX_IOMUXC if PINCTRL + select PINCTRL_IMX if HAS_MCUX_IOMUXC endchoice diff --git a/soc/xtensa/nxp_adsp/imx8m/include/pinctrl_soc.h b/soc/xtensa/nxp_adsp/imx8m/include/pinctrl_soc.h new file mode 100644 index 00000000000..d91b28fedd3 --- /dev/null +++ b/soc/xtensa/nxp_adsp/imx8m/include/pinctrl_soc.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2023, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_XTENSA_NXP_IMX8M_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_XTENSA_NXP_IMX8M_PINCTRL_SOC_H_ + +#include +#include +#include "fsl_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MCUX_IMX_INPUT_SCHMITT_ENABLE_SHIFT IOMUXC_SW_PAD_CTL_PAD_HYS_SHIFT +#define MCUX_IMX_BIAS_PULL_UP_SHIFT IOMUXC_SW_PAD_CTL_PAD_PUE_SHIFT +#define MCUX_IMX_BIAS_PULL_ENABLE_SHIFT IOMUXC_SW_PAD_CTL_PAD_PE_SHIFT +#define MCUX_IMX_DRIVE_OPEN_DRAIN_SHIFT IOMUXC_SW_PAD_CTL_PAD_ODE_SHIFT +#define MCUX_IMX_SLEW_RATE_SHIFT IOMUXC_SW_PAD_CTL_PAD_FSEL_SHIFT +#define MCUX_IMX_DRIVE_STRENGTH_SHIFT IOMUXC_SW_PAD_CTL_PAD_DSE_SHIFT +#define MCUX_IMX_INPUT_ENABLE_SHIFT 31 /* Shift to a bit not used by IOMUXC_SW_PAD_CTL */ +#define MCUX_IMX_INPUT_ENABLE(x) ((x >> MCUX_IMX_INPUT_ENABLE_SHIFT) & 0x1) + +#define Z_PINCTRL_MCUX_IMX_PINCFG_INIT(node_id) \ + ((DT_PROP(node_id, input_schmitt_enable) << MCUX_IMX_INPUT_SCHMITT_ENABLE_SHIFT) | \ + (DT_PROP(node_id, bias_pull_up) << MCUX_IMX_BIAS_PULL_UP_SHIFT) | \ + ((DT_PROP(node_id, bias_pull_up) | DT_PROP(node_id, bias_pull_down)) \ + << MCUX_IMX_BIAS_PULL_ENABLE_SHIFT) | \ + (DT_PROP(node_id, drive_open_drain) << MCUX_IMX_DRIVE_OPEN_DRAIN_SHIFT) | \ + (DT_ENUM_IDX(node_id, drive_strength) << MCUX_IMX_DRIVE_STRENGTH_SHIFT) | \ + (DT_ENUM_IDX(node_id, slew_rate) << MCUX_IMX_SLEW_RATE_SHIFT) | \ + (DT_PROP(node_id, input_enable) << MCUX_IMX_INPUT_ENABLE_SHIFT)) + + +/* This struct must be present. It is used by the mcux gpio driver */ +struct pinctrl_soc_pinmux { + uint32_t mux_register; /*!< IOMUXC SW_PAD_MUX register */ + uint32_t config_register; /*!< IOMUXC SW_PAD_CTL register */ + uint32_t input_register; /*!< IOMUXC SELECT_INPUT DAISY register */ + uint8_t mux_mode: 4; /*!< Mux value for SW_PAD_MUX register */ + uint32_t input_daisy:4; /*!< Mux value for SELECT_INPUT_DAISY register */ +}; + +struct pinctrl_soc_pin { + struct pinctrl_soc_pinmux pinmux; + uint32_t pin_ctrl_flags; /*!< value to write to IOMUXC_SW_PAD_CTL register */ +}; + +typedef struct pinctrl_soc_pin pinctrl_soc_pin_t; + +/* This definition must be present. It is used by the mcux gpio driver */ +#define MCUX_IMX_PINMUX(node_id) \ + { \ + .mux_register = DT_PROP_BY_IDX(node_id, pinmux, 0), \ + .config_register = DT_PROP_BY_IDX(node_id, pinmux, 4), \ + .input_register = DT_PROP_BY_IDX(node_id, pinmux, 2), \ + .mux_mode = DT_PROP_BY_IDX(node_id, pinmux, 1), \ + .input_daisy = DT_PROP_BY_IDX(node_id, pinmux, 3), \ + } + +#define Z_PINCTRL_PINMUX(group_id, pin_prop, idx) \ + MCUX_IMX_PINMUX(DT_PHANDLE_BY_IDX(group_id, pin_prop, idx)) + +#define Z_PINCTRL_STATE_PIN_INIT(group_id, pin_prop, idx) \ + { \ + .pinmux = Z_PINCTRL_PINMUX(group_id, pin_prop, idx), \ + .pin_ctrl_flags = Z_PINCTRL_MCUX_IMX_PINCFG_INIT(group_id), \ + }, + + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \ + DT_FOREACH_PROP_ELEM, pinmux, Z_PINCTRL_STATE_PIN_INIT)}; \ + + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_XTENSA_NXP_IMX8M_PINCTRL_SOC_H_ */