diff --git a/boards/riscv/hpm6750evkmini/Kconfig.board b/boards/riscv/hpm6750evkmini/Kconfig.board new file mode 100644 index 000000000000000..036951beb3ed0cb --- /dev/null +++ b/boards/riscv/hpm6750evkmini/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_HPM6750EVKMINI + bool "HPMicro HPM6750EVKMINI" + depends on SOC_HPM6750 diff --git a/boards/riscv/hpm6750evkmini/Kconfig.defconfig b/boards/riscv/hpm6750evkmini/Kconfig.defconfig new file mode 100644 index 000000000000000..d4fe9f5b4039bb5 --- /dev/null +++ b/boards/riscv/hpm6750evkmini/Kconfig.defconfig @@ -0,0 +1,17 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_HPM6750EVKMINI + +DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition + +config BOARD + default "hpm6750evkmini" + +config FLASH_LOAD_OFFSET + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + +endif # BOARD_HPM6750EVKMINI diff --git a/boards/riscv/hpm6750evkmini/board.cmake b/boards/riscv/hpm6750evkmini/board.cmake new file mode 100644 index 000000000000000..e295c8969163665 --- /dev/null +++ b/boards/riscv/hpm6750evkmini/board.cmake @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(NOT CONFIG_XIP) +board_runner_args(openocd "--use-elf") +endif() +board_runner_args(openocd "--config=${BOARD_DIR}/support/probes/ft2232.cfg" + "--config=${BOARD_DIR}/support/soc/hpm6750-single-core.cfg" + "--config=${BOARD_DIR}/support/boards/hpm6750evkmini.cfg") +board_runner_args(openocd --target-handle=_CHIPNAME.cpu0) + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/riscv/hpm6750evkmini/doc/img/hpm6750evkmini.png b/boards/riscv/hpm6750evkmini/doc/img/hpm6750evkmini.png new file mode 100644 index 000000000000000..5bb39c9bbb45e28 Binary files /dev/null and b/boards/riscv/hpm6750evkmini/doc/img/hpm6750evkmini.png differ diff --git a/boards/riscv/hpm6750evkmini/doc/index.rst b/boards/riscv/hpm6750evkmini/doc/index.rst new file mode 100644 index 000000000000000..3ecd7b8f2bb6031 --- /dev/null +++ b/boards/riscv/hpm6750evkmini/doc/index.rst @@ -0,0 +1,109 @@ +.. _hpm6750evkmini: + +HPMicro HPM6750EVKMINI +###################### + +Overview +******** + +The HPM6750 is a dual-core flashless MCU running 816Mhz. +It has a 2MB continuous on-chip ram. +Also, it provides various memory interfaces, including SDRAM, Quad SPI NOR Flash, SD/eMMC. + +The figure shows the HPM6750EVKMINI board. + +.. image:: img/hpm6750evkmini.png + :align: center + :alt: HPM6750EVKMINI + +Hardware +******** + +The HPM6750EVKMINI platform integrates 2 cores 32-bit 816MHz RISC-V CPUs, DSP, +2MB RAM, Cache, SPI flash memory, ethernet controller and other peripherals. + +- HPM6750IVM MCU (816Mhz, 2MB OCRAM) +- Onboard Memory + - 128Mb SDRAM + - 64Mb Quad SPI NOR Flash +- Display & Camera + - LCD connector + - Camera (DVP) +- WiFi + - RW007 over SPI +- USB + - USB type C (USB 2.0 OTG) connector x2 +- Audio + - Mic + - DAO +- Others + - TF Slot + - FT2232 + - Beeper + - RGB LED +- Expansion port + - ART-PI extension port + +For more information about the HPMICRO SoC and HPM6750EVKMINI board: + +- `HPMICRO Design Resources`_ + +Serial Port +=========== + +The HPM6750EVKMINI platform has 2 UARTs. +The Zephyr console output is by default assigned to UART0 and the default +settings are 115200 8N1. + +Programming and debugging +************************* + +Building +======== + +You can build applications in the usual way. Here is an example for +the :ref:`hello_world` application. + +.. zephyr-app-commands:: + :board: hpm6750evkmini + :zephyr-app: samples/hello_world + :goals: build + +Flashing +======== + +If you want to use XIP mode (``CONFIG_XIP=y``). +If ``CONFIG_XIP=n``, you can load the program into RAM directly +and execute it. + +.. zephyr-app-commands:: + :board: hpm6750evkmini + :zephyr-app: samples/hello_world + :goals: flash + +Open a serial terminal with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +you should see the following message in the terminal: + +.. code-block:: console + + Hello World! hpm6750evkmini + +Debugging +========= + +.. zephyr-app-commands:: + :board: hpm6750evkmini + :zephyr-app: samples/hello_world + :goals: debug + +References +========== + +.. _HPMICRO Design Resources: + http://www.hpmicro.com/resources/resources.html diff --git a/boards/riscv/hpm6750evkmini/hpm6750evkmini-pinctrl.dtsi b/boards/riscv/hpm6750evkmini/hpm6750evkmini-pinctrl.dtsi new file mode 100644 index 000000000000000..af2809d7c7645a0 --- /dev/null +++ b/boards/riscv/hpm6750evkmini/hpm6750evkmini-pinctrl.dtsi @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 HPMicro + * SPDX-License-Identifier: Apache-2.0 + */ +#include +&pinctrl { + pinmux_uart0: pinmux_uart0 { + group0 { + pinmux = + , + , + , + ; + drive-strength = "r000"; + power-source = "3v3"; + }; + }; + pinmux_gpiob: pinmux_gpiob { + group0 { + pinmux = + , + , + ; + bias-pull-down; + drive-strength = "r000"; + power-source = "3v3"; + }; + }; +}; diff --git a/boards/riscv/hpm6750evkmini/hpm6750evkmini.dts b/boards/riscv/hpm6750evkmini/hpm6750evkmini.dts new file mode 100644 index 000000000000000..bdc25d6232f2093 --- /dev/null +++ b/boards/riscv/hpm6750evkmini/hpm6750evkmini.dts @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2022 HPMicro + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "hpm6750evkmini-pinctrl.dtsi" + +/ { + model = "HPMicro HPM6750EVKMINI"; + compatible = "HPMicro,hpm6750evkmini"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,sram = &sram; + zephyr,itcm = &ilm; + zephyr,dtcm = &dlm; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + dram: memory@40000000 { + device_type = "memory"; + reg = <0x40000000 DT_SIZE_M(16)>; + }; + + aliases { + led0 = &led_r; + led1 = &led_g; + led2 = &led_b; + }; + + leds { + compatible = "gpio-leds"; + led_r: led_r { + gpios = <&gpiob 19 GPIO_ACTIVE_LOW>; + label = "LEDR"; + }; + led_g: led_g { + gpios = <&gpiob 18 GPIO_ACTIVE_LOW>; + label = "LEDG"; + }; + led_b: led_b { + gpios = <&gpiob 20 GPIO_ACTIVE_LOW>; + label = "LEDB"; + }; + }; +}; + +&gpio0 { + + gpiob: gpio@1 { + compatible = "hpmicro,hpm-gpio"; + reg = <0x0 0x4000>; + gpio-controller; + #gpio-cells = <2>; + hpmicro-gpio-port = <1>; + interrupts = <2 1>; + interrupt-parent = <&plic0>; + }; + +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_uart0>; + pinctrl-names = "default"; +}; +&gpiob { + pinctrl-0 = <&pinmux_gpiob>; + pinctrl-names = "default"; + status = "okay"; +}; +&flash0 { + status = "okay"; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 0x3000>; + }; + + slot0_partition: partition@3000 { + label = "image-0"; + reg = <0x3000 DT_SIZE_M(4)>; + }; + }; +}; diff --git a/boards/riscv/hpm6750evkmini/hpm6750evkmini.yaml b/boards/riscv/hpm6750evkmini/hpm6750evkmini.yaml new file mode 100644 index 000000000000000..01bdf205444c6cc --- /dev/null +++ b/boards/riscv/hpm6750evkmini/hpm6750evkmini.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +identifier: hpm6750evkmini +name: HPMicro HPM6750EVKMINI +type: mcu +arch: riscv32 +toolchain: + - zephyr + - cross-compile +ram: 2048 +supported: + - gpio + - uart +testing: + ignore_tags: + - bluetooth +vendor: hpmicro diff --git a/boards/riscv/hpm6750evkmini/hpm6750evkmini_defconfig b/boards/riscv/hpm6750evkmini/hpm6750evkmini_defconfig new file mode 100644 index 000000000000000..99f4b237de1decd --- /dev/null +++ b/boards/riscv/hpm6750evkmini/hpm6750evkmini_defconfig @@ -0,0 +1,21 @@ +CONFIG_SOC_SERIES_HPMICRO=y +CONFIG_SOC_HPM6750=y +CONFIG_BOARD_HPM6750EVKMINI=y +CONFIG_XIP=n +CONFIG_PLIC=y +CONFIG_RISCV_MACHINE_TIMER=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_PINCTRL=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_CLOCK_CONTROL=y + +# Serial driver options +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# GPIO driver options +CONFIG_GPIO=y + +# HW DSP options +#CONFIG_SOC_ANDES_V5_HWDSP=y diff --git a/boards/riscv/hpm6750evkmini/pre_dt_board.cmake b/boards/riscv/hpm6750evkmini/pre_dt_board.cmake new file mode 100644 index 000000000000000..9c994ae30303be5 --- /dev/null +++ b/boards/riscv/hpm6750evkmini/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2022, hpmicro +# SPDX-License-Identifier: Apache-2.0 + +# Suppress "simple_bus_reg" on HPMicro boards as all GPIO ports use the same register. +list(APPEND EXTRA_DTC_FLAGS "-Wno-simple_bus_reg") diff --git a/boards/riscv/hpm6750evkmini/support/boards/hpm6750evkmini.cfg b/boards/riscv/hpm6750evkmini/support/boards/hpm6750evkmini.cfg new file mode 100644 index 000000000000000..82c8a02827b219a --- /dev/null +++ b/boards/riscv/hpm6750evkmini/support/boards/hpm6750evkmini.cfg @@ -0,0 +1,299 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +# openocd flash driver argument: +# - ARG7: +# [31:28] Flash probe type +# 0 - SFDP SDR / 1 - SFDP DDR +# 2 - 1-4-4 Read (0xEB, 24-bit address) / 3 - 1-2-2 Read(0xBB, 24-bit address) +# 4 - HyperFLASH 1.8V / 5 - HyperFLASH 3V +# 6 - OctaBus DDR (SPI -> OPI DDR) +# 8 - Xccela DDR (SPI -> OPI DDR) +# 10 - EcoXiP DDR (SPI -> OPI DDR) +# [27:24] Command Pads after Power-on Reset +# 0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI +# [23:20] Command Pads after Configuring FLASH +# 0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI +# [19:16] Quad Enable Sequence (for the device support SFDP 1.0 only) +# 0 - Not needed +# 1 - QE bit is at bit 6 in Status Register 1 +# 2 - QE bit is at bit1 in Status Register 2 +# 3 - QE bit is at bit7 in Status Register 2 +# 4 - QE bit is at bit1 in Status Register 2 and should be programmed by 0x31 +# [15:8] Dummy cycles +# 0 - Auto-probed / detected / default value +# Others - User specified value, for DDR read, the dummy cycles should be 2 * cycles on FLASH datasheet +# [7:4] Misc. +# 0 - Not used +# 1 - SPI mode +# 2 - Internal loopback +# 3 - External DQS +# [3:0] Frequency option +# 1 - 30MHz / 2 - 50MHz / 3 - 66MHz / 4 - 80MHz / 5 - 100MHz / 6 - 120MHz / 7 - 133MHz / 8 - 166MHz +# - ARG8: +# [31:20] Reserved +# [19:16] IO voltage +# 0 - 3V / 1 - 1.8V +# [15:12] Pin group +# 0 - 1st group / 1 - 2nd group +# [11:8] Connection selection +# 0 - CA_CS0 / 1 - CB_CS0 / 2 - CA_CS0 + CB_CS0 (Two FLASH connected to CA and CB respectively) +# [7:0] Drive Strength +# 0 - Default value + +# xpi0 configs +# - flash driver: hpm_xpi +# - flash ctrl index: 0xF3040000 +# - base address: 0x80000000 +# - flash size: 0x1000000 +# - flash option0: 0x7 +flash bank xpi0 hpm_xpi 0x80000000 0x1000000 1 1 $_TARGET0 0xF3040000 0x7 + +proc init_clock {} { + $::_TARGET0 riscv dmi_write 0x39 0xF4002000 + $::_TARGET0 riscv dmi_write 0x3C 0x1 + + $::_TARGET0 riscv dmi_write 0x39 0xF4002000 + $::_TARGET0 riscv dmi_write 0x3C 0x2 + + $::_TARGET0 riscv dmi_write 0x39 0xF4000800 + $::_TARGET0 riscv dmi_write 0x3C 0xFFFFFFFF + + $::_TARGET0 riscv dmi_write 0x39 0xF4000810 + $::_TARGET0 riscv dmi_write 0x3C 0xFFFFFFFF + + $::_TARGET0 riscv dmi_write 0x39 0xF4000820 + $::_TARGET0 riscv dmi_write 0x3C 0xFFFFFFFF + + $::_TARGET0 riscv dmi_write 0x39 0xF4000830 + $::_TARGET0 riscv dmi_write 0x3C 0xFFFFFFFF + echo "clocks has been enabled!" +} + +proc init_sdram { } { +# configure dram frequency +# 133Mhz pll1_clk0: 266Mhz divide by 2 + #$::_TARGET0 riscv dmi_write 0x39 0xF4001820 + $::_TARGET0 riscv dmi_write 0x3C 0x201 +# 166Mhz pll2_clk0: 333Mhz divide by 2 + $::_TARGET0 riscv dmi_write 0x39 0xF4001820 + $::_TARGET0 riscv dmi_write 0x3C 0x401 + + # PD13 + $::_TARGET0 riscv dmi_write 0x39 0xF4040368 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PD12 + $::_TARGET0 riscv dmi_write 0x39 0xF4040360 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PD10 + $::_TARGET0 riscv dmi_write 0x39 0xF4040350 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PD09 + $::_TARGET0 riscv dmi_write 0x39 0xF4040348 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PD08 + $::_TARGET0 riscv dmi_write 0x39 0xF4040340 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PD07 + $::_TARGET0 riscv dmi_write 0x39 0xF4040338 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PD06 + $::_TARGET0 riscv dmi_write 0x39 0xF4040330 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PD05 + $::_TARGET0 riscv dmi_write 0x39 0xF4040328 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PD04 + $::_TARGET0 riscv dmi_write 0x39 0xF4040320 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PD03 + $::_TARGET0 riscv dmi_write 0x39 0xF4040318 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PD02 + $::_TARGET0 riscv dmi_write 0x39 0xF4040310 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PD01 + $::_TARGET0 riscv dmi_write 0x39 0xF4040308 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PD00 + $::_TARGET0 riscv dmi_write 0x39 0xF4040300 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC29 + $::_TARGET0 riscv dmi_write 0x39 0xF40402E8 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC28 + $::_TARGET0 riscv dmi_write 0x39 0xF40402E0 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC27 + $::_TARGET0 riscv dmi_write 0x39 0xF40402D8 + $::_TARGET0 riscv dmi_write 0x3C 0xC + + # PC22 + $::_TARGET0 riscv dmi_write 0x39 0xF40402B0 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC21 + $::_TARGET0 riscv dmi_write 0x39 0xF40402A8 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC17 + $::_TARGET0 riscv dmi_write 0x39 0xF4040288 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC15 + $::_TARGET0 riscv dmi_write 0x39 0xF4040278 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC12 + $::_TARGET0 riscv dmi_write 0x39 0xF4040260 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC11 + $::_TARGET0 riscv dmi_write 0x39 0xF4040258 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC10 + $::_TARGET0 riscv dmi_write 0x39 0xF4040250 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC09 + $::_TARGET0 riscv dmi_write 0x39 0xF4040248 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC08 + $::_TARGET0 riscv dmi_write 0x39 0xF4040240 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC07 + $::_TARGET0 riscv dmi_write 0x39 0xF4040238 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC06 + $::_TARGET0 riscv dmi_write 0x39 0xF4040230 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC05 + $::_TARGET0 riscv dmi_write 0x39 0xF4040228 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC04 + $::_TARGET0 riscv dmi_write 0x39 0xF4040220 + $::_TARGET0 riscv dmi_write 0x3C 0xC + + # PC14 + $::_TARGET0 riscv dmi_write 0x39 0xF4040270 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC13 + $::_TARGET0 riscv dmi_write 0x39 0xF4040268 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC16 + # $::_TARGET0 riscv dmi_write 0x39 0xF4040280 + $::_TARGET0 riscv dmi_write 0x3C 0x1000C + # PC26 + $::_TARGET0 riscv dmi_write 0x39 0xF40402D0 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC25 + $::_TARGET0 riscv dmi_write 0x39 0xF40402C8 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC19 + $::_TARGET0 riscv dmi_write 0x39 0xF4040298 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC18 + $::_TARGET0 riscv dmi_write 0x39 0xF4040290 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC23 + $::_TARGET0 riscv dmi_write 0x39 0xF40402B8 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC24 + $::_TARGET0 riscv dmi_write 0x39 0xF40402C0 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC30 + $::_TARGET0 riscv dmi_write 0x39 0xF40402F0 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC31 + $::_TARGET0 riscv dmi_write 0x39 0xF40402F8 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC02 + $::_TARGET0 riscv dmi_write 0x39 0xF4040210 + $::_TARGET0 riscv dmi_write 0x3C 0xC + # PC03 + $::_TARGET0 riscv dmi_write 0x39 0xF4040218 + $::_TARGET0 riscv dmi_write 0x3C 0xC + + # dramc configuration + $::_TARGET0 riscv dmi_write 0x39 0xF3050000 + $::_TARGET0 riscv dmi_write 0x3C 0x1 + sleep 10 + $::_TARGET0 riscv dmi_write 0x39 0xF3050000 + $::_TARGET0 riscv dmi_write 0x3C 0x2 + $::_TARGET0 riscv dmi_write 0x39 0xF3050008 + $::_TARGET0 riscv dmi_write 0x3C 0x30524 + $::_TARGET0 riscv dmi_write 0x39 0xF305000C + $::_TARGET0 riscv dmi_write 0x3C 0x6030524 + $::_TARGET0 riscv dmi_write 0x39 0xF3050000 + $::_TARGET0 riscv dmi_write 0x3C 0x10000000 + + # 16MB + $::_TARGET0 riscv dmi_write 0x39 0xF3050010 + $::_TARGET0 riscv dmi_write 0x3C 0x40000019 + $::_TARGET0 riscv dmi_write 0x39 0xF3050014 + $::_TARGET0 riscv dmi_write 0x3C 0 + # 16-bit + $::_TARGET0 riscv dmi_write 0x39 0xF3050040 + $::_TARGET0 riscv dmi_write 0x3C 0xf31 + + # 133Mhz configuration + #$::_TARGET0 riscv dmi_write 0x39 0xF3050044 + $::_TARGET0 riscv dmi_write 0x3C 0x884e22 + # 166Mhz configuration + $::_TARGET0 riscv dmi_write 0x39 0xF3050044 + $::_TARGET0 riscv dmi_write 0x3C 0x884e33 + + $::_TARGET0 riscv dmi_write 0x39 0xF3050048 + $::_TARGET0 riscv dmi_write 0x3C 0x1020d0d + $::_TARGET0 riscv dmi_write 0x39 0xF3050048 + $::_TARGET0 riscv dmi_write 0x3C 0x1020d0d + $::_TARGET0 riscv dmi_write 0x39 0xF305004C + $::_TARGET0 riscv dmi_write 0x3C 0x2020300 + + # config delay cell + $::_TARGET0 riscv dmi_write 0x39 0xF3050150 + $::_TARGET0 riscv dmi_write 0x3C 0x3b + $::_TARGET0 riscv dmi_write 0x39 0xF3050150 + $::_TARGET0 riscv dmi_write 0x3C 0x203b + + $::_TARGET0 riscv dmi_write 0x39 0xF3050094 + $::_TARGET0 riscv dmi_write 0x3C 0 + $::_TARGET0 riscv dmi_write 0x39 0xF3050098 + $::_TARGET0 riscv dmi_write 0x3C 0 + + # precharge all + $::_TARGET0 riscv dmi_write 0x39 0xF3050090 + $::_TARGET0 riscv dmi_write 0x3C 0x40000000 + $::_TARGET0 riscv dmi_write 0x39 0xF305009C + $::_TARGET0 riscv dmi_write 0x3C 0xA55A000F + sleep 500 + $::_TARGET0 riscv dmi_write 0x39 0xF305003C + $::_TARGET0 riscv dmi_write 0x3C 0x3 + # auto refresh + $::_TARGET0 riscv dmi_write 0x39 0xF305009C + $::_TARGET0 riscv dmi_write 0x3C 0xA55A000C + sleep 500 + $::_TARGET0 riscv dmi_write 0x39 0xF305003C + $::_TARGET0 riscv dmi_write 0x3C 0x3 + $::_TARGET0 riscv dmi_write 0x39 0xF305009C + $::_TARGET0 riscv dmi_write 0x3C 0xA55A000C + sleep 500 + $::_TARGET0 riscv dmi_write 0x39 0xF305003C + $::_TARGET0 riscv dmi_write 0x3C 0x3 + + # set mode + $::_TARGET0 riscv dmi_write 0x39 0xF30500A0 + $::_TARGET0 riscv dmi_write 0x3C 0x33 + $::_TARGET0 riscv dmi_write 0x39 0xF305009C + $::_TARGET0 riscv dmi_write 0x3C 0xA55A000A + sleep 500 + $::_TARGET0 riscv dmi_write 0x39 0xF305003C + $::_TARGET0 riscv dmi_write 0x3C 0x3 + + $::_TARGET0 riscv dmi_write 0x39 0xF305004C + $::_TARGET0 riscv dmi_write 0x3C 0x2020301 + echo "SDRAM has been initialized" +} + +$_TARGET0 configure -event reset-init { + init_clock + init_sdram +} + +$_TARGET0 configure -event gdb-attach { + reset halt +} diff --git a/boards/riscv/hpm6750evkmini/support/probes/ft2232.cfg b/boards/riscv/hpm6750evkmini/support/probes/ft2232.cfg new file mode 100644 index 000000000000000..4b1a661f08d60ae --- /dev/null +++ b/boards/riscv/hpm6750evkmini/support/probes/ft2232.cfg @@ -0,0 +1,14 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +bindto 0.0.0.0 +adapter speed 10000 +reset_config trst_and_srst +adapter srst delay 50 + +adapter driver ftdi +ftdi_vid_pid 0x0403 0x6010 + +ftdi_layout_init 0x0208 0x020b +ftdi_layout_signal nTRST -data 0x0200 -noe 0x0400 +ftdi_layout_signal nSRST -data 0x0100 -noe 0x0800 diff --git a/boards/riscv/hpm6750evkmini/support/soc/hpm6750-single-core.cfg b/boards/riscv/hpm6750evkmini/support/soc/hpm6750-single-core.cfg new file mode 100644 index 000000000000000..0139f857e4807b0 --- /dev/null +++ b/boards/riscv/hpm6750evkmini/support/soc/hpm6750-single-core.cfg @@ -0,0 +1,13 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +set _CHIP hpm6750 +set _CPUTAPID 0x1000563D +jtag newtap $_CHIP cpu -irlen 5 -expected-id $_CPUTAPID + +set _TARGET0 $_CHIP.cpu0 +target create $_TARGET0 riscv -chain-position $_CHIP.cpu -coreid 0 + +$_TARGET0 configure -work-area-phys 0x00000000 -work-area-size 0x20000 -work-area-backup 0 + +targets $_TARGET0 diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index 8a8d7fbb61a8745..c3f0ef41cbb0f10 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -26,6 +26,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SAM clock_cont zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SMARTBOND clock_control_smartbond.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NUMAKER_SCC clock_control_numaker_scc.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NXP_S32 clock_control_nxp_s32.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_HPM clock_control_hpmicro.c) if(CONFIG_CLOCK_CONTROL_STM32_CUBE) diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index f4647930ae3c9e4..c3c1d84ec650d91 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -80,4 +80,6 @@ source "drivers/clock_control/Kconfig.nxp_s32" source "drivers/clock_control/Kconfig.agilex5" +source "drivers/clock_control/Kconfig.hpmicro" + endif # CLOCK_CONTROL diff --git a/drivers/clock_control/Kconfig.hpmicro b/drivers/clock_control/Kconfig.hpmicro new file mode 100644 index 000000000000000..6fcf8c66736a5ae --- /dev/null +++ b/drivers/clock_control/Kconfig.hpmicro @@ -0,0 +1,9 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +config CLOCK_CONTROL_HPM + bool "HPMICRO clock control" + default y + depends on DT_HAS_HPMICRO_HPM_CLOCK_ENABLED + help + Enable driver for Hpmicro Clock Unit. diff --git a/drivers/clock_control/clock_control_hpmicro.c b/drivers/clock_control/clock_control_hpmicro.c new file mode 100644 index 000000000000000..ee672d58527d486 --- /dev/null +++ b/drivers/clock_control/clock_control_hpmicro.c @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#define DT_DRV_COMPAT hpmicro_hpm_clock + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct clock_control_hpmicro_config { + PLLCTL_Type *base; + uint32_t freq; + uint32_t sys_core; + uint32_t ram_up_time; + uint32_t sysctl_present; +}; + +const static uint32_t hpm_clock_src_map[] = { +IF_ENABLED(HPM_CLK_HAS_SRC_OSC24M, ([HPM_CLK_SRC_OSC24M] = clk_src_osc24m,)) +IF_ENABLED(HPM_CLK_HAS_SRC_PLL0_CLK0, ([HPM_CLK_SRC_PLL0_CLK0] = clk_src_pll0_clk0,)) +IF_ENABLED(HPM_CLK_HAS_SRC_PLL1_CLK0, ([HPM_CLK_SRC_PLL1_CLK0] = clk_src_pll1_clk0,)) +IF_ENABLED(HPM_CLK_HAS_SRC_PLL1_CLK1, ([HPM_CLK_SRC_PLL1_CLK1] = clk_src_pll1_clk1,)) +IF_ENABLED(HPM_CLK_HAS_SRC_PLL2_CLK0, ([HPM_CLK_SRC_PLL2_CLK0] = clk_src_pll2_clk0,)) +IF_ENABLED(HPM_CLK_HAS_SRC_PLL2_CLK1, ([HPM_CLK_SRC_PLL2_CLK1] = clk_src_pll2_clk1,)) +IF_ENABLED(HPM_CLK_HAS_SRC_PLL3_CLK0, ([HPM_CLK_SRC_PLL3_CLK0] = clk_src_pll3_clk0,)) +IF_ENABLED(HPM_CLK_HAS_SRC_PLL4_CLK0, ([HPM_CLK_SRC_PLL4_CLK0] = clk_src_pll4_clk0,)) +IF_ENABLED(HPM_CLK_HAS_SRC_OSC32K, ([HPM_CLK_SRC_OSC32K] = clk_src_osc32k,)) +IF_ENABLED(HPM_CLK_HAS_ADC_SRC_AHB0, ([HPM_CLK_ADC_SRC_AHB0] = clk_adc_src_ahb0,)) +IF_ENABLED(HPM_CLK_HAS_ADC_SRC_ANA0, ([HPM_CLK_ADC_SRC_ANA0] = clk_adc_src_ana0,)) +IF_ENABLED(HPM_CLK_HAS_ADC_SRC_ANA1, ([HPM_CLK_ADC_SRC_ANA1] = clk_adc_src_ana1,)) +IF_ENABLED(HPM_CLK_HAS_ADC_SRC_ANA2, ([HPM_CLK_ADC_SRC_ANA2] = clk_adc_src_ana2,)) +IF_ENABLED(HPM_CLK_HAS_I2S_SRC_AHB0, ([HPM_CLK_I2S_SRC_AHB0] = clk_i2s_src_ahb0,)) +IF_ENABLED(HPM_CLK_HAS_I2S_SRC_AUD0, ([HPM_CLK_I2S_SRC_AUD0] = clk_i2s_src_aud0,)) +IF_ENABLED(HPM_CLK_HAS_I2S_SRC_AUD1, ([HPM_CLK_I2S_SRC_AUD1] = clk_i2s_src_aud1,)) +IF_ENABLED(HPM_CLK_HAS_I2S_SRC_AUD2, ([HPM_CLK_I2S_SRC_AUD2] = clk_i2s_src_aud2)) +}; + +const static uint32_t hpm_clock_name_map[] = { +IF_ENABLED(HPM_CLOCK_HAS_CPU0, ([HPM_CLOCK_CPU0] = clock_cpu0,)) +IF_ENABLED(HPM_CLOCK_HAS_CPU1, ([HPM_CLOCK_CPU1] = clock_cpu1,)) +IF_ENABLED(HPM_CLOCK_HAS_MCHTMR0, ([HPM_CLOCK_MCHTMR0] = clock_mchtmr0,)) +IF_ENABLED(HPM_CLOCK_HAS_MCHTMR1, ([HPM_CLOCK_MCHTMR1] = clock_mchtmr1,)) +IF_ENABLED(HPM_CLOCK_HAS_AXI0, ([HPM_CLOCK_AXI0] = clock_axi0,)) +IF_ENABLED(HPM_CLOCK_HAS_AXI1, ([HPM_CLOCK_AXI1] = clock_axi1,)) +IF_ENABLED(HPM_CLOCK_HAS_AXI2, ([HPM_CLOCK_AXI2] = clock_axi2,)) +IF_ENABLED(HPM_CLOCK_HAS_AHB, ([HPM_CLOCK_AHB] = clock_ahb,)) +IF_ENABLED(HPM_CLOCK_HAS_DRAM, ([HPM_CLOCK_DRAM] = clock_dram,)) +IF_ENABLED(HPM_CLOCK_HAS_XPI0, ([HPM_CLOCK_XPI0] = clock_xpi0,)) +IF_ENABLED(HPM_CLOCK_HAS_XPI1, ([HPM_CLOCK_XPI1] = clock_xpi1,)) +IF_ENABLED(HPM_CLOCK_HAS_GPTMR0, ([HPM_CLOCK_GPTMR0] = clock_gptmr0,)) +IF_ENABLED(HPM_CLOCK_HAS_GPTMR1, ([HPM_CLOCK_GPTMR1] = clock_gptmr1,)) +IF_ENABLED(HPM_CLOCK_HAS_GPTMR2, ([HPM_CLOCK_GPTMR2] = clock_gptmr2,)) +IF_ENABLED(HPM_CLOCK_HAS_GPTMR3, ([HPM_CLOCK_GPTMR3] = clock_gptmr3,)) +IF_ENABLED(HPM_CLOCK_HAS_GPTMR4, ([HPM_CLOCK_GPTMR4] = clock_gptmr4,)) +IF_ENABLED(HPM_CLOCK_HAS_GPTMR5, ([HPM_CLOCK_GPTMR5] = clock_gptmr5,)) +IF_ENABLED(HPM_CLOCK_HAS_GPTMR6, ([HPM_CLOCK_GPTMR6] = clock_gptmr6,)) +IF_ENABLED(HPM_CLOCK_HAS_GPTMR7, ([HPM_CLOCK_GPTMR7] = clock_gptmr7,)) +IF_ENABLED(HPM_CLOCK_HAS_UART0, ([HPM_CLOCK_UART0] = clock_uart0,)) +IF_ENABLED(HPM_CLOCK_HAS_UART1, ([HPM_CLOCK_UART1] = clock_uart1,)) +IF_ENABLED(HPM_CLOCK_HAS_UART2, ([HPM_CLOCK_UART2] = clock_uart2,)) +IF_ENABLED(HPM_CLOCK_HAS_UART3, ([HPM_CLOCK_UART3] = clock_uart3,)) +IF_ENABLED(HPM_CLOCK_HAS_UART4, ([HPM_CLOCK_UART4] = clock_uart4,)) +IF_ENABLED(HPM_CLOCK_HAS_UART5, ([HPM_CLOCK_UART5] = clock_uart5,)) +IF_ENABLED(HPM_CLOCK_HAS_UART6, ([HPM_CLOCK_UART6] = clock_uart6,)) +IF_ENABLED(HPM_CLOCK_HAS_UART7, ([HPM_CLOCK_UART7] = clock_uart7,)) +IF_ENABLED(HPM_CLOCK_HAS_UART8, ([HPM_CLOCK_UART8] = clock_uart8,)) +IF_ENABLED(HPM_CLOCK_HAS_UART9, ([HPM_CLOCK_UART9] = clock_uart9,)) +IF_ENABLED(HPM_CLOCK_HAS_UART10, ([HPM_CLOCK_UART10] = clock_uart10,)) +IF_ENABLED(HPM_CLOCK_HAS_UART11, ([HPM_CLOCK_UART11] = clock_uart11,)) +IF_ENABLED(HPM_CLOCK_HAS_UART12, ([HPM_CLOCK_UART12] = clock_uart12,)) +IF_ENABLED(HPM_CLOCK_HAS_UART13, ([HPM_CLOCK_UART13] = clock_uart13,)) +IF_ENABLED(HPM_CLOCK_HAS_UART14, ([HPM_CLOCK_UART14] = clock_uart14,)) +IF_ENABLED(HPM_CLOCK_HAS_UART15, ([HPM_CLOCK_UART15] = clock_uart15,)) +IF_ENABLED(HPM_CLOCK_HAS_I2C0, ([HPM_CLOCK_I2C0] = clock_i2c0,)) +IF_ENABLED(HPM_CLOCK_HAS_I2C1, ([HPM_CLOCK_I2C1] = clock_i2c1,)) +IF_ENABLED(HPM_CLOCK_HAS_I2C2, ([HPM_CLOCK_I2C2] = clock_i2c2,)) +IF_ENABLED(HPM_CLOCK_HAS_I2C3, ([HPM_CLOCK_I2C3] = clock_i2c3,)) +IF_ENABLED(HPM_CLOCK_HAS_SPI0, ([HPM_CLOCK_SPI0] = clock_spi0,)) +IF_ENABLED(HPM_CLOCK_HAS_SPI1, ([HPM_CLOCK_SPI1] = clock_spi1,)) +IF_ENABLED(HPM_CLOCK_HAS_SPI2, ([HPM_CLOCK_SPI2] = clock_spi2,)) +IF_ENABLED(HPM_CLOCK_HAS_SPI3, ([HPM_CLOCK_SPI3] = clock_spi3,)) +IF_ENABLED(HPM_CLOCK_HAS_CAN0, ([HPM_CLOCK_CAN0] = clock_can0,)) +IF_ENABLED(HPM_CLOCK_HAS_CAN1, ([HPM_CLOCK_CAN1] = clock_can1,)) +IF_ENABLED(HPM_CLOCK_HAS_CAN2, ([HPM_CLOCK_CAN2] = clock_can2,)) +IF_ENABLED(HPM_CLOCK_HAS_CAN3, ([HPM_CLOCK_CAN3] = clock_can3,)) +IF_ENABLED(HPM_CLOCK_HAS_DISPLAY, ([HPM_CLOCK_DISPLAY] = clock_display,)) +IF_ENABLED(HPM_CLOCK_HAS_SDXC0, ([HPM_CLOCK_SDXC0] = clock_sdxc0,)) +IF_ENABLED(HPM_CLOCK_HAS_SDXC1, ([HPM_CLOCK_SDXC1] = clock_sdxc1,)) +IF_ENABLED(HPM_CLOCK_HAS_CAMERA0, ([HPM_CLOCK_CAMERA0] = clock_camera0,)) +IF_ENABLED(HPM_CLOCK_HAS_CAMERA1, ([HPM_CLOCK_CAMERA1] = clock_camera1,)) +IF_ENABLED(HPM_CLOCK_HAS_NTMR0, ([HPM_CLOCK_NTMR0] = clock_ntmr0,)) +IF_ENABLED(HPM_CLOCK_HAS_NTMR1, ([HPM_CLOCK_NTMR1] = clock_ntmr1,)) +IF_ENABLED(HPM_CLOCK_HAS_PTPC, ([HPM_CLOCK_PTPC] = clock_ptpc,)) +IF_ENABLED(HPM_CLOCK_HAS_REF0, ([HPM_CLOCK_REF0] = clock_ref0,)) +IF_ENABLED(HPM_CLOCK_HAS_REF1, ([HPM_CLOCK_REF1] = clock_ref1,)) +IF_ENABLED(HPM_CLOCK_HAS_WATCHDOG0, ([HPM_CLOCK_WATCHDOG0] = clock_watchdog0,)) +IF_ENABLED(HPM_CLOCK_HAS_WATCHDOG1, ([HPM_CLOCK_WATCHDOG1] = clock_watchdog1,)) +IF_ENABLED(HPM_CLOCK_HAS_WATCHDOG2, ([HPM_CLOCK_WATCHDOG2] = clock_watchdog2,)) +IF_ENABLED(HPM_CLOCK_HAS_WATCHDOG3, ([HPM_CLOCK_WATCHDOG3] = clock_watchdog3,)) +IF_ENABLED(HPM_CLOCK_HAS_PUART, ([HPM_CLOCK_PUART] = clock_puart,)) +IF_ENABLED(HPM_CLOCK_HAS_PWDG, ([HPM_CLOCK_PWDG] = clock_pwdg,)) +IF_ENABLED(HPM_CLOCK_HAS_ETH0, ([HPM_CLOCK_ETH0] = clock_eth0,)) +IF_ENABLED(HPM_CLOCK_HAS_ETH1, ([HPM_CLOCK_ETH1] = clock_eth1,)) +IF_ENABLED(HPM_CLOCK_HAS_PTP0, ([HPM_CLOCK_PTP0] = clock_ptp0,)) +IF_ENABLED(HPM_CLOCK_HAS_PTP1, ([HPM_CLOCK_PTP1] = clock_ptp1,)) +IF_ENABLED(HPM_CLOCK_HAS_SDP, ([HPM_CLOCK_SDP] = clock_sdp,)) +IF_ENABLED(HPM_CLOCK_HAS_XDMA, ([HPM_CLOCK_XDMA] = clock_xdma,)) +IF_ENABLED(HPM_CLOCK_HAS_ROM, ([HPM_CLOCK_ROM] = clock_rom,)) +IF_ENABLED(HPM_CLOCK_HAS_RAM0, ([HPM_CLOCK_RAM0] = clock_ram0,)) +IF_ENABLED(HPM_CLOCK_HAS_RAM1, ([HPM_CLOCK_RAM1] = clock_ram1,)) +IF_ENABLED(HPM_CLOCK_HAS_USB0, ([HPM_CLOCK_USB0] = clock_usb0,)) +IF_ENABLED(HPM_CLOCK_HAS_USB1, ([HPM_CLOCK_USB1] = clock_usb1,)) +IF_ENABLED(HPM_CLOCK_HAS_JPEG, ([HPM_CLOCK_JPEG] = clock_jpeg,)) +IF_ENABLED(HPM_CLOCK_HAS_PDMA, ([HPM_CLOCK_PDMA] = clock_pdma,)) +IF_ENABLED(HPM_CLOCK_HAS_KMAN, ([HPM_CLOCK_KMAN] = clock_kman,)) +IF_ENABLED(HPM_CLOCK_HAS_GPIO, ([HPM_CLOCK_GPIO] = clock_gpio,)) +IF_ENABLED(HPM_CLOCK_HAS_MBX0, ([HPM_CLOCK_MBX0] = clock_mbx0,)) +IF_ENABLED(HPM_CLOCK_HAS_MBX1, ([HPM_CLOCK_MBX1] = clock_mbx1,)) +IF_ENABLED(HPM_CLOCK_HAS_HDMA, ([HPM_CLOCK_HDMA] = clock_hdma,)) +IF_ENABLED(HPM_CLOCK_HAS_RNG, ([HPM_CLOCK_RNG] = clock_rng,)) +IF_ENABLED(HPM_CLOCK_HAS_MOT0, ([HPM_CLOCK_MOT0] = clock_mot0,)) +IF_ENABLED(HPM_CLOCK_HAS_MOT1, ([HPM_CLOCK_MOT1] = clock_mot1,)) +IF_ENABLED(HPM_CLOCK_HAS_MOT2, ([HPM_CLOCK_MOT2] = clock_mot2,)) +IF_ENABLED(HPM_CLOCK_HAS_MOT3, ([HPM_CLOCK_MOT3] = clock_mot3,)) +IF_ENABLED(HPM_CLOCK_HAS_ACMP, ([HPM_CLOCK_ACMP] = clock_acmp,)) +IF_ENABLED(HPM_CLOCK_HAS_PDM, ([HPM_CLOCK_PDM] = clock_pdm,)) +IF_ENABLED(HPM_CLOCK_HAS_DAO, ([HPM_CLOCK_DAO] = clock_dao,)) +IF_ENABLED(HPM_CLOCK_HAS_MSYN, ([HPM_CLOCK_MSYN] = clock_msyn,)) +IF_ENABLED(HPM_CLOCK_HAS_LMM0, ([HPM_CLOCK_LMM0] = clock_lmm0,)) +IF_ENABLED(HPM_CLOCK_HAS_LMM1, ([HPM_CLOCK_LMM1] = clock_lmm1,)) +IF_ENABLED(HPM_CLOCK_HAS_ANA0, ([HPM_CLOCK_ANA0] = clock_ana0,)) +IF_ENABLED(HPM_CLOCK_HAS_ANA1, ([HPM_CLOCK_ANA1] = clock_ana1,)) +IF_ENABLED(HPM_CLOCK_HAS_ANA2, ([HPM_CLOCK_ANA2] = clock_ana2,)) +IF_ENABLED(HPM_CLOCK_HAS_ADC0, ([HPM_CLOCK_ADC0] = clock_adc0,)) +IF_ENABLED(HPM_CLOCK_HAS_ADC1, ([HPM_CLOCK_ADC1] = clock_adc1,)) +IF_ENABLED(HPM_CLOCK_HAS_ADC2, ([HPM_CLOCK_ADC2] = clock_adc2,)) +IF_ENABLED(HPM_CLOCK_HAS_ADC3, ([HPM_CLOCK_ADC3] = clock_adc3,)) +IF_ENABLED(HPM_CLOCK_HAS_AUD0, ([HPM_CLOCK_AUD0] = clock_aud0,)) +IF_ENABLED(HPM_CLOCK_HAS_AUD1, ([HPM_CLOCK_AUD1] = clock_aud1,)) +IF_ENABLED(HPM_CLOCK_HAS_AUD2, ([HPM_CLOCK_AUD2] = clock_aud2,)) +IF_ENABLED(HPM_CLOCK_HAS_I2S0, ([HPM_CLOCK_I2S0] = clock_i2s0,)) +IF_ENABLED(HPM_CLOCK_HAS_I2S1, ([HPM_CLOCK_I2S1] = clock_i2s1,)) +IF_ENABLED(HPM_CLOCK_HAS_I2S2, ([HPM_CLOCK_I2S2] = clock_i2s2,)) +IF_ENABLED(HPM_CLOCK_HAS_I2S3, ([HPM_CLOCK_I2S3] = clock_i2s3,)) +IF_ENABLED(HPM_CLOCK_HAS_OSC0CLK0, ([HPM_CLOCK_OSC0CLK0] = clk_osc0clk0,)) +IF_ENABLED(HPM_CLOCK_HAS_PLL0CLK0, ([HPM_CLOCK_PLL0CLK0] = clk_pll0clk0,)) +IF_ENABLED(HPM_CLOCK_HAS_PLL1CLK0, ([HPM_CLOCK_PLL1CLK0] = clk_pll1clk0,)) +IF_ENABLED(HPM_CLOCK_HAS_PLL1CLK1, ([HPM_CLOCK_PLL1CLK1] = clk_pll1clk1,)) +IF_ENABLED(HPM_CLOCK_HAS_PLL2CLK0, ([HPM_CLOCK_PLL2CLK0] = clk_pll2clk0,)) +IF_ENABLED(HPM_CLOCK_HAS_PLL2CLK1, ([HPM_CLOCK_PLL2CLK1] = clk_pll2clk1,)) +IF_ENABLED(HPM_CLOCK_HAS_PLL3CLK0, ([HPM_CLOCK_PLL3CLK0] = clk_pll3clk0,)) +IF_ENABLED(HPM_CLOCK_HAS_PLL4CLK0, ([HPM_CLOCK_PLL4CLK0] = clk_pll4clk0,)) +}; + +static int clock_control_hpmicro_init(const struct device *dev) +{ + const struct clock_control_hpmicro_config *config = dev->config; + uint32_t cpu0_freq = clock_get_frequency(config->sys_core); + uint32_t clock_group = 0; + + if (cpu0_freq == PLLCTL_SOC_PLL_REFCLK_FREQ) { + /* Configure the External OSC ramp-up time*/ + pllctl_xtal_set_rampup_time(config->base, config->ram_up_time); + + /* Select clock setting preset1 */ + sysctl_clock_set_preset(HPM_SYSCTL, config->sysctl_present); + } + /* Add most Clocks to group */ + IF_ENABLED(HPM_CLOCK_HAS_CPU0, (clock_add_to_group(clock_cpu0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_MCHTMR0, (clock_add_to_group(clock_mchtmr0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_AXI0, (clock_add_to_group(clock_axi0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_AXI1, (clock_add_to_group(clock_axi1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_AXI2, (clock_add_to_group(clock_axi2, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_AHB, (clock_add_to_group(clock_ahb, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_DRAM, (clock_add_to_group(clock_dram, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_XPI0, (clock_add_to_group(clock_xpi0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_XPI1, (clock_add_to_group(clock_xpi1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_GPTMR0, (clock_add_to_group(clock_gptmr0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_GPTMR1, (clock_add_to_group(clock_gptmr1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_GPTMR2, (clock_add_to_group(clock_gptmr2, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_GPTMR3, (clock_add_to_group(clock_gptmr3, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_GPTMR4, (clock_add_to_group(clock_gptmr4, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_GPTMR5, (clock_add_to_group(clock_gptmr5, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_GPTMR6, (clock_add_to_group(clock_gptmr6, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_GPTMR7, (clock_add_to_group(clock_gptmr7, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_UART0, (clock_add_to_group(clock_uart0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_UART1, (clock_add_to_group(clock_uart1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_UART2, (clock_add_to_group(clock_uart2, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_UART3, (clock_add_to_group(clock_uart3, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_UART13, (clock_add_to_group(clock_uart13, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_I2C0, (clock_add_to_group(clock_i2c0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_I2C1, (clock_add_to_group(clock_i2c1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_I2C2, (clock_add_to_group(clock_i2c2, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_I2C3, (clock_add_to_group(clock_i2c3, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_SPI0, (clock_add_to_group(clock_spi0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_SPI1, (clock_add_to_group(clock_spi1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_SPI2, (clock_add_to_group(clock_spi2, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_SPI3, (clock_add_to_group(clock_spi3, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_CAN0, (clock_add_to_group(clock_can0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_CAN1, (clock_add_to_group(clock_can1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_CAN2, (clock_add_to_group(clock_can2, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_CAN3, (clock_add_to_group(clock_can3, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_DISPLAY, (clock_add_to_group(clock_display, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_SDXC0, (clock_add_to_group(clock_sdxc0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_SDXC1, (clock_add_to_group(clock_sdxc1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_CAMERA0, (clock_add_to_group(clock_camera0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_CAMERA1, (clock_add_to_group(clock_camera1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_PTPC, (clock_add_to_group(clock_ptpc, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_REF0, (clock_add_to_group(clock_ref0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_REF1, (clock_add_to_group(clock_ref1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_WATCHDOG0, (clock_add_to_group(clock_watchdog0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_ETH0, (clock_add_to_group(clock_eth0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_ETH1, (clock_add_to_group(clock_eth1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_SDP, (clock_add_to_group(clock_sdp, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_XDMA, (clock_add_to_group(clock_xdma, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_RAM0, (clock_add_to_group(clock_ram0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_RAM1, (clock_add_to_group(clock_ram1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_USB0, (clock_add_to_group(clock_usb0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_USB1, (clock_add_to_group(clock_usb1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_JPEG, (clock_add_to_group(clock_jpeg, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_PDMA, (clock_add_to_group(clock_pdma, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_KMAN, (clock_add_to_group(clock_kman, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_GPIO, (clock_add_to_group(clock_gpio, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_MBX0, (clock_add_to_group(clock_mbx0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_HDMA, (clock_add_to_group(clock_hdma, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_RNG, (clock_add_to_group(clock_rng, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_MOT0, (clock_add_to_group(clock_mot0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_MOT1, (clock_add_to_group(clock_mot1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_MOT2, (clock_add_to_group(clock_mot2, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_MOT3, (clock_add_to_group(clock_mot3, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_ACMP, (clock_add_to_group(clock_acmp, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_DAO, (clock_add_to_group(clock_dao, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_MSYN, (clock_add_to_group(clock_msyn, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_LMM0, (clock_add_to_group(clock_lmm0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_LMM1, (clock_add_to_group(clock_lmm1, clock_group);)) + + IF_ENABLED(HPM_CLOCK_HAS_ADC0, (clock_add_to_group(clock_adc0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_ADC1, (clock_add_to_group(clock_adc1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_ADC2, (clock_add_to_group(clock_adc2, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_ADC3, (clock_add_to_group(clock_adc3, clock_group);)) + + IF_ENABLED(HPM_CLOCK_HAS_I2S0, (clock_add_to_group(clock_i2s0, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_I2S1, (clock_add_to_group(clock_i2s1, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_I2S2, (clock_add_to_group(clock_i2s2, clock_group);)) + IF_ENABLED(HPM_CLOCK_HAS_I2S3, (clock_add_to_group(clock_i2s3, clock_group);)) + + /* Connect Group0 to CPU0 */ + clock_connect_group_to_cpu(0, 0); + + if (status_success != pllctl_init_int_pll_with_freq(config->base, 0, config->freq)) { + return -1; + } + + clock_set_source_divider(clock_cpu0, clk_src_pll0_clk0, 1); + /* Connect Group1 to CPU1 */ + clock_connect_group_to_cpu(1, 1); + clock_update_core_clock(); + clock_set_source_divider(clock_ahb, clk_src_pll1_clk1, 2); + clock_set_source_divider(clock_mchtmr0, clk_src_osc24m, 1); + /* Keep cpu clock on wfi, so that mchtmr irq can still work after wfi */ + sysctl_set_cpu_lp_mode(HPM_SYSCTL, HPM_CORE0, cpu_lp_mode_ungate_cpu_clock); + + return 0; +} + +static int hpmicro_check_sys_data(clock_control_subsys_t sys, + struct hpm_clock_configure_data *data) +{ + struct hpm_clock_configure_data cfg_data = *(struct hpm_clock_configure_data *)sys; + + if (sizeof(hpm_clock_name_map)/sizeof(uint32_t) < cfg_data.clock_name) { + return -EPERM; + } + if (sizeof(hpm_clock_src_map)/sizeof(uint32_t) < cfg_data.clock_src) { + return -EPERM; + } + *data = cfg_data; + return 0; +} + +static int clock_control_hpmicro_on(const struct device *dev, + clock_control_subsys_t sys) +{ + struct hpm_clock_configure_data cfg_data; + + if (hpmicro_check_sys_data(sys, &cfg_data) == 0) { + clock_enable(hpm_clock_name_map[cfg_data.clock_name]); + } else { + return -EPERM; + } + + return 0; +} + +static int clock_control_hpmicro_off(const struct device *dev, + clock_control_subsys_t sys) +{ + struct hpm_clock_configure_data cfg_data; + + if (hpmicro_check_sys_data(sys, &cfg_data) == 0) { + clock_disable(hpm_clock_name_map[cfg_data.clock_name]); + } else { + return -EPERM; + } + + return 0; +} + +static int clock_control_hpmicro_get_rate(const struct device *dev, + clock_control_subsys_t sys, + uint32_t *rate) +{ + struct hpm_clock_configure_data cfg_data; + + if (hpmicro_check_sys_data(sys, &cfg_data) == 0) { + *rate = clock_get_frequency(hpm_clock_name_map[cfg_data.clock_name]); + } else { + return -EPERM; + } + return 0; +} + +static int clock_control_hpmicro_configure(const struct device *dev, + clock_control_subsys_t sys, + void *data) +{ + struct hpm_clock_configure_data cfg_data; + + if (hpmicro_check_sys_data(sys, &cfg_data) != 0) { + return -EPERM; + } + clock_set_source_divider(hpm_clock_name_map[cfg_data.clock_name], + hpm_clock_src_map[cfg_data.clock_src], cfg_data.clock_div); + return 0; +} + +static const struct clock_control_hpmicro_config config = { + .base = (PLLCTL_Type *)DT_INST_REG_ADDR(0), + .freq = DT_INST_PROP(0, clock_frequency), + .sys_core = DT_INST_PROP(0, clock_sys_core), + .ram_up_time = DT_INST_PROP(0, ram_up_time), + .sysctl_present = HPM_MAKE_SYSCTL_PRESENT(DT_INST_ENUM_IDX(0, sysctl_present)), +}; + +static const struct clock_control_driver_api clock_control_hpmicro_api = { + .on = clock_control_hpmicro_on, + .off = clock_control_hpmicro_off, + .get_rate = clock_control_hpmicro_get_rate, + .configure = clock_control_hpmicro_configure, +}; + +DEVICE_DT_INST_DEFINE(0, clock_control_hpmicro_init, NULL, NULL, &config, + PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, + &clock_control_hpmicro_api); diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index b168aa38a5e3c23..373956d02578bf4 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -70,6 +70,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_MCHP_MSS gpio_mchp_mss.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SMARTBOND gpio_smartbond.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NXP_S32 gpio_nxp_s32.c) zephyr_library_sources_ifdef(CONFIG_GPIO_TCA6424A gpio_tca6424a.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_HPMICRO gpio_hpmicro.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SHELL gpio_shell.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE gpio_handlers.c) zephyr_library_sources_ifdef(CONFIG_GPIO_XMC4XXX gpio_xmc4xxx.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b008da0bd321dee..cd98407cf16a544 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -181,6 +181,8 @@ source "drivers/gpio/Kconfig.mchp_mss" source "drivers/gpio/Kconfig.xmc4xxx" +source "drivers/gpio/Kconfig.hpmicro" + source "drivers/gpio/Kconfig.smartbond" source "drivers/gpio/Kconfig.nxp_s32" diff --git a/drivers/gpio/Kconfig.hpmicro b/drivers/gpio/Kconfig.hpmicro new file mode 100644 index 000000000000000..fd04b703ef8a374 --- /dev/null +++ b/drivers/gpio/Kconfig.hpmicro @@ -0,0 +1,10 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_HPMICRO + bool "HPMicro GPIO driver" + default y + depends on DT_HAS_HPMICRO_HPM_GPIO_ENABLED + select USE_HPMSDK_GPIO + help + Enable the hpmicro gpio driver. diff --git a/drivers/gpio/gpio_hpmicro.c b/drivers/gpio/gpio_hpmicro.c new file mode 100644 index 000000000000000..816021baf928d06 --- /dev/null +++ b/drivers/gpio/gpio_hpmicro.c @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#define DT_DRV_COMPAT hpmicro_hpm_gpio + +#include +#include +#include +#include +#include +#include +#include +#include + +struct gpio_hpm_config { + struct gpio_driver_config common; + GPIO_Type *gpio_base; + uint32_t port_base; +#ifdef CONFIG_PINCTRL + const struct pinctrl_dev_config *pincfg; +#endif /* CONFIG_PINCTRL */ +}; + +struct gpio_hpm_data { + struct gpio_driver_data common; + /* port ISR callback routine address */ + sys_slist_t callbacks; +}; + +static int gpio_hpm_configure(const struct device *dev, + gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_hpm_config *config = dev->config; + GPIO_Type *gpio_base = config->gpio_base; + uint32_t port_base = config->port_base; + + if ((flags & GPIO_INPUT) && (flags & GPIO_OUTPUT)) { + return -ENOTSUP; + } + + if (flags & GPIO_SINGLE_ENDED) { + return -ENOTSUP; + } + + if ((flags & GPIO_PULL_UP) || (flags & GPIO_PULL_DOWN)) { + return -ENOTSUP; + } + + /* The flags contain options that require touching registers in the + * GPIO module and the corresponding PORT module. + * + * Start with the GPIO module and set up the pin direction register. + * 0 - pin is input, 1 - pin is output + */ + + switch (flags & GPIO_DIR_MASK) { + case GPIO_DISCONNECTED: + case GPIO_INPUT: + gpio_disable_pin_output(gpio_base, port_base, pin); + break; + case GPIO_OUTPUT: + gpio_enable_pin_output(gpio_base, port_base, pin); + if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) { + gpio_write_pin(gpio_base, port_base, pin, 1); + } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) { + gpio_write_pin(gpio_base, port_base, pin, 0); + } + break; + default: + return -ENOTSUP; + } + return 0; +} + +static int gpio_hpm_port_get_raw(const struct device *dev, uint32_t *value) +{ + const struct gpio_hpm_config *config = dev->config; + GPIO_Type *gpio_base = config->gpio_base; + uint32_t port_base = config->port_base; + + *value = gpio_read_port(gpio_base, port_base); + + return 0; +} + +static int gpio_hpm_port_set_masked_raw(const struct device *dev, + uint32_t mask, + uint32_t value) +{ + const struct gpio_hpm_config *config = dev->config; + GPIO_Type *gpio_base = config->gpio_base; + uint32_t port_base = config->port_base; + uint32_t port_val; + + port_val = gpio_read_port(gpio_base, port_base); + mask &= gpio_base->OE[port_base].CLEAR; + if (mask != 0) { + gpio_write_port(gpio_base, port_base, (port_val & ~mask) | (mask & value)); + } + + return 0; +} + +static int gpio_hpm_port_set_bits_raw(const struct device *dev, + uint32_t mask) +{ + const struct gpio_hpm_config *config = dev->config; + GPIO_Type *gpio_base = config->gpio_base; + uint32_t port_base = config->port_base; + + gpio_set_port_high_with_mask(gpio_base, port_base, mask); + + return 0; +} + +static int gpio_hpm_port_clear_bits_raw(const struct device *dev, + uint32_t mask) +{ + const struct gpio_hpm_config *config = dev->config; + GPIO_Type *gpio_base = config->gpio_base; + uint32_t port_base = config->port_base; + + gpio_set_port_low_with_mask(gpio_base, port_base, mask); + + return 0; +} + +static int gpio_hpm_port_toggle_bits(const struct device *dev, uint32_t mask) +{ + const struct gpio_hpm_config *config = dev->config; + GPIO_Type *gpio_base = config->gpio_base; + uint32_t port_base = config->port_base; + + gpio_toggle_port_with_mask(gpio_base, port_base, mask); + + return 0; +} + +static int gpio_hpm_pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + const struct gpio_hpm_config *config = dev->config; + GPIO_Type *gpio_base = config->gpio_base; + uint32_t port_base = config->port_base; + gpio_interrupt_trigger_t trigger = 0; + + if (mode == GPIO_INT_MODE_LEVEL) { + switch (trig) { + case GPIO_INT_TRIG_LOW: + trigger = gpio_interrupt_trigger_level_low; + break; + case GPIO_INT_TRIG_HIGH: + trigger = gpio_interrupt_trigger_level_high; + break; + default: + return -ENOTSUP; + } + } else if (mode == GPIO_INT_MODE_EDGE) { + switch (trig) { + case GPIO_INT_TRIG_LOW: + trigger = gpio_interrupt_trigger_edge_falling; + break; + case GPIO_INT_TRIG_HIGH: + trigger = gpio_interrupt_trigger_edge_rising; + break; + default: + return -ENOTSUP; + } + } + + if (mode == GPIO_INT_MODE_DISABLED) { + gpio_disable_pin_interrupt(gpio_base, port_base, pin); + } else { + gpio_config_pin_interrupt(gpio_base, port_base, + pin, trigger); + gpio_enable_pin_interrupt(gpio_base, port_base, + pin); + } + return 0; +} + +static int gpio_hpm_manage_callback(const struct device *dev, + struct gpio_callback *callback, bool set) +{ + struct gpio_hpm_data *data = dev->data; + + return gpio_manage_callback(&data->callbacks, callback, set); +} + +static void gpio_hpm_port_isr(const struct device *dev) +{ + const struct gpio_hpm_config *config = dev->config; + struct gpio_hpm_data *data = dev->data; + GPIO_Type *gpio_base = config->gpio_base; + uint32_t port_base = config->port_base; + uint32_t int_status; + + int_status = gpio_base->IF[port_base].VALUE; + + /* Clear the port interrupts */ + gpio_base->IF[port_base].VALUE = int_status; + + gpio_fire_callbacks(&data->callbacks, dev, int_status); +} + + +static const struct gpio_driver_api gpio_hpm_driver_api = { + .pin_configure = gpio_hpm_configure, + .port_get_raw = gpio_hpm_port_get_raw, + .port_set_masked_raw = gpio_hpm_port_set_masked_raw, + .port_set_bits_raw = gpio_hpm_port_set_bits_raw, + .port_clear_bits_raw = gpio_hpm_port_clear_bits_raw, + .port_toggle_bits = gpio_hpm_port_toggle_bits, + .pin_interrupt_configure = gpio_hpm_pin_interrupt_configure, + .manage_callback = gpio_hpm_manage_callback, +}; + +#define GPIO_HPMICRO_IRQ_INIT(n) \ + do { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), \ + gpio_hpm_port_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + \ + irq_enable(DT_INST_IRQN(n)); \ + } while (0) + +#define GPIO_PORT_BASE_ADDR(n) DT_INST_PROP(n, hpmicro_gpio_port) + +#ifdef CONFIG_PINCTRL +#define PINCTRL_INIT(n) .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), +#define PINCTRL_DEFINE(n) PINCTRL_DT_INST_DEFINE(n); +#else +#define PINCTRL_DEFINE(n) +#define PINCTRL_INIT(n) +#endif + +#define GPIO_DEVICE_INIT_HPMICRO(n) \ + static int gpio_hpm_port## n ## _init(const struct device *dev); \ + PINCTRL_DEFINE(n) \ + static const struct gpio_hpm_config gpio_hpm_port## n ## _config = {\ + .common = { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n),\ + }, \ + .gpio_base = (GPIO_Type *)DT_INST_REG_ADDR(n), \ + .port_base = GPIO_PORT_BASE_ADDR(n), \ + PINCTRL_INIT(n) \ + }; \ + \ + static struct gpio_hpm_data gpio_hpm_port## n ##_data; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + gpio_hpm_port## n ##_init, \ + NULL, \ + &gpio_hpm_port## n ##_data, \ + &gpio_hpm_port## n##_config, \ + POST_KERNEL, \ + CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_hpm_driver_api); \ + \ + static int gpio_hpm_port## n ##_init(const struct device *dev) \ + { \ + GPIO_HPMICRO_IRQ_INIT(n);\ + return 0; \ + } + +DT_INST_FOREACH_STATUS_OKAY(GPIO_DEVICE_INIT_HPMICRO) diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index c46cf3691f7051a..9add10792fbb343 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -35,3 +35,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_EMSDP pinctrl_emsdp.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_CC32XX pinctrl_ti_cc32xx.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_QUICKLOGIC_EOS_S3 pinctrl_eos_s3.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_HPMICRO pinctrl_hpmicro.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 164cbd110892e0e..852da13b252ad3d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -64,5 +64,6 @@ source "drivers/pinctrl/Kconfig.emsdp" source "drivers/pinctrl/Kconfig.ti_cc32xx" source "drivers/pinctrl/Kconfig.numaker" source "drivers/pinctrl/Kconfig.eos_s3" +source "drivers/pinctrl/Kconfig.hpmicro" endif # PINCTRL diff --git a/drivers/pinctrl/Kconfig.hpmicro b/drivers/pinctrl/Kconfig.hpmicro new file mode 100644 index 000000000000000..8464a508577dafe --- /dev/null +++ b/drivers/pinctrl/Kconfig.hpmicro @@ -0,0 +1,10 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_HPMICRO + bool "Pin controller driver for HPMicro MCUs" + default y + depends on DT_HAS_HPMICRO_HPM_PINCTRL_ENABLED + select USE_HPMSDK_PINCTRL + help + Enable pin controller driver for HPMicro series MCUs diff --git a/drivers/pinctrl/pinctrl_hpmicro.c b/drivers/pinctrl/pinctrl_hpmicro.c new file mode 100644 index 000000000000000..e505b321b9af967 --- /dev/null +++ b/drivers/pinctrl/pinctrl_hpmicro.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#define DT_DRV_COMPAT hpmicro_hpm_pinctrl +#include +#include +#include +#include +#include + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinctrl), okay) +#define IOC_BASE_ADDRESS DT_REG_ADDR(DT_NODELABEL(pinctrl)) +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinctrl_bioc), okay) +#define BIOC_BASE_ADDRESS DT_REG_ADDR(DT_NODELABEL(pinctrl_bioc)) +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinctrl_pioc), okay) +#define PIOC_BASE_ADDRESS DT_REG_ADDR(DT_NODELABEL(pinctrl_pioc)) +#endif + +static int hpmicro_pin_configure(IOC_Type *ioc_base, const uint32_t pin_mux, const uint32_t pin_cfg) +{ + uint32_t ioc_pad = HPMICRO_PAD_NUM(pin_mux); + uint32_t is_analog = HPMICRO_FUNC_ANALOG(pin_mux); + uint32_t alt_select = HPMICRO_FUNC_ALT_SELECT(pin_mux); + uint32_t loop_back = HPMICRO_FUNC_LOOPBACK(pin_cfg); + uint32_t pad_ms = HPMICRO_PAD_CTL_MS(pin_cfg); + uint32_t pad_od = HPMICRO_PAD_CTL_OD(pin_cfg); + uint32_t pad_smt = HPMICRO_PAD_CTL_SMT(pin_cfg); + uint32_t pad_ps = HPMICRO_PAD_CTL_PS(pin_cfg); + uint32_t pad_pe = HPMICRO_PAD_CTL_PE(pin_cfg); + uint32_t pad_ds = HPMICRO_PAD_CTL_DS(pin_cfg); + + ioc_base->PAD[ioc_pad].FUNC_CTL = + IOC_PAD_FUNC_CTL_LOOP_BACK_SET(loop_back) | + IOC_PAD_FUNC_CTL_ANALOG_SET(is_analog) | + IOC_PAD_FUNC_CTL_ALT_SELECT_SET(alt_select); + + ioc_base->PAD[ioc_pad].PAD_CTL = + IOC_PAD_PAD_CTL_MS_SET(pad_ms) | + IOC_PAD_PAD_CTL_OD_SET(pad_od) | + IOC_PAD_PAD_CTL_SMT_SET(pad_smt) | + IOC_PAD_PAD_CTL_PS_SET(pad_ps) | + IOC_PAD_PAD_CTL_PE_SET(pad_pe) | + IOC_PAD_PAD_CTL_DS_SET(pad_ds); + return 0; +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + uint16_t i; + uint32_t pin_mux, pin_cfg; + int ret = -EINVAL; +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinctrl), okay) + IOC_Type *ioc_base = (IOC_Type *)IOC_BASE_ADDRESS; +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinctrl_bioc), okay) + IOC_Type *bioc_base = (IOC_Type *)BIOC_BASE_ADDRESS; +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinctrl_pioc), okay) + IOC_Type *pioc_base = (IOC_Type *)PIOC_BASE_ADDRESS; +#endif + /* configure all pins */ + for (i = 0; i < pin_cnt; i++) { + pin_mux = pins[i].pinmux; + pin_cfg = pins[i].pincfg; + if (HPMICRO_FUNC_IOC_SELECT(pin_mux) == IOC_TYPE_IOC) { +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinctrl), okay) + ret = hpmicro_pin_configure(ioc_base, pin_mux, pin_cfg); + if (ret < 0) { + return ret; + } +#endif + } else if (HPMICRO_FUNC_IOC_SELECT(pin_mux) == IOC_TYPE_BIOC) { +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinctrl_bioc), okay) + ret = hpmicro_pin_configure(bioc_base, pin_mux, pin_cfg); + if (ret < 0) { + return ret; + } +#endif + } else if (HPMICRO_FUNC_IOC_SELECT(pin_mux) == IOC_TYPE_PIOC) { +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pinctrl_pioc), okay) + ret = hpmicro_pin_configure(pioc_base, pin_mux, pin_cfg); + if (ret < 0) { + return ret; + } +#endif + } + } + return ret; +} diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 658ab50a71d6a04..84af10e93f946cb 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -66,6 +66,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_EFINIX_SAPPIHIRE uart_efinix_sapphire.c zephyr_library_sources_ifdef(CONFIG_UART_SEDI uart_sedi.c) zephyr_library_sources_ifdef(CONFIG_UART_BCM2711_MU uart_bcm2711.c) +zephyr_library_sources_ifdef(CONFIG_UART_HPM uart_hpmicro.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE uart_handlers.c) if(CONFIG_UART_NATIVE_POSIX) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index e4ab09538618331..0a993f0756714ba 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -243,4 +243,6 @@ source "drivers/serial/Kconfig.sedi" source "drivers/serial/Kconfig.bcm2711" +source "drivers/serial/Kconfig.hpmicro" + endif # SERIAL diff --git a/drivers/serial/Kconfig.hpmicro b/drivers/serial/Kconfig.hpmicro new file mode 100644 index 000000000000000..1665acc119f1de0 --- /dev/null +++ b/drivers/serial/Kconfig.hpmicro @@ -0,0 +1,12 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +config UART_HPM + bool "HPMICRO serial driver" + default y + depends on DT_HAS_HPMICRO_HPM_UART_ENABLED + select USE_HPMSDK_UART + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + help + This option enables the UART driver for HPM SoC family. diff --git a/drivers/serial/uart_hpmicro.c b/drivers/serial/uart_hpmicro.c new file mode 100644 index 000000000000000..2ee2cdb25547206 --- /dev/null +++ b/drivers/serial/uart_hpmicro.c @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#define DT_DRV_COMPAT hpmicro_hpm_uart + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct uart_hpm_cfg { + UART_Type *base; + uint32_t parity; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_config_func_t irq_config_func; +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + const struct pinctrl_dev_config *pincfg; + const struct hpm_clock_configure_data uart_clk; +}; + +struct uart_hpm_data { + uint32_t baud_rate; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t user_cb; + void *user_data; +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + +static int uart_hpm_init(const struct device *dev) +{ + const struct uart_hpm_cfg *const cfg = dev->config; + const struct device *const clk = DEVICE_DT_GET(HPMICRO_CLOCK_CONTROL_NODE); + struct uart_hpm_data *const data = dev->data; + parity_setting_t parity; + hpm_stat_t stat = status_success; + uart_config_t config = {0}; + int ret; + + ret = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + ret = clock_control_configure(clk, + (clock_control_subsys_t *) &cfg->uart_clk, NULL); + if (ret != 0) { + return ret; + } + + uart_default_config((UART_Type *)cfg->base, &config); + + ret = clock_control_get_rate(clk, + (clock_control_subsys_t *) &cfg->uart_clk, &config.src_freq_in_hz); + if (ret != 0) { + return ret; + } + config.baudrate = data->baud_rate; + switch (cfg->parity) { + case UART_CFG_PARITY_NONE: + parity = parity_none; + break; + case UART_CFG_PARITY_ODD: + parity = parity_odd; + break; + case UART_CFG_PARITY_EVEN: + parity = parity_even; + break; + default: + return -ENOTSUP; + } + config.parity = parity; + stat = uart_init((UART_Type *)cfg->base, &config); + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + cfg->irq_config_func(dev); +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + + return 0; +} + +static int uart_hpm_poll_in(const struct device *dev, unsigned char *c) +{ + const struct uart_hpm_cfg *const cfg = dev->config; + + if (status_success != uart_receive_byte((UART_Type *)cfg->base, c)) { + return 1; + } else { + return 0; + } +} + +static void uart_hpm_poll_out(const struct device *dev, unsigned char c) +{ + const struct uart_hpm_cfg *const cfg = dev->config; + + uart_send_byte((UART_Type *)cfg->base, c); +} + +static int uart_hpm_err_check(const struct device *dev) +{ + ARG_UNUSED(dev); + /* HPM Uart does not currently support error detection */ + return 0; +} + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + +int uart_hpm_fifo_fill(const struct device *dev, const uint8_t *tx_data, + int len) +{ + const struct uart_hpm_cfg *const cfg = dev->config; + uint8_t num_tx = 0U; + + if (uart_check_status((UART_Type *)cfg->base, uart_stat_transmitter_empty) != 0) { + while ((len - num_tx > 0) && (num_tx < 16)) { + uart_send_byte((UART_Type *)cfg->base, tx_data[num_tx++]); + } + } + + return num_tx; +} + +int uart_hpm_fifo_read(const struct device *dev, uint8_t *rx_data, + const int size) +{ + const struct uart_hpm_cfg *const cfg = dev->config; + uint8_t num_rx = 0U; + + while ((size - num_rx > 0) && + (uart_check_status((UART_Type *)cfg->base, uart_stat_data_ready) != 0)) { + uart_receive_byte((UART_Type *)cfg->base, &rx_data[num_rx++]); + } + + return num_rx; +} + +void uart_hpm_irq_tx_enable(const struct device *dev) +{ + const struct uart_hpm_cfg *const cfg = dev->config; + + uart_enable_irq((UART_Type *)cfg->base, uart_intr_tx_slot_avail); +} + +void uart_hpm_irq_tx_disable(const struct device *dev) +{ + const struct uart_hpm_cfg *const cfg = dev->config; + + uart_disable_irq((UART_Type *)cfg->base, uart_intr_tx_slot_avail); +} + +int uart_hpm_irq_tx_ready(const struct device *dev) +{ + const struct uart_hpm_cfg *const cfg = dev->config; + + if (uart_check_status((UART_Type *)cfg->base, uart_stat_transmitter_empty) != 0) { + return 1; + } else { + return 0; + } +} + +int uart_hpm_irq_tx_complete(const struct device *dev) +{ + const struct uart_hpm_cfg *const cfg = dev->config; + + if (uart_check_status((UART_Type *)cfg->base, uart_stat_transmitter_empty) != 0) { + return 1; + } else { + return 0; + } +} + +void uart_hpm_irq_rx_enable(const struct device *dev) +{ + const struct uart_hpm_cfg *const cfg = dev->config; + + uart_enable_irq((UART_Type *)cfg->base, uart_intr_rx_data_avail_or_timeout); +} + +void uart_hpm_irq_rx_disable(const struct device *dev) +{ + const struct uart_hpm_cfg *const cfg = dev->config; + + uart_disable_irq((UART_Type *)cfg->base, uart_intr_rx_data_avail_or_timeout); +} + +int uart_hpm_irq_rx_ready(const struct device *dev) +{ + const struct uart_hpm_cfg *const cfg = dev->config; + + if (uart_check_status((UART_Type *)cfg->base, uart_stat_data_ready) != 0) { + return 1; + } else { + return 0; + } +} + +void uart_hpm_irq_err_enable(const struct device *dev) +{ + /*This feature is not supported by the hpmicro driver */ +} + +void uart_hpm_irq_err_disable(const struct device *dev) +{ + /*This feature is not supported by the hpmicro driver */ +} + +int uart_hpm_irq_is_pending(const struct device *dev) +{ + const struct uart_hpm_cfg *const cfg = dev->config; + uint32_t irq_id; + + irq_id = uart_get_irq_id((UART_Type *)cfg->base); + if ((irq_id & uart_intr_id_rx_data_avail) || + (irq_id & uart_intr_id_tx_slot_avail)) { + return 1; + } else { + return 0; + } +} + +void uart_hpm_irq_callback_set(const struct device *dev, + uart_irq_callback_user_data_t cb, + void *user_data) +{ + struct uart_hpm_data *const dev_data = dev->data; + + dev_data->user_cb = cb; + dev_data->user_data = user_data; +} + +static void uart_hpm_isr(const struct device *dev) +{ + struct uart_hpm_data * const dev_data = dev->data; + + if (dev_data->user_cb) { + dev_data->user_cb(dev, dev_data->user_data); + } +} + +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +static const struct uart_driver_api uart_hpm_driver_api = { + .poll_in = uart_hpm_poll_in, + .poll_out = uart_hpm_poll_out, + .err_check = uart_hpm_err_check, +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = uart_hpm_fifo_fill, + .fifo_read = uart_hpm_fifo_read, + .irq_tx_enable = uart_hpm_irq_tx_enable, + .irq_tx_disable = uart_hpm_irq_tx_disable, + .irq_tx_ready = uart_hpm_irq_tx_ready, + .irq_tx_complete = uart_hpm_irq_tx_complete, + .irq_rx_enable = uart_hpm_irq_rx_enable, + .irq_rx_disable = uart_hpm_irq_rx_disable, + .irq_rx_ready = uart_hpm_irq_rx_ready, + .irq_err_enable = uart_hpm_irq_err_enable, + .irq_err_disable = uart_hpm_irq_err_disable, + .irq_is_pending = uart_hpm_irq_is_pending, + .irq_callback_set = uart_hpm_irq_callback_set, +#endif +}; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#define DEV_CONFIG_IRQ_FUNC_INIT(n) \ + .irq_config_func = irq_config_func##n, +#define UART_HPMICRO_IRQ_FUNC_DECLARE(n) \ + static void irq_config_func##n(const struct device *dev); +#define UART_HPMICRO_IRQ_FUNC_DEFINE(n) \ + static void irq_config_func##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + uart_hpm_isr, DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } +#else /* !CONFIG_UART_INTERRUPT_DRIVEN */ +#define DEV_CONFIG_IRQ_FUNC_INIT(n) +#define UART_HPMICRO_IRQ_FUNC_DECLARE(n) +#define UART_HPMICRO_IRQ_FUNC_DEFINE(n) +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +#define HPM_UART_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + UART_HPMICRO_IRQ_FUNC_DECLARE(n) \ + static struct uart_hpm_data uart_hpm_data_##n = { \ + .baud_rate = DT_INST_PROP(n, current_speed), \ + }; \ + static const struct uart_hpm_cfg uart_hpm_config_##n = { \ + .base = (UART_Type *)DT_INST_REG_ADDR(n), \ + .parity = DT_INST_ENUM_IDX_OR(n, parity, UART_CFG_PARITY_NONE), \ + DEV_CONFIG_IRQ_FUNC_INIT(n) \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + HPM_CLOCK_CFG_DATA_DEFAULT(uart_clk, n) \ + }; \ + DEVICE_DT_INST_DEFINE(n, &uart_hpm_init, \ + NULL, \ + &uart_hpm_data_##n, \ + &uart_hpm_config_##n, PRE_KERNEL_1, \ + CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_hpm_driver_api); \ + UART_HPMICRO_IRQ_FUNC_DEFINE(n) + +DT_INST_FOREACH_STATUS_OKAY(HPM_UART_INIT) diff --git a/dts/bindings/clock/hpmicro,hpm-clock.yaml b/dts/bindings/clock/hpmicro,hpm-clock.yaml new file mode 100644 index 000000000000000..c97121b677700b5 --- /dev/null +++ b/dts/bindings/clock/hpmicro,hpm-clock.yaml @@ -0,0 +1,46 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +description: HPMicro Clock + +compatible: "hpmicro,hpm-clock" + +include: [clock-controller.yaml, base.yaml] + +properties: + reg: + required: true + + clock-sys-core: + required: true + type: int + description: Configuring the core of the clock. HPM_CLOCK_CPU0 or HPM_CLOCK_CPU1 + + ram-up-time: + required: true + type: int + description: Configure the External OSC ramp-up time. 32KHZ clock + + sysctl-present: + type: int + required: true + description: | + Clock presets + 1: 24 MHz clock + 2: Recommended Settings + enum: + - 1 + - 2 + + clock-frequency: + required: true + type: int + description: Clock Frequency HZ + + "#clock-cells": + const: 3 + +clock-cells: + - name + - src + - div diff --git a/dts/bindings/gpio/hpmicro,hpm-gpio.yaml b/dts/bindings/gpio/hpmicro,hpm-gpio.yaml new file mode 100644 index 000000000000000..5425885a593d908 --- /dev/null +++ b/dts/bindings/gpio/hpmicro,hpm-gpio.yaml @@ -0,0 +1,37 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +description: HPMicro GPIO node + +compatible: "hpmicro,hpm-gpio" + +include: [gpio-controller.yaml, base.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + hpmicro-gpio-port: + type: int + description: | + GPIO Port Number + GPIOA (0UL) + GPIOB (1UL) + GPIOC (2UL) + GPIOD (3UL) + GPIOE (4UL) + GPIOF (5UL) + GPIOX (13UL) + GPIOY (14UL) + GPIOZ (15UL) + required: true + + interrupts: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/pinctrl/hpmicro,hpm-pinctrl.yaml b/dts/bindings/pinctrl/hpmicro,hpm-pinctrl.yaml new file mode 100644 index 000000000000000..f3d12439735c2d4 --- /dev/null +++ b/dts/bindings/pinctrl/hpmicro,hpm-pinctrl.yaml @@ -0,0 +1,110 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +description: | + The HPMicro pin controller is a singleton node responsible for + controlling pin function selection and pin properties. For example, you can + use this node to route UART0 RX to pin PA10 and enable the pull-up resistor + on the pin. Remapping is also supported. + + The node has the 'pinctrl' node label set in your SoC's devicetree, + so you can modify it like this: + + &pinctrl { + /* your modifications go here */ + }; + + All device pin configurations should be placed in child nodes of the + 'pinctrl' node, as shown in this example: + + &pinctrl { + pinmux_uart0: pinmux_uart0 { + group0 { + pinmux = , + ; + }; + }; + pinmux_gpiob: pinmux_gpiob { + group0 { + pinmux = , + , + ; + bias-pull-down; + }; + }; + }; + + A group can also specify shared pin properties common to all the specified + pins, such as the 'bias-pull-up' property in group 2. Here is a list of + supported standard pin properties: + + - drive-open-drain: Open-drain drive mode. + - bias-disable: Disable pull-up/down (default, not required). + - bias-pull-up: Enable pull-up resistor. + - bias-pull-down: Enable pull-down resistor. + - input-enable: enable input. + - input-schmitt-enable: enable input schmitt circuit. + +compatible: "hpmicro,hpm-pinctrl" + +include: base.yaml + +child-binding: + description: HPMicro pin controller pin group + child-binding: + description: | + HPMicro pin controller pin configuration node. + include: + - name: pincfg-node.yaml + property-allowlist: + - drive-open-drain + - input-enable + - bias-disable + - bias-pull-down + - bias-pull-up + - input-schmitt-enable + properties: + pinmux: + required: true + type: array + description: | + Represents pin mux settings. Use HPMICRO_PINMUX + With: + - pin: The gpio pin number (0, 1, ..., GPIO_NUM_MAX) + - analog: bool, select analog pin in pad + - alt_select: alt0-alt31 + - ioc: IOC_TYPE_IOC IOC_TYPE_BIOC IOC_TYPE_PIOC + drive-strength: + description: | + Pin drive capability configuration + High speed pin 3.3v: + - r000 85.61 Ohm + - r001 61.2 Ohm + - r010 42.88 Ohm + - r011 35.76 Ohm + - r111 30.67 Ohm + High speed pin 1.8v: + - r000 84.07 Ohm + - r001 60.14 Ohm + - r010 42.15 Ohm + - r011 35.19 Ohm + - r111 30.2 Ohm + Normal pin: + - rx00 4 ma + - rx01 8 ma + - rx11 12 ma + type: string + enum: + - "r000" + - "r001" + - "r010" + - "r011" + - "r100" + - "r101" + - "r110" + - "r111" + power-source: + type: string + enum: + - "3v3" + - "1v8" diff --git a/dts/bindings/serial/hpmicro,hpm-uart.yaml b/dts/bindings/serial/hpmicro,hpm-uart.yaml new file mode 100644 index 000000000000000..6c7c833df1a0f50 --- /dev/null +++ b/dts/bindings/serial/hpmicro,hpm-uart.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +description: HPMicro UART + +compatible: "hpmicro,hpm-uart" + +include: [uart-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index 4b2ab91c73e1a01..fb2a58a77bbf47c 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -260,6 +260,7 @@ honeywell Honeywell hoperf HOPERF Microelectronics Co. Ltd hoperun Jiangsu HopeRun Software Co., Ltd. hp Hewlett Packard +hpmicro HPMicro Semiconductor Co., Ltd. hsg HannStar Display Co. holtek Holtek Semiconductor, Inc. hugsun Shenzhen Hugsun Technology Co. Ltd. diff --git a/dts/riscv/hpmicro/hpm6750.dtsi b/dts/riscv/hpmicro/hpm6750.dtsi new file mode 100644 index 000000000000000..9f568e20faaaa1c --- /dev/null +++ b/dts/riscv/hpmicro/hpm6750.dtsi @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2022 HPMicro + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu0: cpu@0 { + compatible = "riscv"; + device_type = "cpu"; + reg = <0>; + status = "okay"; + riscv,isa = "rv32imafdcxandes"; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + CPU0_intc: interrupt-controller { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "riscv,cpu-intc"; + }; + }; + cpu1: cpu@1 { + compatible = "riscv"; + device_type = "cpu"; + reg = <1>; + status = "okay"; + riscv,isa = "rv32imafdcxandes"; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + CPU1_intc: interrupt-controller { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "riscv,cpu-intc"; + }; + }; + + fgpio: peripheral@C0000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xC0000 0x2000>; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "hpmicro,hpm6750"; + ranges; + clk: clock-controller@f4100000 { + compatible = "hpmicro,hpm-clock"; + reg = <0xf4100000 0x100>; + clock-frequency = <816000000>; + reg-names = "clk"; + status = "okay"; + clock-sys-core = ; + ram-up-time = <(32*1000*9)>; + sysctl-present = <2>; + #clock-cells = <3>; + }; + + mtimer: timer@e6000000 { + compatible = "andestech,machine-timer"; + reg = <0xe6000000 0x10>; + interrupts-extended = <&CPU0_intc 7 &CPU1_intc 7>; + }; + + flash0: flash@80000000 { + compatible = "soc-nv-flash"; + reg = <0x80000000 DT_SIZE_M(16)>; + }; + + ilm: memory@0 { + compatible = "zephyr,memory-region"; + reg = <0x0 DT_SIZE_K(256)>; + zephyr,memory-region = "ITCM"; + }; + + dlm: memory@80000 { + compatible = "zephyr,memory-region"; + reg = <0x080000 DT_SIZE_K(256)>; + zephyr,memory-region = "DTCM"; + }; + + sram: memory@1080000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0x01080000 DT_SIZE_K(1024)>; + }; + + core0_lm_slv: memory@1000000 { + device_type = "memory"; + reg = <0x1000000 DT_SIZE_K(512)>; + }; + + core1_lm_slv: memory@1180000 { + device_type = "memory"; + reg = <0x1180000 DT_SIZE_K(256)>; + }; + + plic0: interrupt-controller@e4000000 { + compatible = "sifive,plic-1.0.0"; + #address-cells = <1>; + #interrupt-cells = <2>; + interrupt-controller; + reg = < 0xe4000000 0x00001000 + 0xe4002000 0x00000800 + 0xe4200000 0x00010000 >; + reg-names = "prio", "irq_en", "reg"; + riscv,max-priority = <255>; + riscv,ndev = <1023>; + interrupts-extended = <&CPU0_intc 0 &CPU1_intc 0>; + }; + + plic_sw0: interrupt-controller@e6400000 { + compatible = "andestech,plic_sw"; + #address-cells = <1>; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0xe6400000 0x00400000>; + riscv,max-priority = <255>; + riscv,ndev = <1023>; + interrupts-extended = <&CPU0_intc 3 &CPU1_intc 3>; + }; + + gpio0: peripheral@f0000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xf0000000 0x4000>; + }; + + gpio1: peripheral@f0004000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xf0004000 0x4000>; + }; + + uart0: serial@f0040000 { + compatible = "hpmicro,hpm-uart"; + reg = <0xf0040000 0x1000>; + interrupts = <31 1>; + interrupt-parent = <&plic0>; + clocks = <&clk HPM_CLOCK_UART0 HPM_CLK_SRC_OSC24M 1>; + status = "disabled"; + }; + + pinctrl: pin-controller@f4040000 { + compatible = "hpmicro,hpm-pinctrl"; + reg = <0xf4040000 0x40000>; + status = "okay"; + }; + pinctrl_pioc: pin-controller@f40d8000 { + compatible = "hpmicro,hpm-pinctrl"; + reg = <0xf40d8000 0x40000>; + status = "okay"; + }; + + pinctrl_bioc: pin-controller@f5010000 { + compatible = "hpmicro,hpm-pinctrl"; + reg = <0xf5010000 0x40000>; + status = "okay"; + }; + }; +}; diff --git a/include/zephyr/drivers/clock_control/hpmicro_clock_control.h b/include/zephyr/drivers/clock_control/hpmicro_clock_control.h new file mode 100644 index 000000000000000..af4be610026672e --- /dev/null +++ b/include/zephyr/drivers/clock_control/hpmicro_clock_control.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_HPMICRO_CLOCK_CONTROL_H_ +#define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_HPMICRO_CLOCK_CONTROL_H_ + +#include +#include +#include +#include +#include + +/** + * @brief Generate clock setting preset + * + */ +#define HPM_MAKE_SYSCTL_PRESENT(x) BIT(x) + +/** + * @brief hpmicro clock_control_subsys_t configure data + * + */ + +struct hpm_clock_configure_data { + uint32_t clock_name; + uint32_t clock_src; + uint16_t clock_div; +}; + +/** Common clock control device node for all hpmicro chips */ +#define HPMICRO_CLOCK_CONTROL_NODE DT_NODELABEL(clk) + +#define HPM_CLOCK_CFG_DATA_DEFAULT(declar, n) \ + .declar.clock_name = DT_INST_CLOCKS_CELL(n, name), \ + .declar.clock_src = DT_INST_CLOCKS_CELL(n, src), \ + .declar.clock_div = DT_INST_CLOCKS_CELL(n, div), + +#endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_HPMICRO_CLOCK_CONTROL_H_ */ diff --git a/include/zephyr/drivers/pinctrl/pinctrl_hpmicro_common.h b/include/zephyr/drivers/pinctrl/pinctrl_hpmicro_common.h new file mode 100644 index 000000000000000..75424b0d5aa1356 --- /dev/null +++ b/include/zephyr/drivers/pinctrl/pinctrl_hpmicro_common.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022 HPMicro + * SPDX-License-Identifier: Apache-2.0 + */ + + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_HPMICRO_COMMON_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_HPMICRO_COMMON_H_ + +#include + +/** + * @brief Location of configuration items in the code + * + */ +#define HPMICRO_OPEN_DRAIN 1U +#define HPMICRO_OPEN_DRAIN_SHIFT 0U + +#define HPMICRO_NO_PULL 1U +#define HPMICRO_NO_PULL_SHIFT 1U + +#define HPMICRO_PULL_DOWN 1U +#define HPMICRO_PULL_DOWN_SHIFT 2U + +#define HPMICRO_PULL_UP 1U +#define HPMICRO_PULL_UP_SHIFT 3U + +#define HPMICRO_FORCE_INPUT 1U +#define HPMICRO_FORCE_INPUT_SHIFT 4U + +#define HPMICRO_DRIVER_STRENGTH 7U +#define HPMICRO_DRIVER_STRENGTH_SHIFT 5U + +#define HPMICRO_SCHMITT_ENABLE 1U +#define HPMICRO_SCHMITT_ENABLE_SHIFT 12U + +#define HPMICRO_POWER 1U +#define HPMICRO_POWER_SHIFT 13U + +#define HPMICRO_PAD_NUM(_mux)\ + (((_mux) >> HPMICRO_PIN_NUM_SHIFT) & HPMICRO_PIN_NUM_MASK) + +#define HPMICRO_FUNC_ANALOG(_mux)\ + (((_mux) >> HPMICRO_PIN_ANALOG_SHIFT) & HPMICRO_PIN_ANALOG_MASK) + +#define HPMICRO_FUNC_ALT_SELECT(_mux)\ + (((_mux) >> HPMICRO_PIN_ALT_SHIFT) & HPMICRO_PIN_ALT_MASK) + +#define HPMICRO_FUNC_IOC_SELECT(_mux)\ + (((_mux) >> HPMICRO_PIN_IOC_SHIFT) & HPMICRO_PIN_IOC_MASK) + +#define HPMICRO_FUNC_LOOPBACK(_cfg)\ + (((_cfg) >> HPMICRO_FORCE_INPUT_SHIFT) & HPMICRO_FORCE_INPUT) + +#define HPMICRO_PAD_CTL_MS(_cfg)\ + (((_cfg) >> HPMICRO_POWER_SHIFT) & HPMICRO_POWER) + +#define HPMICRO_PAD_CTL_OD(_cfg)\ + (((_cfg) >> HPMICRO_OPEN_DRAIN_SHIFT) & HPMICRO_OPEN_DRAIN) + +#define HPMICRO_PAD_CTL_SMT(_cfg)\ + (((_cfg) >> HPMICRO_SCHMITT_ENABLE_SHIFT) & HPMICRO_SCHMITT_ENABLE) + +#define HPMICRO_PAD_CTL_PULL_UP(_cfg)\ + (((_cfg) >> HPMICRO_PULL_UP_SHIFT) & HPMICRO_PULL_UP) + +#define HPMICRO_PAD_CTL_PULL_DN(_cfg)\ + (((_cfg) >> HPMICRO_PULL_DOWN_SHIFT) & HPMICRO_PULL_DOWN) + +#define HPMICRO_PAD_CTL_PS(_cfg)\ +HPMICRO_PAD_CTL_PULL_UP(_cfg) + +#define HPMICRO_PAD_CTL_PE(_cfg)\ + ((!(((_cfg) >> HPMICRO_NO_PULL_SHIFT) & HPMICRO_NO_PULL)) & \ + (HPMICRO_PAD_CTL_PULL_UP(_cfg) ^ HPMICRO_PAD_CTL_PULL_DN(_cfg))) + +#define HPMICRO_PAD_CTL_DS(_cfg)\ + (((_cfg) >> HPMICRO_DRIVER_STRENGTH_SHIFT) & HPMICRO_DRIVER_STRENGTH) + +#endif /* ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_HPMICRO_COMMON_H_ */ diff --git a/include/zephyr/dt-bindings/clock/hpmicro-clocks.h b/include/zephyr/dt-bindings/clock/hpmicro-clocks.h new file mode 100644 index 000000000000000..1fd6c812a5738a6 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/hpmicro-clocks.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_HPMICRO_CLOCKS_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_HPMICRO_CLOCKS_H_ + +/** + * @brief The cell div of clock-cell is not operated + * + */ +#define HPM_CLOCK_CELL_DIV_NONE (0xffff) +#define HPM_CLK_SRC_DEFAULT (0xffff) + +/** + * @brief Hpmicro clock src + * + */ +#define HPM_CLK_SRC_OSC24M (0U) +#define HPM_CLK_SRC_PLL0_CLK0 (1U) +#define HPM_CLK_SRC_PLL1_CLK0 (2U) +#define HPM_CLK_SRC_PLL1_CLK1 (3U) +#define HPM_CLK_SRC_PLL2_CLK0 (4U) +#define HPM_CLK_SRC_PLL2_CLK1 (5U) +#define HPM_CLK_SRC_PLL3_CLK0 (6U) +#define HPM_CLK_SRC_PLL4_CLK0 (7U) +#define HPM_CLK_SRC_OSC32K (8U) +#define HPM_CLK_ADC_SRC_AHB0 (9U) +#define HPM_CLK_ADC_SRC_ANA0 (10U) +#define HPM_CLK_ADC_SRC_ANA1 (11U) +#define HPM_CLK_ADC_SRC_ANA2 (12U) +#define HPM_CLK_I2S_SRC_AHB0 (13U) +#define HPM_CLK_I2S_SRC_AUD0 (14U) +#define HPM_CLK_I2S_SRC_AUD1 (15U) +#define HPM_CLK_I2S_SRC_AUD2 (16U) + +/** + * @brief Hpmicro clock name + * + */ +#define HPM_CLOCK_CPU0 (0U) +#define HPM_CLOCK_CPU1 (1U) +#define HPM_CLOCK_MCHTMR0 (2U) +#define HPM_CLOCK_MCHTMR1 (3U) +#define HPM_CLOCK_AXI0 (4U) +#define HPM_CLOCK_AXI1 (5U) +#define HPM_CLOCK_AXI2 (6U) +#define HPM_CLOCK_AHB (7U) +#define HPM_CLOCK_DRAM (8U) +#define HPM_CLOCK_XPI0 (9U) +#define HPM_CLOCK_XPI1 (10U) +#define HPM_CLOCK_GPTMR0 (11U) +#define HPM_CLOCK_GPTMR1 (12U) +#define HPM_CLOCK_GPTMR2 (13U) +#define HPM_CLOCK_GPTMR3 (14U) +#define HPM_CLOCK_GPTMR4 (15U) +#define HPM_CLOCK_GPTMR5 (16U) +#define HPM_CLOCK_GPTMR6 (17U) +#define HPM_CLOCK_GPTMR7 (18U) +#define HPM_CLOCK_UART0 (19U) +#define HPM_CLOCK_UART1 (20U) +#define HPM_CLOCK_UART2 (21U) +#define HPM_CLOCK_UART3 (22U) +#define HPM_CLOCK_UART4 (23U) +#define HPM_CLOCK_UART5 (24U) +#define HPM_CLOCK_UART6 (25U) +#define HPM_CLOCK_UART7 (26U) +#define HPM_CLOCK_UART8 (27U) +#define HPM_CLOCK_UART9 (28U) +#define HPM_CLOCK_UART10 (29U) +#define HPM_CLOCK_UART11 (30U) +#define HPM_CLOCK_UART12 (31U) +#define HPM_CLOCK_UART13 (32U) +#define HPM_CLOCK_UART14 (33U) +#define HPM_CLOCK_UART15 (34U) +#define HPM_CLOCK_I2C0 (35U) +#define HPM_CLOCK_I2C1 (36U) +#define HPM_CLOCK_I2C2 (37U) +#define HPM_CLOCK_I2C3 (38U) +#define HPM_CLOCK_SPI0 (39U) +#define HPM_CLOCK_SPI1 (40U) +#define HPM_CLOCK_SPI2 (41U) +#define HPM_CLOCK_SPI3 (42U) +#define HPM_CLOCK_CAN0 (43U) +#define HPM_CLOCK_CAN1 (44U) +#define HPM_CLOCK_CAN2 (45U) +#define HPM_CLOCK_CAN3 (46U) +#define HPM_CLOCK_DISPLAY (47U) +#define HPM_CLOCK_SDXC0 (48U) +#define HPM_CLOCK_SDXC1 (49U) +#define HPM_CLOCK_CAMERA0 (50U) +#define HPM_CLOCK_CAMERA1 (51U) +#define HPM_CLOCK_NTMR0 (52U) +#define HPM_CLOCK_NTMR1 (53U) + +#define HPM_CLOCK_PTPC (54U) +#define HPM_CLOCK_REF0 (55U) +#define HPM_CLOCK_REF1 (56U) +#define HPM_CLOCK_WATCHDOG0 (57U) +#define HPM_CLOCK_WATCHDOG1 (58U) +#define HPM_CLOCK_WATCHDOG2 (59U) +#define HPM_CLOCK_WATCHDOG3 (60U) +#define HPM_CLOCK_PUART (61U) +#define HPM_CLOCK_PWDG (62U) +#define HPM_CLOCK_ETH0 (63U) +#define HPM_CLOCK_ETH1 (64U) +#define HPM_CLOCK_PTP0 (65U) +#define HPM_CLOCK_PTP1 (66U) +#define HPM_CLOCK_SDP (67U) +#define HPM_CLOCK_XDMA (68U) +#define HPM_CLOCK_ROM (69U) +#define HPM_CLOCK_RAM0 (70U) +#define HPM_CLOCK_RAM1 (71U) +#define HPM_CLOCK_USB0 (72U) +#define HPM_CLOCK_USB1 (73U) +#define HPM_CLOCK_JPEG (74U) +#define HPM_CLOCK_PDMA (75U) +#define HPM_CLOCK_KMAN (76U) +#define HPM_CLOCK_GPIO (77U) +#define HPM_CLOCK_MBX0 (78U) +#define HPM_CLOCK_MBX1 (78U) +#define HPM_CLOCK_HDMA (79U) +#define HPM_CLOCK_RNG (80U) +#define HPM_CLOCK_MOT0 (81U) +#define HPM_CLOCK_MOT1 (82U) +#define HPM_CLOCK_MOT2 (83U) +#define HPM_CLOCK_MOT3 (84U) +#define HPM_CLOCK_ACMP (85U) +#define HPM_CLOCK_PDM (86U) +#define HPM_CLOCK_DAO (87U) +#define HPM_CLOCK_MSYN (88U) +#define HPM_CLOCK_LMM0 (89U) +#define HPM_CLOCK_LMM1 (90U) + +/* For ADC, there are 2-stage clock source and divider configuration */ +#define HPM_CLOCK_ANA0 (91U) +#define HPM_CLOCK_ANA1 (92U) +#define HPM_CLOCK_ANA2 (93U) +#define HPM_CLOCK_ADC0 (94U) +#define HPM_CLOCK_ADC1 (95U) +#define HPM_CLOCK_ADC2 (96U) +#define HPM_CLOCK_ADC3 (97U) + +/* For I2S, there are 2-stage clock source and divider configuration */ +#define HPM_CLOCK_AUD0 (98U) +#define HPM_CLOCK_AUD1 (99U) +#define HPM_CLOCK_AUD2 (100U) +#define HPM_CLOCK_I2S0 (101U) +#define HPM_CLOCK_I2S1 (102U) +#define HPM_CLOCK_I2S2 (103U) +#define HPM_CLOCK_I2S3 (104U) + +/* Clock sources */ +#define HPM_CLOCK_OSC0CLK0 (105U) +#define HPM_CLOCK_PLL0CLK0 (106U) +#define HPM_CLOCK_PLL1CLK0 (107U) +#define HPM_CLOCK_PLL1CLK1 (108U) +#define HPM_CLOCK_PLL2CLK0 (109U) +#define HPM_CLOCK_PLL2CLK1 (110U) +#define HPM_CLOCK_PLL3CLK0 (111U) +#define HPM_CLOCK_PLL4CLK0 (112U) + +#endif diff --git a/include/zephyr/dt-bindings/pinctrl/hpmicro-pinctrl-common.h b/include/zephyr/dt-bindings/pinctrl/hpmicro-pinctrl-common.h new file mode 100644 index 000000000000000..435428d29db4b80 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/hpmicro-pinctrl-common.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_HPMICRO_PINCTRL_COMMON_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_HPMICRO_PINCTRL_COMMON_H_ + +#include + +/** + * @brief Pin numbers of gpio + * + */ +#define HPMICRO_PIN_NUM_SHIFT 0U +#define HPMICRO_PIN_NUM_MASK BIT_MASK(10) + +/** + * @brief io peripheral function + * + */ +#define HPMICRO_PIN_ANALOG_MASK BIT_MASK(0) +#define HPMICRO_PIN_ANALOG_SHIFT 10U +#define HPMICRO_PIN_ALT_MASK BIT_MASK(5) +#define HPMICRO_PIN_ALT_SHIFT 11U +#define HPMICRO_PIN_IOC_MASK BIT_MASK(2) +#define HPMICRO_PIN_IOC_SHIFT 30U + +/** + * @brief numerical ioc_pad for IO ports + */ + +#define HPMICRO_PORTA 0 /* IO port A */ +#define HPMICRO_PORTB 32 /* .. */ +#define HPMICRO_PORTC 64 +#define HPMICRO_PORTD 96 +#define HPMICRO_PORTE 128 +#define HPMICRO_PORTF 160 +#define HPMICRO_PORTX 416 +#define HPMICRO_PORTY 448 +#define HPMICRO_PORTZ 480 /* IO port Z */ + +/** + * @brief ioc controller mode + * + */ +#define IOC_TYPE_IOC 0 +#define IOC_TYPE_BIOC 1 +#define IOC_TYPE_PIOC 2 + +/** + * @brief helper macro to encode an IO port pin in a numerical format + */ + +#define HPMICRO_PIN(_port, _pin) \ + (_port + _pin) + +/** + * @brief macro generation codes to select pin functions + * pin: HPMICRO_PIN(port, pin) + * is_analog: 1: enable analog, 0: disable analog + * alt: 0 - 31 Function Selection alt0-alt31 + * ioc: IOC_TYPE_IOC IOC_TYPE_BIOC IOC_TYPE_PIOC + */ +#define HPMICRO_PINMUX_1(pin, ioc, is_analog, alt) \ + (((pin & HPMICRO_PIN_NUM_MASK) << HPMICRO_PIN_NUM_SHIFT) | \ + ((is_analog & HPMICRO_PIN_ANALOG_MASK) << HPMICRO_PIN_ANALOG_SHIFT) | \ + ((alt & HPMICRO_PIN_ALT_MASK) << HPMICRO_PIN_ALT_SHIFT) | \ + ((ioc & HPMICRO_PIN_IOC_MASK) << HPMICRO_PIN_IOC_SHIFT)) + +/** + * @brief macro generation codes to select pin functions + * port: HPMICRO_PORTA - HPMICRO_PORTZ + * pin: 0-32 + * is_analog: 1: enable analog, 0: disable analog + * alt: 0 - 31 Function Selection alt0-alt31 + * ioc: IOC_TYPE_IOC IOC_TYPE_BIOC IOC_TYPE_PIOC + */ +#define HPMICRO_PINMUX(port, pin, ioc, is_analog, alt) \ + HPMICRO_PINMUX_1(HPMICRO_PIN(port, pin), ioc, is_analog, alt) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_HPMICRO_PINCTRL_COMMON_H_ */ diff --git a/modules/Kconfig b/modules/Kconfig index 687ce19da818abf..a5542d39299f853 100644 --- a/modules/Kconfig +++ b/modules/Kconfig @@ -59,6 +59,9 @@ comment "Unavailable modules, please install those via the project manifest." # config ZEPHYR__MODULE # bool +comment "hal_hpmicro module not available." + depends on !ZEPHYR_HAL_HPMICRO_MODULE + comment "hal_gigadevice module not available." depends on !ZEPHYR_HAL_GIGADEVICE_MODULE diff --git a/modules/hal_hpmicro/CMakeLists.txt b/modules/hal_hpmicro/CMakeLists.txt new file mode 100644 index 000000000000000..41ff98522b80ace --- /dev/null +++ b/modules/hal_hpmicro/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_HAS_HPMICRO_HAL) +add_subdirectory(${ZEPHYR_CURRENT_MODULE_DIR} hal_hpmicro) +endif() diff --git a/modules/hal_hpmicro/Kconfig b/modules/hal_hpmicro/Kconfig new file mode 100644 index 000000000000000..4c906cc08c5be9e --- /dev/null +++ b/modules/hal_hpmicro/Kconfig @@ -0,0 +1,86 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 +config ZEPHYR_HAL_HPMICRO_MODULE + bool + +config HAS_HPMICRO_HAL + bool "HPMSDK HAL drivers support" + +if HAS_HPMICRO_HAL + +config USE_HPMSDK_UART + bool "HPMSDK UART driver support" +config USE_HPMSDK_DRAM + bool "HPMSDK DRAM driver support" +config USE_HPMSDK_SDP + bool "HPMSDK SDP driver support" +config USE_HPMSDK_LCDC + bool "HPMSDK LCDC driver support" +config USE_HPMSDK_I2C + bool "HPMSDK I2C driver support" +config USE_HPMSDK_PMP + bool "HPMSDK PMP driver support" +config USE_HPMSDK_RNG + bool "HPMSDK RNG driver support" +config USE_HPMSDK_GPIO + bool "HPMSDK GPIO driver support" +config USE_HPMSDK_SPI + bool "HPMSDK SPI driver support" +config USE_HPMSDK_PDMA + bool "HPMSDK PDMA driver support" +config USE_HPMSDK_WDG + bool "HPMSDK WDG driver support" +config USE_HPMSDK_DMA + bool "HPMSDK DMA driver support" +config USE_HPMSDK_GPTMR + bool "HPMSDK GPTMR driver support" +config USE_HPMSDK_PWM + bool "HPMSDK PWM driver support" +config USE_HPMSDK_PLLCTL + bool "HPMSDK PLLCTL driver support" +config USE_HPMSDK_PLLCTLV2 + bool "HPMSDK PLLCTLV2 driver support" +config USE_HPMSDK_USB + bool "HPMSDK USB driver support" +config USE_HPMSDK_RTC + bool "HPMSDK RTC driver support" +config USE_HPMSDK_ACMP + bool "HPMSDK ACMP driver support" +config USE_HPMSDK_I2S + bool "HPMSDK I2S driver support" +config USE_HPMSDK_DAO + bool "HPMSDK DAO driver support" +config USE_HPMSDK_PDM + bool "HPMSDK PDM driver support" +config USE_HPMSDK_VAD + bool "HPMSDK VAD driver support" +config USE_HPMSDK_CAM + bool "HPMSDK CAM driver support" +config USE_HPMSDK_CAN + bool "HPMSDK CAN driver support" +config USE_HPMSDK_JPEG + bool "HPMSDK JPEG driver support" +config USE_HPMSDK_ENET + bool "HPMSDK ENET driver support" +config USE_HPMSDK_SDXC + bool "HPMSDK SDXC driver support" +config USE_HPMSDK_ADC12 + bool "HPMSDK ADC12 driver support" +config USE_HPMSDK_ADC16 + bool "HPMSDK ADC16 driver support" +config USE_HPMSDK_PMU + bool "HPMSDK PMU driver support" +config USE_HPMSDK_PTPC + bool "HPMSDK PTPC driver support" +config USE_HPMSDK_MCHTMR + bool "HPMSDK MCHTMR driver support" +config USE_HPMSDK_PINCTRL + bool "HPMSDK MCHTMR driver support" +config USE_HPMSDK_FFA + bool "HPMSDK FFA driver support" +config USE_HPMSDK_TSNS + bool "HPMSDK TSNS driver support" +config USE_HPMSDK_DAC + bool "HPMSDK DAC driver support" + +endif # HAS_HPMICRO_HAL diff --git a/soc/riscv/riscv-privileged/hpmicro/CMakeLists.txt b/soc/riscv/riscv-privileged/hpmicro/CMakeLists.txt new file mode 100644 index 000000000000000..5e4fabc458eb274 --- /dev/null +++ b/soc/riscv/riscv-privileged/hpmicro/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources( + start.S + soc.c +) + +if(CONFIG_SOC_ANDES_V5_HWDSP) + zephyr_cc_option(-mext-dsp) +endif() diff --git a/soc/riscv/riscv-privileged/hpmicro/Kconfig.defconfig.hpm6360 b/soc/riscv/riscv-privileged/hpmicro/Kconfig.defconfig.hpm6360 new file mode 100644 index 000000000000000..7acaed31d9253c7 --- /dev/null +++ b/soc/riscv/riscv-privileged/hpmicro/Kconfig.defconfig.hpm6360 @@ -0,0 +1,21 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +if SOC_HPM6360 + +config SOC + default "hpm6360" + +config SYS_CLOCK_TICKS_PER_SEC + default 1000 + +config MAIN_STACK_SIZE + default 4096 + +config IDLE_STACK_SIZE + default 2048 + +config TEST_EXTRA_STACK_SIZE + default 2048 + +endif # SOC_HPM6360 diff --git a/soc/riscv/riscv-privileged/hpmicro/Kconfig.defconfig.hpm6750 b/soc/riscv/riscv-privileged/hpmicro/Kconfig.defconfig.hpm6750 new file mode 100644 index 000000000000000..3eae66973a2de87 --- /dev/null +++ b/soc/riscv/riscv-privileged/hpmicro/Kconfig.defconfig.hpm6750 @@ -0,0 +1,21 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +if SOC_HPM6750 + +config SOC + default "hpm6750" + +config SYS_CLOCK_TICKS_PER_SEC + default 1000 + +config MAIN_STACK_SIZE + default 4096 + +config IDLE_STACK_SIZE + default 2048 + +config TEST_EXTRA_STACK_SIZE + default 2048 + +endif # SOC_HPM6750 diff --git a/soc/riscv/riscv-privileged/hpmicro/Kconfig.defconfig.series b/soc/riscv/riscv-privileged/hpmicro/Kconfig.defconfig.series new file mode 100644 index 000000000000000..5003e8d901641f9 --- /dev/null +++ b/soc/riscv/riscv-privileged/hpmicro/Kconfig.defconfig.series @@ -0,0 +1,39 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_HPMICRO + +source "soc/riscv/riscv-privileged/hpmicro/Kconfig.defconfig.hpm6*" + +config SOC_SERIES + default "hpmicro" + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 24000000 + +config KERNEL_ENTRY + default "_start" + +config RISCV_GENERIC_TOOLCHAIN + default y if "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "zephyr" + default n + +config RISCV_SOC_INTERRUPT_INIT + default y + +config RISCV_HAS_CPU_IDLE + default y + +config RISCV_HAS_PLIC + default y + +config RISCV_GP + default y + +config MAX_IRQ_PER_AGGREGATOR + default 112 + +config NUM_IRQS + default 128 + +endif # SOC_SERIES_HPMICRO diff --git a/soc/riscv/riscv-privileged/hpmicro/Kconfig.series b/soc/riscv/riscv-privileged/hpmicro/Kconfig.series new file mode 100644 index 000000000000000..e70fe69dab7ed7f --- /dev/null +++ b/soc/riscv/riscv-privileged/hpmicro/Kconfig.series @@ -0,0 +1,11 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_HPMICRO + bool "HPMicro HPM6700_6400 Series" + select RISCV + select SOC_FAMILY_RISCV_PRIVILEGED + select ARCH_HAS_NOCACHE_MEMORY_SUPPORT + select HAS_HPMICRO_HAL + help + Enable support for HPMicro HPM6700_6400 series SoC diff --git a/soc/riscv/riscv-privileged/hpmicro/Kconfig.soc b/soc/riscv/riscv-privileged/hpmicro/Kconfig.soc new file mode 100644 index 000000000000000..34c58ffa16104ca --- /dev/null +++ b/soc/riscv/riscv-privileged/hpmicro/Kconfig.soc @@ -0,0 +1,55 @@ +# Copyright (c) 2022 HPMicro +# SPDX-License-Identifier: Apache-2.0 + +choice +prompt "HPMicro HPM6700_6400 SoC Selection" +depends on SOC_SERIES_HPMICRO + +config SOC_HPM6750 + bool "HPMicro HPM6750 SoC implementation" + select ATOMIC_OPERATIONS_BUILTIN + select INCLUDE_RESET_VECTOR + select RISCV_ISA_RV32I + select RISCV_ISA_EXT_G + select RISCV_ISA_EXT_C + select USE_HPMSDK_PDM + select USE_HPMSDK_PLLCTL + select USE_HPMSDK_PMP + +config SOC_HPM6360 + bool "HPMicro HPM6360 SoC implementation" + select ATOMIC_OPERATIONS_BUILTIN + select INCLUDE_RESET_VECTOR + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_A + select RISCV_ISA_RV32I + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + select USE_HPMSDK_PDM + select USE_HPMSDK_PLLCTLV2 + select USE_HPMSDK_PMP + +endchoice + +if SOC_SERIES_HPMICRO + +choice +prompt "FPU options" +default SOC_HPMICRO_NO_FPU + +config SOC_HPMICRO_NO_FPU + bool "No FPU" + +config SOC_HPMICRO_SINGLE_PRECISION_FPU + bool "Single precision FPU" + select CPU_HAS_FPU + select FPU_SHARING if FPU && MULTITHREADING + +config SOC_HPMICRO_DOUBLE_PRECISION_FPU + bool "Double precision FPU" + select CPU_HAS_FPU_DOUBLE_PRECISION + select FPU_SHARING if FPU && MULTITHREADING + +endchoice + +endif # SOC_SERIES_HPMICRO diff --git a/soc/riscv/riscv-privileged/hpmicro/linker.ld b/soc/riscv/riscv-privileged/hpmicro/linker.ld new file mode 100644 index 000000000000000..d46377f6d0ad27f --- /dev/null +++ b/soc/riscv/riscv-privileged/hpmicro/linker.ld @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +#include +#include + +#define IS_CHOSEN_SRAM(x) (DT_SAME_NODE(x, DT_CHOSEN(zephyr_sram))) + +MEMORY +{ +#ifdef CONFIG_XIP + MCU_XIP (wx) : ORIGIN = DT_REG_ADDR(DT_CHOSEN(zephyr_flash)), LENGTH = 0x3000 +#endif +#if (DT_REG_SIZE(DT_NODELABEL(core0_lm_slv)) > 0) && !IS_CHOSEN_SRAM(core0_lm_slv) + CORE0_LM_SLV (wx) : ORIGIN = DT_REG_ADDR(DT_NODELABEL(core0_lm_slv)), LENGTH = DT_REG_SIZE(DT_NODELABEL(core0_lm_slv)) +#endif +#if (DT_REG_SIZE(DT_NODELABEL(core1_lm_slv)) > 0) && !IS_CHOSEN_SRAM(core1_lm_slv) + CORE1_LM_SLV (wx) : ORIGIN = DT_REG_ADDR(DT_NODELABEL(core1_lm_slv)), LENGTH = DT_REG_SIZE(DT_NODELABEL(core1_lm_slv)) +#endif +#if (DT_REG_SIZE(DT_NODELABEL(sram)) > 0) && !IS_CHOSEN_SRAM(sram) + OCRAM (wx) : ORIGIN = DT_REG_ADDR(DT_NODELABEL(sram)), LENGTH = DT_REG_SIZE(DT_NODELABEL(sram)) +#endif +#if (DT_REG_SIZE(DT_NODELABEL(noncache)) > 0) && !IS_CHOSEN_SRAM(noncache) + NONCACHEABLE (wx) : ORIGIN = DT_REG_ADDR(DT_NODELABEL(noncache)), LENGTH = DT_REG_SIZE(DT_NODELABEL(noncache)) +#endif +#if (DT_REG_SIZE(DT_NODELABEL(dram)) > 0) && !IS_CHOSEN_SRAM(dram) + DRAM (wx) : ORIGIN = DT_REG_ADDR(DT_NODELABEL(dram)), LENGTH = DT_REG_SIZE(DT_NODELABEL(dram)) +#endif +} + +#include +#include diff --git a/soc/riscv/riscv-privileged/hpmicro/pinctrl_soc.h b/soc/riscv/riscv-privileged/hpmicro/pinctrl_soc.h new file mode 100644 index 000000000000000..b64f96d3af88178 --- /dev/null +++ b/soc/riscv/riscv-privileged/hpmicro/pinctrl_soc.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#ifndef ZEPHYR_SOC_RISCV_RISCV_PRIVILEGE_HPMICRO_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_RISCV_RISCV_PRIVILEGE_HPMICRO_PINCTRL_SOC_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +struct pinctrl_soc_pin { + /** Pinmux settings (pin, direction and signal). */ + uint32_t pinmux; + /** Pincfg settings (bias). */ + uint32_t pincfg; +}; + +typedef struct pinctrl_soc_pin pinctrl_soc_pin_t; + +#define Z_PINCTRL_HPMICRO_PINCFG_INIT(node_id) \ + (((HPMICRO_OPEN_DRAIN & DT_PROP(node_id, drive_open_drain)) \ + << HPMICRO_OPEN_DRAIN_SHIFT) | \ + ((HPMICRO_NO_PULL & DT_PROP(node_id, bias_disable)) \ + << HPMICRO_NO_PULL_SHIFT) | \ + ((HPMICRO_PULL_DOWN & DT_PROP(node_id, bias_pull_down)) \ + << HPMICRO_PULL_DOWN_SHIFT) | \ + ((HPMICRO_PULL_UP & DT_PROP(node_id, bias_pull_up)) \ + << HPMICRO_PULL_UP_SHIFT) | \ + ((HPMICRO_FORCE_INPUT & DT_PROP(node_id, input_enable)) \ + << HPMICRO_FORCE_INPUT_SHIFT) | \ + ((HPMICRO_DRIVER_STRENGTH & DT_ENUM_IDX(node_id, drive_strength)) \ + << HPMICRO_DRIVER_STRENGTH_SHIFT) | \ + ((HPMICRO_DRIVER_STRENGTH & DT_ENUM_IDX(node_id, power_source)) \ + << HPMICRO_DRIVER_STRENGTH_SHIFT) | \ + ((HPMICRO_SCHMITT_ENABLE & DT_PROP(node_id, input_schmitt_enable)) \ + << HPMICRO_SCHMITT_ENABLE_SHIFT)) + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + { \ + .pinmux = DT_PROP_BY_IDX(node_id, prop, idx), \ + .pincfg = Z_PINCTRL_HPMICRO_PINCFG_INIT(node_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_RISCV_RISCV_PRIVILEGE_HPMICRO_PINCTRL_SOC_H_ */ diff --git a/soc/riscv/riscv-privileged/hpmicro/sections.ld b/soc/riscv/riscv-privileged/hpmicro/sections.ld new file mode 100644 index 000000000000000..a6588ab4c867d79 --- /dev/null +++ b/soc/riscv/riscv-privileged/hpmicro/sections.ld @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +#include +#include + +#ifdef CONFIG_XIP +__nor_cfg_option_load_addr__ = DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) + 0x400; +__boot_header_load_addr__ = DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) + 0x1000; +__app_load_addr__ = DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) + 0x3000; +__boot_header_length__ = __boot_header_end__ - __boot_header_start__; +__app_offset__ = __app_load_addr__ - __boot_header_load_addr__; +#endif + +SECTIONS +{ +#ifdef CONFIG_XIP + .nor_cfg_option __nor_cfg_option_load_addr__ : { + KEEP(*(.nor_cfg_option)) + } GROUP_LINK_IN(MCU_XIP) + + .boot_header __boot_header_load_addr__ : { + __boot_header_start__ = .; + KEEP(*(.boot_header)) + KEEP(*(.fw_info_table)) + KEEP(*(.dc_info)) + __boot_header_end__ = .; + } GROUP_LINK_IN(MCU_XIP) +#endif + .start : { + . = ALIGN(8); + KEEP(*(.init.*)) + KEEP(*(.start)) + } GROUP_LINK_IN(ROMABLE_REGION) +} diff --git a/soc/riscv/riscv-privileged/hpmicro/soc.c b/soc/riscv/riscv-privileged/hpmicro/soc.c new file mode 100644 index 000000000000000..fd6ebfad087225e --- /dev/null +++ b/soc/riscv/riscv-privileged/hpmicro/soc.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_XIP +#include +#endif + +#ifdef CONFIG_XIP +/** + * @brief FLASH configuration option definitions: + * option[0]: + * [31:16] 0xfcf9 - FLASH configuration option tag + * [15:4] 0 - Reserved + * [3:0] option words (exclude option[0]) + * option[1]: + * [31:28] Flash probe type + * 0 - SFDP SDR / 1 - SFDP DDR + * 2 - 1-4-4 Read (0xEB, 24-bit address) / 3 - 1-2-2 Read(0xBB, 24-bit address) + * 4 - HyperFLASH 1.8V / 5 - HyperFLASH 3V + * 6 - OctaBus DDR (SPI -> OPI DDR) + * 8 - Xccela DDR (SPI -> OPI DDR) + * 10 - EcoXiP DDR (SPI -> OPI DDR) + * [27:24] Command Pads after Power-on Reset + * 0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI + * [23:20] Command Pads after Configuring FLASH + * 0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI + * [19:16] Quad Enable Sequence (for the device support SFDP 1.0 only) + * 0 - Not needed + * 1 - QE bit is at bit 6 in Status Register 1 + * 2 - QE bit is at bit1 in Status Register 2 + * 3 - QE bit is at bit7 in Status Register 2 + * 4 - QE bit is at bit1 in Status Register 2 and should be programmed by 0x31 + * [15:8] Dummy cycles + * 0 - Auto-probed / detected / default value + * Others - User specified value, for DDR read, the dummy cycles should be + * 2 * cycles on FLASH datasheet + * [7:4] Misc. + * 0 - Not used + * 1 - SPI mode + * 2 - Internal loopback + * 3 - External DQS + * [3:0] Frequency option + * 1 - 30MHz / 2 - 50MHz / 3 - 66MHz / 4 - 80MHz / 5 - 100MHz + * / 6 - 120MHz / 7 - 133MHz / 8 - 166MHz + * + * option[2] (Effective only if the bit[3:0] in option[0] > 1) + * [31:20] Reserved + * [19:16] IO voltage + * 0 - 3V / 1 - 1.8V + * [15:12] Pin group + * 0 - 1st group / 1 - 2nd group + * [11:8] Connection selection + * 0 - CA_CS0 / 1 - CB_CS0 / 2 - CA_CS0 + CB_CS0 + * (Two FLASH connected to CA and CB respectively) + * [7:0] Drive Strength + * 0 - Default value + * option[3] (Effective only if the bit[3:0] in option[0] > 2, + * required only for the QSPI NOR FLASH that not supports + * JESD216) + * [31:16] reserved + * [15:12] Sector Erase Command Option, not required here + * [11:8] Sector Size Option, not required here + * [7:0] Flash Size Option + * 0 - 4MB / 1 - 8MB / 2 - 16MB + */ +__attribute__ ((section(".nor_cfg_option"))) const uint32_t option[4] = { + 0xfcf90001, 0x00000007, 0x0, 0x0 + }; +uint32_t __fw_size__[] = {32768}; +#endif +__weak void _init_noncache(void) +{ + extern uint32_t _nocache_ram_start[]; + extern uint32_t _nocache_ram_end[]; + + uint32_t start_addr = (uint32_t) _nocache_ram_start; + uint32_t end_addr = (uint32_t) _nocache_ram_end; + uint32_t length = end_addr - start_addr; + + /* noncacheable bss section */ + for (int i = 0; i < length; i++) { + *(_nocache_ram_start + i) = 0; + } +} + +void soc_init_pmp(void) +{ + extern uint32_t _nocache_ram_start[]; + extern uint32_t _nocache_ram_end[]; + + uint32_t start_addr = (uint32_t) _nocache_ram_start; + uint32_t end_addr = (uint32_t) _nocache_ram_end; + uint32_t length = end_addr - start_addr; + pmp_entry_t pmp_entry[1]; + + if (length == 0) { + return; + } + + /* Ensure the address and the length are power of 2 aligned */ + __ASSERT((length & (length - 1U)) == 0U, + "Length are power of 2 aligned"); + __ASSERT((start_addr & (length - 1U)) == 0U, + "Address are power of 2 aligned"); + + pmp_entry[0].pmp_addr = PMP_NAPOT_ADDR(start_addr, length); + pmp_entry[0].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, + EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK); + pmp_entry[0].pma_addr = PMA_NAPOT_ADDR(start_addr, length); + pmp_entry[0].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN); + + pmp_config(&pmp_entry[0], ARRAY_SIZE(pmp_entry)); +} + +#if defined(CONFIG_NOCACHE_MEMORY) +static int hpmicro_soc_init(void) +{ + uint32_t key; + + key = irq_lock(); + soc_init_pmp(); + irq_unlock(key); + + return 0; +} + +SYS_INIT(hpmicro_soc_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +#endif diff --git a/soc/riscv/riscv-privileged/hpmicro/soc.h b/soc/riscv/riscv-privileged/hpmicro/soc.h new file mode 100644 index 000000000000000..7f11e849b052800 --- /dev/null +++ b/soc/riscv/riscv-privileged/hpmicro/soc.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#ifndef __RISCV_HPMICRO_SOC_H_ +#define __RISCV_HPMICRO_SOC_H_ + +#include + +#endif /* __RISCV_HPMICRO_SOC_H_ */ diff --git a/soc/riscv/riscv-privileged/hpmicro/start.S b/soc/riscv/riscv-privileged/hpmicro/start.S new file mode 100644 index 000000000000000..6073f8e9a1ffdfb --- /dev/null +++ b/soc/riscv/riscv-privileged/hpmicro/start.S @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include +#include "hpm_csr_regs.h" + +GTEXT(_start) + +SECTION_FUNC(init, _start) + /* Disable linker relaxation before GP register initialization. */ + .option push + .option norelax + /* reset mstatus to 0*/ + csrrw x0, mstatus, x0 + +#ifdef __nds_execit + /* Initialize EXEC.IT table */ + la t0, _ITB_BASE_ + csrw uitb, t0 +#endif + +#ifdef __riscv_flen + /* Enable FPU */ + li t0, CSR_MSTATUS_FS_MASK + csrrs t0, mstatus, t0 + + /* Initialize FCSR */ + fscsr zero +#endif +#if defined(CONFIG_NOCACHE_MEMORY) + call _init_noncache +#endif + /* System reset handler */ + call __start + .option pop diff --git a/soc/riscv/riscv-privileged/hpmicro/vectors.S b/soc/riscv/riscv-privileged/hpmicro/vectors.S new file mode 100644 index 000000000000000..6c5dac1e46a6bbb --- /dev/null +++ b/soc/riscv/riscv-privileged/hpmicro/vectors.S @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include +#include +#include + +#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE + +/* Exports */ +GTEXT(__soc_save_context) +GTEXT(__soc_restore_context) + +SECTION_FUNC(exception.other, __soc_save_context) + +#ifdef CONFIG_SOC_ANDES_V5_PFT + csrr t0, NDS_MXSTATUS +#endif +#ifdef CONFIG_SOC_ANDES_V5_HWDSP + csrr t1, NDS_UCODE +#endif + +#ifdef CONFIG_SOC_ANDES_V5_PFT + sw t0, __soc_esf_t_mxstatus_OFFSET(a0) +#endif +#ifdef CONFIG_SOC_ANDES_V5_HWDSP + sw t1, __soc_esf_t_ucode_OFFSET(a0) +#endif + ret + +SECTION_FUNC(exception.other, __soc_restore_context) + +#ifdef CONFIG_SOC_ANDES_V5_PFT + lw t0, __soc_esf_t_mxstatus_OFFSET(a0) +#endif +#ifdef CONFIG_SOC_ANDES_V5_HWDSP + lw t1, __soc_esf_t_ucode_OFFSET(a0) +#endif + +#ifdef CONFIG_SOC_ANDES_V5_PFT + csrw NDS_MXSTATUS, t0 +#endif +#ifdef CONFIG_SOC_ANDES_V5_HWDSP + csrw NDS_UCODE, t1 +#endif + ret + +#endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */ diff --git a/tests/drivers/gpio/gpio_basic_api/boards/hpm6750evkmini.overlay b/tests/drivers/gpio/gpio_basic_api/boards/hpm6750evkmini.overlay new file mode 100644 index 000000000000000..f54839e1e54d9a6 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/hpm6750evkmini.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 HPMicro + * SPDX-License-Identifier: Apache-2.0 + */ + + / { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&gpiob 26 0>; /* P1 pin 32 (PB26) */ + in-gpios = <&gpiob 27 0>; /* P1 pin 29 (PB27) */ + }; +}; + +&pinctrl { + pinmux_gpiob: pinmux_gpiob { + group0 { + pinmux = , + ; + bias-pull-down; + }; + }; +}; + +&gpiob { + pinctrl-0 = <&pinmux_gpiob>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/west.yml b/west.yml index 8866ec48a783949..3e5419ea1eec81e 100644 --- a/west.yml +++ b/west.yml @@ -170,6 +170,11 @@ manifest: path: modules/hal/gigadevice groups: - hal + - name: hal_hpmicro + revision: pull/2/head + path: modules/hal/hpmicro + groups: + - hal - name: hal_infineon revision: 815e84a5150f95627201f192779a0180d5052de7 path: modules/hal/infineon