diff --git a/boards/nxp/s32k148_evb/Kconfig.defconfig b/boards/nxp/s32k148_evb/Kconfig.defconfig new file mode 100644 index 000000000000..2d0ab9d9263d --- /dev/null +++ b/boards/nxp/s32k148_evb/Kconfig.defconfig @@ -0,0 +1,13 @@ +# Copyright 2023-2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_S32K148_EVB + +if SERIAL + +config UART_CONSOLE + default y + +endif # SERIAL + +endif # BOARD_S32K148_EVB diff --git a/boards/nxp/s32k148_evb/Kconfig.s32k148_evb b/boards/nxp/s32k148_evb/Kconfig.s32k148_evb new file mode 100644 index 000000000000..50f931e7b76a --- /dev/null +++ b/boards/nxp/s32k148_evb/Kconfig.s32k148_evb @@ -0,0 +1,6 @@ +# Copyright 2023-2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_S32K148_EVB + select SOC_S32K148 + select SOC_PART_NUMBER_FS32K148HAT0MLUT diff --git a/boards/nxp/s32k148_evb/board.yml b/boards/nxp/s32k148_evb/board.yml new file mode 100644 index 000000000000..90d9decc827e --- /dev/null +++ b/boards/nxp/s32k148_evb/board.yml @@ -0,0 +1,6 @@ +board: + name: s32k148_evb + full_name: S32K148EVB-Q176 + vendor: nxp + socs: + - name: s32k148 diff --git a/boards/nxp/s32k148_evb/doc/img/s32k148_evb.jpg b/boards/nxp/s32k148_evb/doc/img/s32k148_evb.jpg new file mode 100644 index 000000000000..1c2c1db112fa Binary files /dev/null and b/boards/nxp/s32k148_evb/doc/img/s32k148_evb.jpg differ diff --git a/boards/nxp/s32k148_evb/doc/index.rst b/boards/nxp/s32k148_evb/doc/index.rst new file mode 100644 index 000000000000..d7a6a9f029e8 --- /dev/null +++ b/boards/nxp/s32k148_evb/doc/index.rst @@ -0,0 +1,203 @@ +.. zephyr:board:: s32k148_evb + +Overview +******** + +`NXP S32K148-Q176`_ is a low-cost evaluation and development board for general-purpose industrial +and automotive applications. +The S32K148-Q176 is based on the 32-bit Arm Cortex-M4F `NXP S32K148`_ microcontroller. +The onboard OpenSDA serial and debug adapter, running a mass storage device (MSD) bootloader +and a collection of OpenSDA Applications, offers options for serial communication, +flash programming, and run-control debugging. +It is a bridge between a USB host and the embedded target processor. + +Hardware +******** + +- NXP S32K148 + - Arm Cortex-M4F @ up to 112 Mhz + - 1.5 MB Flash + - 256 KB SRAM + - up to 127 I/Os + - 3x FlexCAN with FD + - eDMA, 12-bit ADC, MPU, ECC and more. + +- Interfaces: + - CAN, LIN, UART/SCI + - Ethernet connector compatible with different ethernet daughter cards + - 2 touchpads, potentiometer, user RGB LED and 2 buttons. + +More information about the hardware and design resources can be found at +`NXP S32K148-Q176`_ website. + +Supported Features +================== + +The ``s32k148_evb`` board configuration supports the following hardware features: + ++-----------+------------+------------------+ +| Interface | Controller | Driver/Component | ++===========+============+==================+ +| SYSMPU | on-chip | mpu | ++-----------+------------+------------------+ +| PORT | on-chip | pinctrl | ++-----------+------------+------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+------------------+ +| LPUART | on-chip | serial | ++-----------+------------+------------------+ +| FTM | on-chip | pwm | ++-----------+------------+------------------+ +| FlexCAN | on-chip | can | ++-----------+------------+------------------+ +| Watchdog | on-chip | watchdog | ++-----------+------------+------------------+ +| RTC | on-chip | counter | ++-----------+------------+------------------+ +| ADC | on-chip | adc | ++-----------+------------+------------------+ + +The default configuration can be found in the Kconfig file +:zephyr_file:`boards/nxp/s32k148_evb/s32k148_evb_defconfig`. + +.. note:: + Before using the Ethernet interface, please take note of the following: + - For boards with the part number ``LSF24D`` at ``U16``, ``R553`` needs to be depopulated. + +Connections and IOs +=================== + +This board has 5 GPIO ports named from ``gpioa`` to ``gpioe``. + +Pin control can be further configured from your application overlay by adding +children nodes with the desired pinmux configuration to the singleton node +``pinctrl``. Supported properties are described in +:zephyr_file:`dts/bindings/pinctrl/nxp,port-pinctrl.yaml`. + +LEDs +---- + +The NXP S32K148-Q176 board has one user RGB LED that can be used either as a GPIO +LED or as a PWM LED. + +.. table:: RGB LED as GPIO LED + :widths: auto + + =============== ================ =============== ===== + Devicetree node Devicetree alias Label Pin + =============== ================ =============== ===== + led1_red led0 LED1_RGB_RED PTE21 + led1_green led1 LED1_RGB_GREEN PTE22 + led1_blue led2 LED1_RGB_BLUE PTE23 + =============== ================ =============== ===== + +.. table:: RGB LED as PWM LED + :widths: auto + + =============== ======================== ================== ================ + Devicetree node Devicetree alias Label Pin + =============== ======================== ================== ================ + led1_red_pwm pwm-led0 / red-pwm-led LED1_RGB_RED_PWM PTE21 / FTM4_CH1 + led1_green_pwm pwm-led1 / green-pwm-led LED1_RGB_GREEN_PWM PTE22 / FTM4_CH2 + led1_blue_pwm pwm-led2 / blue-pwm-led LED1_RGB_BLUE_PWM PTE23 / FTM4_CH3 + =============== ======================== ================== ================ + +The user can control the LEDs in any way. An output of ``0`` illuminates the LED. + +Buttons +------- + +The NXP S32K148-Q176 board has two user buttons: + ++-----------------+-------+-------+ +| Devicetree node | Label | Pin | ++=================+=======+=======+ +| sw0 / button_3 | SW3 | PTC12 | ++-----------------+-------+-------+ +| sw1 / button_4 | SW4 | PTC13 | ++-----------------+-------+-------+ + +Serial Console +============== + +The serial console is provided via ``lpuart1`` on the OpenSDA adapter. + ++------+--------------+ +| Pin | Pin Function | ++======+==============+ +| PTC7 | LPUART1_TX | ++------+--------------+ +| PTC6 | LPUART1_RX | ++------+--------------+ + +System Clock +============ + +The Arm Cortex-M4F core is configured to run at 80 MHz (RUN mode). + +Programming and Debugging +************************* + +Applications for the ``s32k148_evb`` board can be built in the usual way as +documented in :ref:`build_an_application`. + +Configuring a Debug adapter +=========================== + +This board integrates an OpenSDA debug adapter. It can be used for flashing and debugging. + +Connect the USB cable to a PC and connect micro USB connector of the USB cable to micro-B port J24 on the ``s32k148_evb``. + +In order to use NXP S32 Design Studio IDE install the debug host tools as in indicated in :ref:`nxp-s32-debug-host-tools`. + +In order to use GDB, first install PEMicro USB driver: + +- download `PEMicro USB driver`_ +- Windows: run installation file, Linux: extract downloaded file and run ``setup.sh`` file + +Next, download GDB Server Plug-In. It provides GDB remote debugging and flash programming support: + +- download `GDB Server Plug-In for Eclipse-based ARM IDEs`_ +- extract downloaded file +- unzip jar file ``com.pemicro.debug.gdbjtag.pne_X.X.X.XXXXXXXXXXXX.jar`` + +The server can be run using the following command: + +.. code-block:: console + + pegdbserver_console -startserver -device=NXP_S32K1xx_S32K148F2M0M11 + +Use this command to flash ``zephyr.elf`` file: + +.. code-block:: console + + (gdb) load zephyr.elf + +Configuring a Console +===================== + +We will use OpenSDA as a USB-to-serial adapter for the serial console. + +Use the following settings with your serial terminal of choice (minicom, putty, etc.): + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +References +********** + +.. target-notes:: + +.. _NXP S32K148-Q176: + https://www.nxp.com/design/design-center/development-boards-and-designs/automotive-development-platforms/s32k-mcu-platforms/s32k148-q176-evaluation-board-for-automotive-general-purpose:S32K148EVB + +.. _NXP S32K148: + https://www.nxp.com/products/processors-and-microcontrollers/s32-automotive-platform/s32k-auto-general-purpose-mcus/s32k1-microcontrollers-for-automotive-general-purpose:S32K1 + +.. _GDB Server Plug-In for Eclipse-based ARM IDEs: + https://www.pemicro.com/products/product_viewDetails.cfm?product_id=15320151&productTab=1000000 + +.. _PEMicro USB driver: + https://www.pemicro.com/opensda/ diff --git a/boards/nxp/s32k148_evb/s32k148_evb-pinctrl.dtsi b/boards/nxp/s32k148_evb/s32k148_evb-pinctrl.dtsi new file mode 100644 index 000000000000..b1e9123feb3b --- /dev/null +++ b/boards/nxp/s32k148_evb/s32k148_evb-pinctrl.dtsi @@ -0,0 +1,86 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + lpuart0_default: lpuart0_default { + group0 { + pinmux = , ; + drive-strength = "low"; + }; + }; + + lpuart1_default: lpuart1_default { + group0 { + pinmux = , ; + drive-strength = "low"; + }; + }; + + lpi2c0_default: lpi2c0_default { + group1 { + pinmux = , ; + drive-strength = "low"; + }; + }; + + lpspi0_default: lpspi0_default { + group0 { + pinmux = , + , + , + ; + drive-strength = "low"; + }; + }; + + ftm4_default: ftm4_default { + group0 { + pinmux = , + , + ; + drive-strength = "low"; + }; + }; + + flexcan0_default: flexcan0_default { + group0 { + pinmux = , ; + drive-strength = "low"; + }; + }; + + pinmux_enet: pinmux_enet { + group1 { + pinmux = , + , + , + , + , + , + , + ; + drive-strength = "low"; + slew-rate = "fast"; + }; + }; + + pinmux_enet_mdio: pinmux_enet_mdio { + group0 { + pinmux = ; + drive-strength = "low"; + drive-open-drain; + bias-pull-up; + slew-rate = "fast"; + }; + group1 { + pinmux = ; + drive-strength = "low"; + slew-rate = "fast"; + }; + }; +}; diff --git a/boards/nxp/s32k148_evb/s32k148_evb.dts b/boards/nxp/s32k148_evb/s32k148_evb.dts new file mode 100644 index 000000000000..b23dd47b7824 --- /dev/null +++ b/boards/nxp/s32k148_evb/s32k148_evb.dts @@ -0,0 +1,194 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include +#include +#include "s32k148_evb-pinctrl.dtsi" + +/ { + model = "NXP S32K148EVB"; + compatible = "nxp,s32k148_evb"; + + chosen { + zephyr,sram = &sram_l; + zephyr,flash = &flash0; + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + zephyr,uart-pipe = &lpuart1; + zephyr,canbus = &flexcan0; + }; + + aliases { + led0 = &led1_red; + led1 = &led1_green; + led2 = &led1_blue; + pwm-led0 = &led1_red_pwm; + pwm-led1 = &led1_green_pwm; + pwm-led2 = &led1_blue_pwm; + red-pwm-led = &led1_red_pwm; + green-pwm-led = &led1_green_pwm; + blue-pwm-led = &led1_blue_pwm; + sw0 = &button_3; + sw1 = &button_4; + i2c-0 = &lpi2c0; + }; + + leds { + compatible = "gpio-leds"; + + led1_red: led_0 { + gpios = <&gpioe 21 GPIO_ACTIVE_HIGH>; + label = "LED1_RGB_RED"; + }; + + led1_green: led_1 { + gpios = <&gpioe 22 GPIO_ACTIVE_HIGH>; + label = "LED1_RGB_GREEN"; + }; + + led1_blue: led_2 { + gpios = <&gpioe 23 GPIO_ACTIVE_HIGH>; + label = "LED1_RGB_BLUE"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + + led1_red_pwm: led_pwm_0 { + pwms = <&ftm4 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "LED1_RGB_RED_PWM"; + }; + + led1_green_pwm: led_pwm_1 { + pwms = <&ftm4 2 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "LED1_RGB_GREEN_PWM"; + }; + + led1_blue_pwm: led_pwm_2 { + pwms = <&ftm4 3 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "LED1_RGB_BLUE_PWM"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + button_3: button_0 { + label = "SW3"; + gpios = <&gpioc 12 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + + button_4: button_1 { + label = "SW4"; + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + +}; + +&cpu0 { + clock-frequency = <112000000>; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +&gpioc { + status = "okay"; +}; + +&gpiod { + status = "okay"; +}; + +&gpioe { + status = "okay"; +}; + +&lpuart0 { + pinctrl-0 = <&lpuart0_default>; + pinctrl-names = "default"; + current-speed = <115200>; +}; + +&lpuart1 { + pinctrl-0 = <&lpuart1_default>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&lpi2c0 { + pinctrl-0 = <&lpi2c0_default>; + pinctrl-names = "default"; + scl-gpios = <&gpiob 9 GPIO_ACTIVE_HIGH>; + sda-gpios = <&gpiob 10 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&lpspi0 { + pinctrl-0 = <&lpspi0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&ftm4 { + compatible = "nxp,ftm-pwm"; + pinctrl-0 = <&ftm4_default>; + pinctrl-names = "default"; + clock-source = "system"; + prescaler = <4>; + #pwm-cells = <3>; + status = "okay"; +}; + +/* + * The S32K148EVB board contains a UJA1132 SBC which needs to be configured via SPI. + * The factory preset forces it to normal mode though, so the CAN phy is enabled + * even without configuration. + * Therefore, we don't reference a can phy driver node here for now. + */ +&flexcan0 { + pinctrl-0 = <&flexcan0_default>; + pinctrl-names = "default"; + bitrate = <125000>; + status = "okay"; +}; + +&adc0 { + sample-time = <65>; + vref-mv = <5000>; + status = "okay"; +}; + +&adc1 { + sample-time = <65>; + vref-mv = <5000>; + status = "okay"; +}; + +&enet_mac { + pinctrl-0 = <&pinmux_enet>; + pinctrl-names = "default"; + zephyr,random-mac-address; + phy-connection-type = "rmii"; +}; + +&enet_mdio { + pinctrl-0 = <&pinmux_enet_mdio>; + pinctrl-names = "default"; +}; diff --git a/boards/nxp/s32k148_evb/s32k148_evb.yaml b/boards/nxp/s32k148_evb/s32k148_evb.yaml new file mode 100644 index 000000000000..caa76f3afefc --- /dev/null +++ b/boards/nxp/s32k148_evb/s32k148_evb.yaml @@ -0,0 +1,22 @@ +# Copyright 2023-2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +identifier: s32k148_evb +name: NXP S32K148EVB-Q176 +vendor: nxp +type: mcu +arch: arm +ram: 256 +flash: 1536 +toolchain: + - zephyr +supported: + - mpu + - gpio + - uart + - pinctrl + - pwm + - can + - watchdog + - counter + - adc diff --git a/boards/nxp/s32k148_evb/s32k148_evb_defconfig b/boards/nxp/s32k148_evb/s32k148_evb_defconfig new file mode 100644 index 000000000000..08e047dd7bb0 --- /dev/null +++ b/boards/nxp/s32k148_evb/s32k148_evb_defconfig @@ -0,0 +1,13 @@ +# Copyright 2023-2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BUILD_OUTPUT_HEX=y + +# Run from internal program flash +CONFIG_XIP=y + +# Enable MPU +CONFIG_ARM_MPU=y + +CONFIG_SERIAL=y +CONFIG_CONSOLE=y diff --git a/boards/shields/nxp_adtja1101/Kconfig.defconfig b/boards/shields/nxp_adtja1101/Kconfig.defconfig new file mode 100644 index 000000000000..c141a2a596a3 --- /dev/null +++ b/boards/shields/nxp_adtja1101/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_NXP_ADTJA1101 + +config PHY_TJA11xx + default y + +endif # SHIELD_NXP_ADTJA1101 diff --git a/boards/shields/nxp_adtja1101/Kconfig.shield b/boards/shields/nxp_adtja1101/Kconfig.shield new file mode 100644 index 000000000000..82ae3931b4ca --- /dev/null +++ b/boards/shields/nxp_adtja1101/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_NXP_ADTJA1101 + def_bool $(shields_list_contains,nxp_adtja1101) diff --git a/boards/shields/nxp_adtja1101/doc/index.rst b/boards/shields/nxp_adtja1101/doc/index.rst new file mode 100644 index 000000000000..6c3c520afe41 --- /dev/null +++ b/boards/shields/nxp_adtja1101/doc/index.rst @@ -0,0 +1,31 @@ +.. _nxp_adtja1101: + +NXP ADTJA1101-RMII Automotive Ethernet Adapter +############################################## + +Overview +******** + +The ADTJA1101-RMII is an automotive Ethernet adapter card specifically built to +add 100Mbps automotive Ethernet connectivity to the S32K148 Microcontroller and +i.MX8 platforms. + +This shield can be used with the NXP S32K148-Q176 evaluation board by plugging +into the common expansion connector, through which the ADTJA1101-RMII connects +the RMII interfaces of the S32K148 directly to NXP’s 100BASE-T1 Ethernet PHY +TJA1101. + +More information about this module can be found at `_ADTJA1101-RMII`_. + +Programming +*********** + +Set ``--shield nxp_adtja1101`` when you invoke ``west build``. + +References +********** + +.. target-notes:: + +.. _ADTJA1101-RMII: + https://www.nxp.com/part/ADTJA1101-RMII diff --git a/boards/shields/nxp_adtja1101/nxp_adtja1101.overlay b/boards/shields/nxp_adtja1101/nxp_adtja1101.overlay new file mode 100644 index 000000000000..a78fe870f2a9 --- /dev/null +++ b/boards/shields/nxp_adtja1101/nxp_adtja1101.overlay @@ -0,0 +1,20 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&enet_mac { + status = "okay"; + phy-handle = <&phy>; +}; + +&enet_mdio { + status = "okay"; + phy: phy@0 { + compatible = "nxp,tja11xx"; + reg = <0>; + status = "okay"; + master-slave = "default"; + }; +}; diff --git a/drivers/ethernet/phy/CMakeLists.txt b/drivers/ethernet/phy/CMakeLists.txt index 40964bf8d6b8..efe9809b164d 100644 --- a/drivers/ethernet/phy/CMakeLists.txt +++ b/drivers/ethernet/phy/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_library_sources_ifdef(CONFIG_PHY_GENERIC_MII phy_mii.c) zephyr_library_sources_ifdef(CONFIG_PHY_ADIN2111 phy_adin2111.c) zephyr_library_sources_ifdef(CONFIG_PHY_DM8806 phy_dm8806.c) +zephyr_library_sources_ifdef(CONFIG_PHY_TJA11xx phy_tja11xx.c) zephyr_library_sources_ifdef(CONFIG_PHY_TJA1103 phy_tja1103.c) zephyr_library_sources_ifdef(CONFIG_PHY_MICROCHIP_KSZ8081 phy_microchip_ksz8081.c) zephyr_library_sources_ifdef(CONFIG_PHY_MICROCHIP_VSC8541 phy_microchip_vsc8541.c) diff --git a/drivers/ethernet/phy/Kconfig b/drivers/ethernet/phy/Kconfig index 2d2779c5f2d9..722afee024e6 100644 --- a/drivers/ethernet/phy/Kconfig +++ b/drivers/ethernet/phy/Kconfig @@ -14,6 +14,7 @@ module-dep = LOG module-str = Log level for Ethernet PHY driver module-help = Sets log level for Ethernet PHY Device Drivers. source "subsys/net/Kconfig.template.log_config.net" +source "drivers/ethernet/phy/Kconfig.tja11xx" source "drivers/ethernet/phy/Kconfig.tja1103" source "drivers/ethernet/phy/Kconfig.dm8806" source "drivers/ethernet/phy/Kconfig.microchip_t1s" diff --git a/drivers/ethernet/phy/Kconfig.tja11xx b/drivers/ethernet/phy/Kconfig.tja11xx new file mode 100644 index 000000000000..eaeaac5722f7 --- /dev/null +++ b/drivers/ethernet/phy/Kconfig.tja11xx @@ -0,0 +1,12 @@ +# NXP PHY TJA11xx driver configuration options + +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +menuconfig PHY_TJA11xx + bool "TJA11xx PHY driver" + default y + depends on DT_HAS_NXP_TJA11xx_ENABLED + depends on MDIO + help + Enable TJA11xx PHY driver. diff --git a/drivers/ethernet/phy/phy_tja11xx.c b/drivers/ethernet/phy/phy_tja11xx.c new file mode 100644 index 000000000000..7353740a85b2 --- /dev/null +++ b/drivers/ethernet/phy/phy_tja11xx.c @@ -0,0 +1,269 @@ +/* +* Copyright 2023 NXP +* Copyright 2023 CogniPilot Foundation +* +* SPDX-License-Identifier: Apache-2.0 +*/ + +#define DT_DRV_COMPAT nxp_tja11xx + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(phy_tja11xx, CONFIG_PHY_LOG_LEVEL); + +/* Extended control register */ +#define TJA1101_EXTENDED_CONTROL 0x0017U +/* Configuration register 1 */ +#define TJA1101_CONFIGURATION_1 0x0018U + +struct phy_tja11xx_config { + const struct device *mdio; + struct gpio_dt_spec gpio_interrupt; + uint8_t phy_addr; + uint8_t master_slave; +}; + +struct phy_tja11xx_data { + const struct device *dev; + struct phy_link_state state; + struct k_sem sem; + struct k_sem offload_sem; + phy_callback_t cb; + struct gpio_callback phy_tja11xx_int_callback; + void *cb_data; + + struct k_work_delayable monitor_work; +}; + +static inline int phy_tja11xx_c22_read(const struct device *dev, uint16_t reg, uint16_t *val) +{ + const struct phy_tja11xx_config *const cfg = dev->config; + + return mdio_read(cfg->mdio, cfg->phy_addr, reg, val); +} + +static inline int phy_tja11xx_c22_write(const struct device *dev, uint16_t reg, uint16_t val) +{ + const struct phy_tja11xx_config *const cfg = dev->config; + + return mdio_write(cfg->mdio, cfg->phy_addr, reg, val); +} + +static int phy_tja11xx_reg_read(const struct device *dev, uint16_t reg_addr, uint32_t *data) +{ + const struct phy_tja11xx_config *cfg = dev->config; + int ret; + + mdio_bus_enable(cfg->mdio); + + ret = phy_tja11xx_c22_read(dev, reg_addr, (uint16_t *)data); + + mdio_bus_disable(cfg->mdio); + + return ret; +} + +static int phy_tja11xx_reg_write(const struct device *dev, uint16_t reg_addr, uint32_t data) +{ + const struct phy_tja11xx_config *cfg = dev->config; + int ret; + + mdio_bus_enable(cfg->mdio); + + ret = phy_tja11xx_c22_write(dev, reg_addr, (uint16_t)data); + + mdio_bus_disable(cfg->mdio); + + return ret; +} + +static int update_link_state(const struct device *dev) +{ + struct phy_tja11xx_data *const data = dev->data; + bool link_up; + uint16_t val; + + if (phy_tja11xx_c22_read(dev, MII_BMSR, &val) < 0) { + return -EIO; + } + + link_up = (val & MII_BMSR_LINK_STATUS) != 0; + + /* Let workqueue re-schedule and re-check if the + * link status is unchanged this time + */ + if (data->state.is_up == link_up) { + return -EAGAIN; + } + + data->state.is_up = link_up; + + return 0; +} + +static int phy_tja11xx_get_link_state(const struct device *dev, struct phy_link_state *state) +{ + struct phy_tja11xx_data *const data = dev->data; + const struct phy_tja11xx_config *const cfg = dev->config; + int rc = 0; + + k_sem_take(&data->sem, K_FOREVER); + + /* If Interrupt is configured then the workqueue will not + * update the link state periodically so do it explicitly + */ + if (cfg->gpio_interrupt.port != NULL) { + rc = update_link_state(dev); + } + + memcpy(state, &data->state, sizeof(struct phy_link_state)); + + k_sem_give(&data->sem); + + return rc; +} + +static void invoke_link_cb(const struct device *dev) +{ + struct phy_tja11xx_data *const data = dev->data; + struct phy_link_state state; + + if (data->cb == NULL) { + return; + } + + /* Send callback only on link state change */ + if (phy_tja11xx_get_link_state(dev, &state) != 0) { + return; + } + + data->cb(dev, &state, data->cb_data); +} + +static void monitor_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct phy_tja11xx_data *const data = + CONTAINER_OF(dwork, struct phy_tja11xx_data, monitor_work); + const struct device *dev = data->dev; + int rc; + + k_sem_take(&data->sem, K_FOREVER); + + rc = update_link_state(dev); + + k_sem_give(&data->sem); + + /* If link state has changed and a callback is set, invoke callback */ + if (rc == 0) { + invoke_link_cb(dev); + } + + /* Submit delayed work */ + k_work_reschedule(&data->monitor_work, K_MSEC(CONFIG_PHY_MONITOR_PERIOD)); +} + +static void phy_tja11xx_cfg_irq_poll(const struct device *dev) +{ + struct phy_tja11xx_data *const data = dev->data; + + k_work_init_delayable(&data->monitor_work, monitor_work_handler); + + monitor_work_handler(&data->monitor_work.work); +} + +static int phy_tja11xx_cfg_link(const struct device *dev, enum phy_link_speed adv_speeds) +{ + ARG_UNUSED(dev); + + if (adv_speeds & LINK_FULL_100BASE_T) { + return 0; + } + + return -ENOTSUP; +} + +static int phy_tja11xx_init(const struct device *dev) +{ + struct phy_tja11xx_data *const data = dev->data; + int ret; + + data->dev = dev; + data->cb = NULL; + data->state.is_up = false; + data->state.speed = LINK_FULL_100BASE_T; + + ret = phy_tja11xx_reg_write(dev, TJA1101_EXTENDED_CONTROL, 0x1804); + if (ret < 0) { + return ret; + } + + ret = phy_tja11xx_reg_write(dev, MII_BMCR, 0x2100); + if (ret < 0) { + return ret; + } + + ret = phy_tja11xx_reg_write(dev, TJA1101_CONFIGURATION_1, 0x8A00); + if (ret < 0) { + return ret; + } + + ret = phy_tja11xx_reg_write(dev, TJA1101_EXTENDED_CONTROL, 0x9804); + if (ret < 0) { + return ret; + } + phy_tja11xx_cfg_irq_poll(dev); + + return ret; +} + +static int phy_tja11xx_link_cb_set(const struct device *dev, phy_callback_t cb, void *user_data) +{ + struct phy_tja11xx_data *const data = dev->data; + + data->cb = cb; + data->cb_data = user_data; + + /* Invoke the callback to notify the caller of the current + * link status. + */ + invoke_link_cb(dev); + + return 0; +} + +static const struct ethphy_driver_api phy_tja11xx_api = { + .get_link = phy_tja11xx_get_link_state, + .cfg_link = phy_tja11xx_cfg_link, + .link_cb_set = phy_tja11xx_link_cb_set, + .read = phy_tja11xx_reg_read, + .write = phy_tja11xx_reg_write, +}; + +#define TJA11xx_INITIALIZE(n) \ + static const struct phy_tja11xx_config phy_tja11xx_config_##n = { \ + .phy_addr = DT_INST_REG_ADDR(n), \ + .mdio = DEVICE_DT_GET(DT_INST_BUS(n)), \ + .gpio_interrupt = GPIO_DT_SPEC_INST_GET_OR(n, int_gpios, {0}), \ + .master_slave = DT_INST_ENUM_IDX(n, master_slave), \ + }; \ + static struct phy_tja11xx_data phy_tja11xx_data_##n = { \ + .sem = Z_SEM_INITIALIZER(phy_tja11xx_data_##n.sem, 1, 1), \ + .offload_sem = Z_SEM_INITIALIZER(phy_tja11xx_data_##n.offload_sem, 0, 1), \ + }; \ + DEVICE_DT_INST_DEFINE(n, &phy_tja11xx_init, NULL, &phy_tja11xx_data_##n, \ + &phy_tja11xx_config_##n, POST_KERNEL, CONFIG_PHY_INIT_PRIORITY, \ + &phy_tja11xx_api); + +DT_INST_FOREACH_STATUS_OKAY(TJA11xx_INITIALIZE) diff --git a/dts/arm/nxp/nxp_s32k148.dtsi b/dts/arm/nxp/nxp_s32k148.dtsi new file mode 100644 index 000000000000..845a1dff9195 --- /dev/null +++ b/dts/arm/nxp/nxp_s32k148.dtsi @@ -0,0 +1,103 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + cpus { + cpu@0 { + compatible = "arm,cortex-m4f"; + }; + }; + + soc { + /* + * SRAM_L and SRAM_U ranges form a contiguous block but misaligned + * and burst accesses cannot occur across the 0x20000000 boundary + * that separates the two SRAM arrays. Hence, treat the two arrays + * as separate memory ranges. + */ + sram_l: sram@1ffe0000 { + compatible = "mmio-sram"; + reg = <0x1ffe0000 DT_SIZE_K(128)>; + }; + + sram_u: sram@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(124)>; + }; + + enet: ethernet@40079000 { + compatible = "nxp,enet"; + reg = <0x40079000 0x628>; + clocks = <&clock NXP_S32_ENET_CLK>; + + enet_mac: ethernet { + compatible = "nxp,enet-mac"; + interrupts = <73 0>, <74 0>, <75 0>; + interrupt-names = "TX", "RX", "ERR"; + nxp,mdio = <&enet_mdio>; + nxp,ptp-clock = <&enet_ptp_clock>; + phy-connection-type = "rmii"; + }; + + enet_mdio: mdio { + compatible = "nxp,enet-mdio"; + #address-cells = <1>; + #size-cells = <0>; + }; + + enet_ptp_clock: ptp_clock { + compatible = "nxp,enet-ptp-clock"; + interrupts = <72 0>; + clocks = <&clock NXP_S32_ENET_CLK>; + }; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <4>; +}; + +&ftfc { + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0 (DT_SIZE_M(1) + DT_SIZE_K(512))>; + erase-block-size = ; + write-block-size = <8>; + }; +}; + +&lpuart2 { + clocks = <&clock NXP_S32_LPUART2_CLK>; +}; + +&lpspi1 { + clocks = <&clock NXP_S32_LPSPI1_CLK>; +}; + +&lpspi2 { + clocks = <&clock NXP_S32_LPSPI2_CLK>; +}; + +&flexcan0 { + interrupts = <78 0>, <79 0>, <80 0>, <81 0>, <82 0>; + interrupt-names = "warning", "error", "wake-up", "mb-0-15", "mb-16-31"; +}; + +&flexcan1 { + interrupts = <85 0>, <86 0>, <88 0>, <89 0>; + interrupt-names = "warning", "error", "mb-0-15", "mb-16-31"; + clocks = <&clock NXP_S32_FLEXCAN1_CLK>; +}; + +&flexcan2 { + interrupts = <92 0>, <93 0>, <95 0>, <96 0>; + interrupt-names = "warning", "error", "mb-0-15", "mb-16-31"; + clocks = <&clock NXP_S32_FLEXCAN2_CLK>; +}; diff --git a/dts/bindings/ethernet/nxp,tja11xx.yaml b/dts/bindings/ethernet/nxp,tja11xx.yaml new file mode 100644 index 000000000000..57825a8833a4 --- /dev/null +++ b/dts/bindings/ethernet/nxp,tja11xx.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: TJA11xx PHY + +compatible: "nxp,tja11xx" + +include: phy.yaml + +properties: + reg: + required: true + description: PHY address + + int-gpios: + type: phandle-array + description: + interrupt GPIO for PHY. Will be pulled high in its default state. + + master-slave: + type: string + required: false + description: | + 100BASE-T1 Specifies that either phy has to run in master / slave mode + Default selects the mode set by the pinstrapping on the hardware design. + enum: + - "default" + - "master" + - "slave" diff --git a/include/zephyr/dt-bindings/clock/nxp_s32k148_clock.h b/include/zephyr/dt-bindings/clock/nxp_s32k148_clock.h new file mode 100644 index 000000000000..f50254977acf --- /dev/null +++ b/include/zephyr/dt-bindings/clock/nxp_s32k148_clock.h @@ -0,0 +1,100 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NXP_S32K148_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NXP_S32K148_CLOCK_H_ + +#define NXP_S32_LPO_128K_CLK 1U +#define NXP_S32_SIRC_CLK 2U +#define NXP_S32_SIRC_VLP_CLK 3U +#define NXP_S32_SIRC_STOP_CLK 4U +#define NXP_S32_FIRC_CLK 5U +#define NXP_S32_FIRC_VLP_CLK 6U +#define NXP_S32_FIRC_STOP_CLK 7U +#define NXP_S32_SOSC_CLK 8U +#define NXP_S32_SPLL_CLK 9U +#define NXP_S32_SIRCDIV1_CLK 10U +#define NXP_S32_SIRCDIV2_CLK 11U +#define NXP_S32_FIRCDIV1_CLK 12U +#define NXP_S32_FIRCDIV2_CLK 13U +#define NXP_S32_SOSCDIV1_CLK 14U +#define NXP_S32_SOSCDIV2_CLK 15U +#define NXP_S32_SPLLDIV1_CLK 16U +#define NXP_S32_SPLLDIV2_CLK 17U +#define NXP_S32_LPO_32K_CLK 18U +#define NXP_S32_LPO_1K_CLK 19U +#define NXP_S32_TCLK0_REF_CLK 20U +#define NXP_S32_TCLK1_REF_CLK 21U +#define NXP_S32_TCLK2_REF_CLK 22U +#define NXP_S32_SCS_CLK 24U +#define NXP_S32_SCS_RUN_CLK 25U +#define NXP_S32_SCS_VLPR_CLK 26U +#define NXP_S32_SCS_HSRUN_CLK 27U +#define NXP_S32_CORE_CLK 28U +#define NXP_S32_CORE_RUN_CLK 29U +#define NXP_S32_CORE_VLPR_CLK 30U +#define NXP_S32_CORE_HSRUN_CLK 31U +#define NXP_S32_BUS_CLK 32U +#define NXP_S32_BUS_RUN_CLK 33U +#define NXP_S32_BUS_VLPR_CLK 34U +#define NXP_S32_BUS_HSRUN_CLK 35U +#define NXP_S32_SLOW_CLK 36U +#define NXP_S32_SLOW_RUN_CLK 37U +#define NXP_S32_SLOW_VLPR_CLK 38U +#define NXP_S32_SLOW_HSRUN_CLK 39U +#define NXP_S32_RTC_CLK 40U +#define NXP_S32_LPO_CLK 41U +#define NXP_S32_SCG_CLKOUT_CLK 42U +#define NXP_S32_FTM0_EXT_CLK 43U +#define NXP_S32_FTM1_EXT_CLK 44U +#define NXP_S32_FTM2_EXT_CLK 45U +#define NXP_S32_FTM3_EXT_CLK 46U +#define NXP_S32_FTM4_EXT_CLK 47U +#define NXP_S32_FTM5_EXT_CLK 48U +#define NXP_S32_ADC0_CLK 50U +#define NXP_S32_ADC1_CLK 51U +#define NXP_S32_CLKOUT0_CLK 52U +#define NXP_S32_CMP0_CLK 53U +#define NXP_S32_CRC0_CLK 54U +#define NXP_S32_DMA0_CLK 55U +#define NXP_S32_DMAMUX0_CLK 56U +#define NXP_S32_EIM0_CLK 57U +#define NXP_S32_ENET_CLK 58U +#define NXP_S32_ERM0_CLK 59U +#define NXP_S32_EWM0_CLK 60U +#define NXP_S32_FLEXCAN0_CLK 61U +#define NXP_S32_FLEXCAN1_CLK 62U +#define NXP_S32_FLEXCAN2_CLK 63U +#define NXP_S32_FLEXIO_CLK 64U +#define NXP_S32_FTFC_CLK 65U +#define NXP_S32_FTM0_CLK 66U +#define NXP_S32_FTM1_CLK 67U +#define NXP_S32_FTM2_CLK 68U +#define NXP_S32_FTM3_CLK 69U +#define NXP_S32_FTM4_CLK 70U +#define NXP_S32_FTM5_CLK 71U +#define NXP_S32_LPI2C0_CLK 72U +#define NXP_S32_LPIT0_CLK 73U +#define NXP_S32_LPSPI0_CLK 74U +#define NXP_S32_LPSPI1_CLK 75U +#define NXP_S32_LPSPI2_CLK 76U +#define NXP_S32_LPTMR0_CLK 77U +#define NXP_S32_LPUART0_CLK 78U +#define NXP_S32_LPUART1_CLK 79U +#define NXP_S32_LPUART2_CLK 80U +#define NXP_S32_MPU0_CLK 81U +#define NXP_S32_MSCM0_CLK 82U +#define NXP_S32_PDB0_CLK 83U +#define NXP_S32_PDB1_CLK 84U +#define NXP_S32_PORTA_CLK 85U +#define NXP_S32_PORTB_CLK 86U +#define NXP_S32_PORTC_CLK 87U +#define NXP_S32_PORTD_CLK 88U +#define NXP_S32_PORTE_CLK 89U +#define NXP_S32_RTC0_CLK 90U +#define NXP_S32_TRACE_CLK 91U + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NXP_S32K148_CLOCK_H_ */ diff --git a/samples/drivers/adc/adc_dt/boards/s32k148_evb.overlay b/samples/drivers/adc/adc_dt/boards/s32k148_evb.overlay new file mode 100644 index 000000000000..52972e71cbb8 --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/s32k148_evb.overlay @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Accenture + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + zephyr,user { + io-channels = <&adc0 28>; + }; +}; + +&pinctrl { + adc0_default: adc0_default { + group_1 { + pinmux = ; + drive-strength = "low"; + }; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + channel@c { + reg = <28>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; diff --git a/samples/drivers/adc/adc_dt/sample.yaml b/samples/drivers/adc/adc_dt/sample.yaml index f686b8edcb5f..0d88a53cdaa4 100644 --- a/samples/drivers/adc/adc_dt/sample.yaml +++ b/samples/drivers/adc/adc_dt/sample.yaml @@ -36,6 +36,7 @@ tests: - frdm_mcxc242 - ucans32k1sic - xg24_rb4187c + - s32k148_evb integration_platforms: - nucleo_l073rz - nrf52840dk/nrf52840 diff --git a/samples/drivers/adc/adc_sequence/boards/s32k148_evb.overlay b/samples/drivers/adc/adc_sequence/boards/s32k148_evb.overlay new file mode 100644 index 000000000000..b3334b8a3bed --- /dev/null +++ b/samples/drivers/adc/adc_sequence/boards/s32k148_evb.overlay @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Accenture + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + adc0 = &adc0; + }; +}; + +&pinctrl { + adc0_default: adc0_default { + group_1 { + pinmux = ; + drive-strength = "low"; + }; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + channel@c { + reg = <28>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; diff --git a/samples/drivers/adc/adc_sequence/sample.yaml b/samples/drivers/adc/adc_sequence/sample.yaml index 0461205a058f..ef81f39c2f79 100644 --- a/samples/drivers/adc/adc_sequence/sample.yaml +++ b/samples/drivers/adc/adc_sequence/sample.yaml @@ -12,6 +12,7 @@ tests: - nrf54l15dk/nrf54l15/cpuapp - nrf54h20dk/nrf54h20/cpuapp - ucans32k1sic + - s32k148_evb - frdm_mcxc242 - stm32f3_disco integration_platforms: diff --git a/tests/drivers/adc/adc_api/boards/s32k148_evb.overlay b/tests/drivers/adc/adc_api/boards/s32k148_evb.overlay new file mode 100644 index 000000000000..65f8107ad28a --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/s32k148_evb.overlay @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Accenture + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + zephyr,user { + io-channels = <&adc0 28>; + }; +}; + +&pinctrl { + adc0_default: adc0_default { + group_1 { + pinmux = ; + drive-strength = "low"; + }; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + channel@c { + reg = <28>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&adc1 { + status = "disabled"; +}; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/s32k148_evb.overlay b/tests/drivers/gpio/gpio_basic_api/boards/s32k148_evb.overlay new file mode 100644 index 000000000000..6d94daf3b9f8 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/s32k148_evb.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&gpioa 0 0>; + in-gpios = <&gpioa 1 0>; + }; +}; diff --git a/tests/drivers/gpio/gpio_hogs/boards/s32k148_evb.overlay b/tests/drivers/gpio/gpio_hogs/boards/s32k148_evb.overlay new file mode 100644 index 000000000000..7b4324fb9201 --- /dev/null +++ b/tests/drivers/gpio/gpio_hogs/boards/s32k148_evb.overlay @@ -0,0 +1,35 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + zephyr,user { + output-high-gpios = <&gpioa 3 GPIO_ACTIVE_LOW>; + output-low-gpios = <&gpioa 2 GPIO_ACTIVE_HIGH>; + input-gpios = <&gpioa 1 GPIO_ACTIVE_HIGH>; + }; +}; + +&gpioa { + hog1 { + gpio-hog; + gpios = <3 GPIO_ACTIVE_LOW>; + output-high; + }; + + hog2 { + gpio-hog; + gpios = <1 GPIO_ACTIVE_HIGH>; + input; + }; + + hog3 { + gpio-hog; + gpios = <2 GPIO_ACTIVE_HIGH>; + output-low; + }; +}; diff --git a/west.yml b/west.yml index cc8fc0598be2..b6d30a365e2b 100644 --- a/west.yml +++ b/west.yml @@ -203,7 +203,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 2a1d73aeb863a73bb06ba8b236de7da6d3e31847 + revision: e3b7e815ac1849d527d4a56d3d02328c532a318b path: modules/hal/nxp groups: - hal