diff --git a/.gdbinit b/.gdbinit new file mode 100644 index 0000000000000000000000000000000000000000..76b6f237a7b36977092d7d6778426f0b143c14a0 --- /dev/null +++ b/.gdbinit @@ -0,0 +1,42 @@ +# increase the default remote timeout in gdb because +# Windows libusb transactions could be slow +set remotetimeout 100000 + +# gdb connect to openocd in port 3333 +target extended-remote localhost:3333 + +# start openocd working queue, monitor followed with openocd command here +monitor init + +# force to use hardware breakpoint, otherwise use software breakpoint +# for e2000d/q, num of hardware breakpoints supposed to be 6 +monitor gdb_breakpoint_override hardware + +# load elf image +load ./build/zephyr/zephyr.elf + +# in case symbols skip load,load agin +file ./build/zephyr/zephyr.elf + +# we can break at the beginning of code by address or by symbol +#break _boot + +# add more breakpoints in application +#break JtagTouchRegisters +#break JtagTouchMemory +# break bubbleSort +# break JtagPostSort +#break bubbleSortCXX + +# show all breakspoints we before running +# info breakpoints + +# show [-0x10 ~ +0x10 ] range of instructions when breaked +# display /10i $pc-16 + +# start running +# continue + +layout split + +si diff --git a/.gitlint_qemu b/.gitlint_qemu new file mode 100644 index 0000000000000000000000000000000000000000..c4e4cf7f036ec0c9883ea13d8febb47316a1d7f4 --- /dev/null +++ b/.gitlint_qemu @@ -0,0 +1,39 @@ +# increase the default remote timeout in gdb because +# Windows libusb transactions could be slow +set remotetimeout 100000 + +# gdb connect to openocd in port 3333 +target extended-remote localhost:1234 + +# start openocd working queue, monitor followed with openocd command here +# monitor init + +# force to use hardware breakpoint, otherwise use software breakpoint +# for e2000d/q, num of hardware breakpoints supposed to be 6 +# monitor gdb_breakpoint_override hardware + +# load elf image +# load ./build/zephyr/zephyr.elf + +# in case symbols skip load,load agin +file ./build/zephyr/zephyr.elf + +# we can break at the beginning of code by address or by symbol +#break _boot + +# add more breakpoints in application +#break JtagTouchRegisters +#break JtagTouchMemory +# break bubbleSort +# break JtagPostSort +#break bubbleSortCXX + +# show all breakspoints we before running +# info breakpoints + +# show [-0x10 ~ +0x10 ] range of instructions when breaked +# display /10i $pc-16 + +# start running +# continue +si diff --git a/arch/arm/core/Kconfig b/arch/arm/core/Kconfig index a06b4cb5e9570cdd8d04dcd97c90da136405891b..711703ddceb42c90782817d770e1884b8f79ab43 100644 --- a/arch/arm/core/Kconfig +++ b/arch/arm/core/Kconfig @@ -59,6 +59,11 @@ config CPU_AARCH32_CORTEX_A help This option signifies the use of a CPU of the Cortex-A family. +config CPU_AARCH32_ARMV8 + bool + help + This option signifies the use of a CPU of the Armv8 family. + config ISA_THUMB2 bool help diff --git a/arch/arm/core/cortex_a_r/Kconfig b/arch/arm/core/cortex_a_r/Kconfig index 10bf721a87006ab5214a20e53f7a8cc7ca0419da..52565b5d50beac975b36be12e239ec36f4d91ed3 100644 --- a/arch/arm/core/cortex_a_r/Kconfig +++ b/arch/arm/core/cortex_a_r/Kconfig @@ -13,6 +13,24 @@ # CPU_AARCH32_CORTEX_A / if CPU_AARCH32_CORTEX_R blocks so they are not # exposed if one selects a different ARM Cortex Family (Cortex-M). +config CPU_PHYTIUM_FT310 + bool + select CPU_AARCH32_CORTEX_A + select CPU_AARCH32_ARMV8 + select CPU_HAS_ICACHE + select CPU_HAS_DCACHE + select ARMV7_A + help + This option signifies the use of a FT310 CPU. + +if CPU_PHYTIUM_FT310 + config AARCH64_2_AARCH32 + bool + help + Example Convert aarch64 to aarch32 + +endif + config CPU_CORTEX_A9 bool select CPU_AARCH32_CORTEX_A diff --git a/arch/arm/core/cortex_a_r/reset.S b/arch/arm/core/cortex_a_r/reset.S index c72f0814c7ab6fb6f9a02ea55360a3359082ea1b..0a13e58c6672fe73ef69463e09622ed4740ea627 100644 --- a/arch/arm/core/cortex_a_r/reset.S +++ b/arch/arm/core/cortex_a_r/reset.S @@ -32,6 +32,87 @@ GDATA(z_arm_undef_stack) GTEXT(z_arm_platform_init) #endif +SECTION_SUBSEC_FUNC(TEXT, _reset_section, __start) +#if defined(CONFIG_AARCH64_2_AARCH32) +aarch64_2_aarch32: + .long 0xd5384240 /* mrs x0, currentel */ + .long 0xd342fc00 /* lsr x0, x0, #2 */ + .long 0x92400400 /* and x0, x0, #0x3 */ + .long 0xf1000c1f /* cmp x0, #0x3 */ + .long 0x540003a1 /* b.ne 1d0080c4 */ + +el3_mode: + .long 0xd53ecca0 /* mrs x0, s3_6_c12_c12_5 - ICC_SRE_EL3 */ + .long 0xb2400c00 /* orr x0, x0, #0xf */ + .long 0xd51ecca0 /* msr s3_6_c12_c12_5, x0 */ + .long 0xd5033fdf /* isb */ + .long 0xd53cc9a0 /* mrs x0, s3_4_c12_c9_5 - ICC_SRE_EL2 */ + .long 0xb2400c00 /* orr x0, x0, #0xf */ + .long 0xd51cc9a0 /* msr s3_4_c12_c9_5, x0 */ + .long 0xd5033fdf /* isb */ + .long 0xd538cca0 /* mrs x0, s3_0_c12_c12_5 - ICC_SRE_EL1 */ + .long 0xb2400000 /* orr x0, x0, #0x1 */ + .long 0xd518cca0 /* msr s3_0_c12_c12_5, x0 */ + .long 0xd5033fdf /* isb */ + + .long 0xd2803620 /* mov x0, #0x1b1 */ + .long 0xd51e1100 /* msr scr_el3, x0 */ + .long 0xd2867fe0 /* mov x0, #0x33ff */ + .long 0xd51c1140 /* msr cptr_el2, x0 */ + .long 0xd2810000 /* mov x0, #0x800 */ + .long 0xf2a61a00 /* movk x0, #0x30d0, lsl #16 */ + .long 0xd5181000 /* msr sctlr_el1, x0 */ + .long 0x910003e0 /* mov x0, sp */ + .long 0xd51c4100 /* msr sp_el1, x0 */ + .long 0xd53ec000 /* mrs x0, vbar_el3 */ + .long 0xd518c000 /* msr vbar_el1, x0 */ + .long 0xd2803a60 /* mov x0, #0x1d3 */ + .long 0xd51e4000 /* msr spsr_el3, x0 */ + .long 0x10000500 /* adr x0, 1d008158 */ + .long 0xd51e4020 /* msr elr_el3, x0 */ + .long 0xd69f03e0 /* eret */ + +el2_mode: + .long 0xd53cc9a0 /* mrs x0, s3_4_c12_c9_5 - ICC_SRE_EL2 */ + .long 0xb2400c00 /* orr x0, x0, #0xf */ + .long 0xd51cc9a0 /* msr s3_4_c12_c9_5, x0 */ + .long 0xd5033fdf /* isb */ + .long 0xd538cca0 /* mrs x0, s3_0_c12_c12_5 - ICC_SRE_EL1 */ + .long 0xb2400000 /* orr x0, x0, #0x1 */ + .long 0xd518cca0 /* msr s3_0_c12_c12_5, x0 */ + .long 0xd5033fdf /* isb */ + .long 0xd53ce100 /* mrs x0, cnthctl_el2 */ + .long 0xb2400400 /* orr x0, x0, #0x3 */ + .long 0xd51ce100 /* msr cnthctl_el2, x0 */ + .long 0xd51ce07f /* msr cntvoff_el2, xzr */ + .long 0xd5380000 /* mrs x0, midr_el1 */ + .long 0xd53800a1 /* mrs x1, mpidr_el1 */ + .long 0xd51c0000 /* msr vpidr_el2, x0 */ + .long 0xd51c00a1 /* msr vmpidr_el2, x1 */ + .long 0xd2867fe0 /* mov x0, #0x33ff */ + .long 0xd51c1140 /* msr cptr_el2, x0 */ + .long 0xd51c117f /* msr hstr_el2, xzr */ + .long 0xd2a00600 /* mov x0, #0x300000 */ + .long 0xd5181040 /* msr cpacr_el1, x0 */ + .long 0xd2800000 /* mov x0, #0x0 */ + .long 0xb2630000 /* orr x0, x0, #0x20000000 */ + .long 0xd51c1100 /* msr hcr_el2, x0 */ + .long 0xd53c1100 /* mrs x0, hcr_el2 */ + .long 0xd2810000 /* mov x0, #0x800 */ + .long 0xf2a61a00 /* movk x0, #0x30d0, lsl #16 */ + .long 0xd5181000 /* msr sctlr_el1, x0 */ + .long 0x910003e0 /* mov x0, sp */ + .long 0xd51c4100 /* msr sp_el1, x0 */ + .long 0xd53cc000 /* mrs x0, vbar_el2 */ + .long 0xd518c000 /* msr vbar_el1, x0 */ + .long 0xd2803a60 /* mov x0, #0x1d3 */ + .long 0xd51c4000 /* msr spsr_el2, x0 */ + .long 0x10000060 /* adr x0, 1d008158 */ + .long 0xd51c4020 /* msr elr_el2, x0 */ + .long 0xd69f03e0 /* eret */ +el1_mode: + b z_arm_reset +#endif /** * * @brief Reset vector @@ -45,8 +126,10 @@ GTEXT(z_arm_platform_init) * */ SECTION_SUBSEC_FUNC(TEXT, _reset_section, z_arm_reset) -SECTION_SUBSEC_FUNC(TEXT, _reset_section, __start) + + #if defined(CONFIG_AARCH32_ARMV8_R) + /* Check if we are starting in HYP mode */ mrs r0, cpsr and r0, r0, #MODE_MASK diff --git a/arch/arm/core/mmu/arm_mmu.c b/arch/arm/core/mmu/arm_mmu.c index 5281d265cd0efb98f140195b81638560bbfcc3d2..b69f251ca23d31c9d1c1789bda0e9ea0aa01146c 100644 --- a/arch/arm/core/mmu/arm_mmu.c +++ b/arch/arm/core/mmu/arm_mmu.c @@ -34,6 +34,10 @@ #include #include "arm_mmu_priv.h" +#ifdef CONFIG_DCACHE +#include +#endif + LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); /* Level 1 page table: always required, must be 16k-aligned */ @@ -73,7 +77,7 @@ static const struct arm_mmu_flat_range mmu_zephyr_ranges[] = { .start = (uint32_t)_image_ram_start, .end = (uint32_t)_image_ram_end, .attrs = MT_NORMAL | MATTR_SHARED | - MPERM_R | MPERM_W | + MPERM_R | MPERM_W |MPERM_X | MATTR_CACHE_OUTER_WB_WA | MATTR_CACHE_INNER_WB_WA}, /* Mark text segment cacheable, read only and executable */ @@ -848,7 +852,9 @@ int z_arm_mmu_init(void) reg_val |= ARM_MMU_SCTLR_DCACHE_ENABLE_BIT; reg_val |= ARM_MMU_SCTLR_MMU_ENABLE_BIT; __set_SCTLR(reg_val); - +#ifdef CONFIG_DCACHE + arch_dcache_invd_all() ; +#endif return 0; } diff --git a/arch/arm/core/vector_table.ld b/arch/arm/core/vector_table.ld index 615067dbf7483fac592ea1c64cd56109698c3af5..ada784d28d305610ac775fb586d4ecd1166fb06c 100644 --- a/arch/arm/core/vector_table.ld +++ b/arch/arm/core/vector_table.ld @@ -47,10 +47,15 @@ . = ALIGN( 0x80 ); #endif +aarch64_2_aarch32 = .; +KEEP(*(.aarch64_2_aarch32_section)) +KEEP(*(".aarch64_2_aarch32_section.*")) + +. = ALIGN( 0x80 ); _vector_start = .; KEEP(*(.exc_vector_table)) KEEP(*(".exc_vector_table.*")) - +. = ALIGN( 0x80 ); KEEP(*(.vectors)) _vector_end = .; diff --git a/arch/arm64/core/Kconfig b/arch/arm64/core/Kconfig index fd74a5264161a12624f3431d2fbfd2ffeed2c3fa..dc2133fd8181f3fc7f1278cf62001199e4bb34a6 100644 --- a/arch/arm64/core/Kconfig +++ b/arch/arm64/core/Kconfig @@ -30,6 +30,20 @@ config CPU_AARCH64_CORTEX_R help This option signifies the use of a CPU of the Cortex-R 64-bit family. +config CPU_PHYTIUM_FTC310 + bool + select CPU_CORTEX_A + select ARMV8_A + help + This option signifies the use of a Phytium-FTC310 CPU + +config CPU_PHYTIUM_FTC664 + bool + select CPU_CORTEX_A + select ARMV8_A + help + This option signifies the use of a Phytium-FTC664 CPU + config CPU_CORTEX_A53 bool select CPU_CORTEX_A diff --git a/arch/arm64/core/mmu.c b/arch/arm64/core/mmu.c index 7d5670da0f238fe464f8be235e5d8ad144c17243..0af7886d1d412be08d6dd524ec3f7a4cc8810b05 100644 --- a/arch/arm64/core/mmu.c +++ b/arch/arm64/core/mmu.c @@ -839,7 +839,7 @@ static void enable_mmu_el1(struct arm_mmu_ptables *ptables, unsigned int flags) /* Enable the MMU and data cache */ val = read_sctlr_el1(); write_sctlr_el1(val | SCTLR_M_BIT | SCTLR_C_BIT); - + /* Ensure the MMU enable takes effect immediately */ barrier_isync_fence_full(); diff --git a/arch/arm64/core/reset.S b/arch/arm64/core/reset.S index 9b3b4462e851abf1c8d5c471a1523bff1e51f14f..1f8015f31bf43f0d5009f437fd3da5b092ccfc3a 100644 --- a/arch/arm64/core/reset.S +++ b/arch/arm64/core/reset.S @@ -124,15 +124,23 @@ resetwait: ldr x0, =arm64_cpu_boot_params get_cpu_id x1 - /* + /* * If the cores start up at the same time, we should atomically load and * store the mpid into arm64_cpu_boot_params. */ - ldaxr x2, [x0, #BOOT_PARAM_MPID_OFFSET] +try_store: + //ldaxr x2, [x0, #BOOT_PARAM_MPID_OFFSET] + ldr x2, [x0, #BOOT_PARAM_MPID_OFFSET] cmp x2, #-1 bne 1f + + /* try to store x1 (mpid) */ - stlxr w3, x1, [x0] + //stlxr w3, x1, [x0] + str x1 ,[x0] + mov w3 , 0 + //cbnz w3,try_store + /* If succeed, go to primary_core */ cbz w3, primary_core @@ -196,8 +204,13 @@ switch_el: mov_imm x0, (SPSR_DAIF_MASK | SPSR_MODE_EL1T) msr spsr_el2, x0 + bl InvalidateFlushDcaches + dsb sy + isb + adr x0, 1f msr elr_el2, x0 + eret 1: @@ -212,3 +225,81 @@ switch_el: isb ret x25 /* either z_arm64_prep_c or z_arm64_secondary_prep_c */ + + +/* flush or invalidate dcache, refer to rt-thread __asm_flush_dcache_all */ +InvalidateFlushDcacheLevel: + lsl x12, x0, #1 + msr csselr_el1, x12 /* select cache level */ + isb /* sync change of cssidr_el1 */ + mrs x6, ccsidr_el1 /* read the new cssidr_el1 */ + and x2, x6, #7 /* x2 <- log2(cache line size)-4 */ + add x2, x2, #4 /* x2 <- log2(cache line size) */ + mov x3, #0x3ff + and x3, x3, x6, lsr #3 /* x3 <- max number of #ways, ccsidr_el1[12:3] */ + clz w5, w3 /* bit position of #ways */ + mov x4, #0x7fff + and x4, x4, x6, lsr #13 /* x4 <- max number of #sets, ccsidr_el1[27:13] */ + /* x12 <- cache level << 1 */ + /* x2 <- line length offset */ + /* x3 <- number of cache ways - 1 */ + /* x4 <- number of cache sets - 1 */ + /* x5 <- bit position of #ways */ + +InvalidateFlushCacheSet: + mov x6, x3 /* x6 <- working copy of #ways */ + +InvalidateFlushCacheWay: + lsl x7, x6, x5 /* x7 = x6 << x5 */ + orr x9, x12, x7 /* x9 = x12 | x7, map way and level to cisw value */ + lsl x7, x4, x2 + orr x9, x9, x7 /* map set number to cisw value */ + tbz w1, #0, 1f /* x1 = 0f, flush cache */ + dc isw, x9 /* invalidate dcache */ + b 2f +1: dc cisw, x9 /* clean & invalidate by set/way */ +2: subs x6, x6, #1 /* decrement the way */ + b.ge InvalidateFlushCacheWay + subs x4, x4, #1 /* decrement the set */ + b.ge InvalidateFlushCacheSet + + ret + +.global InvalidateFlushDcaches +InvalidateFlushDcaches: + mov x1, x0 /* x1 = 0 flush, x1 = 1 invalidate */ + dsb sy /* barrier for full system */ + mrs x10, clidr_el1 /* read clidr_el1 */ + lsr x11, x10, #24 + and x11, x11, #0x7 /* x11 <- loc bit[26:24], level of cache hierarchy */ + cbz x11, InvalidateFlushDcacheEnd /* if loc is 0, no cache, exit */ + mov x15, lr /* preserve LR */ + mov x0, #0 /* start flush at cache level 0 */ + /* x0 <- cache level */ + /* x10 <- clidr_el1 */ + /* x11 <- loc */ + /* x15 <- return address */ + +InvalidateFlushCachesLoopLevel: + lsl x12, x0, #1 /* x12 = x0 * 2 */ + add x12, x12, x0 /* x0 <- tripled cache level */ + lsr x12, x10, x12 /* get x10, clidr_el1[ctype-n] to x12 */ + and x12, x12, #7 /* x12 <- cache type */ + cmp x12, #2 /* if not 000(no-cache), 001(i-cache only) */ + b.lt InvalidateFlushCachesSkipLevel /* skip if no cache or icache */ + bl InvalidateFlushDcacheLevel /* x1 = 0 flush, 1 invalidate */ + +InvalidateFlushCachesSkipLevel: + add x0, x0, #1 /* increment cache level */ + cmp x11, x0 + b.gt InvalidateFlushCachesLoopLevel + + mov x0, #0 + msr csselr_el1, x0 /* restore csselr_el1 */ + dsb sy + isb + mov lr, x15 + +InvalidateFlushDcacheEnd: + ret + diff --git a/boards/arm/e2000q_a32_demo/Kconfig.board b/boards/arm/e2000q_a32_demo/Kconfig.board new file mode 100644 index 0000000000000000000000000000000000000000..8c1809da637263552a3199bffadd0758acbbed83 --- /dev/null +++ b/boards/arm/e2000q_a32_demo/Kconfig.board @@ -0,0 +1,18 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +config BOARD_E2000Q_A32_DEMO + bool "e2000q a32 demo" + depends on SOC_PHYTIUM_E2000Q diff --git a/boards/arm/e2000q_a32_demo/Kconfig.defconfig b/boards/arm/e2000q_a32_demo/Kconfig.defconfig new file mode 100644 index 0000000000000000000000000000000000000000..3593adb0aae179b90c93a590df012e864376a23d --- /dev/null +++ b/boards/arm/e2000q_a32_demo/Kconfig.defconfig @@ -0,0 +1,30 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +if BOARD_E2000Q_A32_DEMO + +config BOARD + default "e2000q_a32_demo" + +if NETWORKING + +config NET_L2_ETHERNET + default y + + + +endif # NETWORKING + +endif # BOARD_E2000Q_A32_DEMO diff --git a/boards/arm/e2000q_a32_demo/board.cmake b/boards/arm/e2000q_a32_demo/board.cmake new file mode 100644 index 0000000000000000000000000000000000000000..7d63903e3bde223e21d1c15bd3f4f829f0c61b1a --- /dev/null +++ b/boards/arm/e2000q_a32_demo/board.cmake @@ -0,0 +1,14 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. diff --git a/boards/arm/e2000q_a32_demo/e2000q_a32_demo.dts b/boards/arm/e2000q_a32_demo/e2000q_a32_demo.dts new file mode 100644 index 0000000000000000000000000000000000000000..3f33384c364983bf552f45a085879aeb6b8811c3 --- /dev/null +++ b/boards/arm/e2000q_a32_demo/e2000q_a32_demo.dts @@ -0,0 +1,52 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +// +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/license/apache-2-0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +/dts-v1/; +#include +#include + +/ { + model = "E2000Q DEMO board"; + compatible = "phytium,e2000q"; + + #address-cells = <1>; + #size-cells = <1>; + + + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + }; + +}; + +&uart1 { + status = "okay"; + current-speed = <115200>; +}; + +&xmac0 { + status = "okay"; + local-mac-address = [00 00 00 01 02 03]; +}; + +&sdhc1 { + status = "okay"; + sdmmc { + compatible = "zephyr,sdmmc-disk"; + status = "okay"; + }; +}; \ No newline at end of file diff --git a/boards/arm/e2000q_a32_demo/e2000q_a32_demo_defconfig b/boards/arm/e2000q_a32_demo/e2000q_a32_demo_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..965e1bbe22b3ca703241745fe4a63296eda6a8fd --- /dev/null +++ b/boards/arm/e2000q_a32_demo/e2000q_a32_demo_defconfig @@ -0,0 +1,37 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + + +CONFIG_SOC_SERIES_PHYTIUM_E2000Q=y +CONFIG_SOC_PHYTIUM_E2000Q=y +CONFIG_BOARD_E2000Q_A32_DEMO=y + + +# The GTC is always clocked at 1/2 of the CPU frequency (CPU_3x2x) +CONFIG_ARM_ARCH_TIMER=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=50000000 + +#CONFIG_PINCTRL=y +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + + +CONFIG_ARM_MMU_NUM_L2_TABLES=1024 + + +CONFIG_ARMV7_SYS_STACK_SIZE=8192 +# Main stack size +CONFIG_MAIN_STACK_SIZE=8192 diff --git a/boards/arm/e2000q_a32_demo/e2000q_a32_demo_smp.dts b/boards/arm/e2000q_a32_demo/e2000q_a32_demo_smp.dts new file mode 100644 index 0000000000000000000000000000000000000000..b09e550d0c13fd211ea64ead622547692fafe22e --- /dev/null +++ b/boards/arm/e2000q_a32_demo/e2000q_a32_demo_smp.dts @@ -0,0 +1,39 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +/dts-v1/; +#include +#include + +/ { + model = "E2000Q DEMO board"; + compatible = "phytium,e2000q"; + + #address-cells = <1>; + #size-cells = <1>; + + + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + }; + +}; + +&uart1 { + status = "okay"; + current-speed = <115200>; +}; diff --git a/boards/arm/e2000q_a32_demo/e2000q_a32_demo_smp_defconfig b/boards/arm/e2000q_a32_demo/e2000q_a32_demo_smp_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..8fed5ade501e81f24098f53da60b595184d15d4d --- /dev/null +++ b/boards/arm/e2000q_a32_demo/e2000q_a32_demo_smp_defconfig @@ -0,0 +1,49 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +CONFIG_SOC_SERIES_PHYTIUM_E2000Q=y +CONFIG_SOC_PHYTIUM_E2000Q=y +CONFIG_BOARD_E2000Q_A32_DEMO=y + + +# The GTC is always clocked at 1/2 of the CPU frequency (CPU_3x2x) +CONFIG_ARM_ARCH_TIMER=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=50000000 + +#CONFIG_PINCTRL=y +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + + +CONFIG_ARM_MMU_NUM_L2_TABLES=1024 + + +CONFIG_ARMV7_SYS_STACK_SIZE=8192 +# Main stack size +CONFIG_MAIN_STACK_SIZE=8192 + +# Timer Drivers +CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME=y + +# PSCI is supported with NS +CONFIG_PM_CPU_OPS=y +CONFIG_PM_CPU_OPS_PSCI=y + +# SMP-related +CONFIG_SMP=y +CONFIG_MP_MAX_NUM_CPUS=2 +CONFIG_TIMEOUT_64BIT=y + diff --git a/boards/arm64/e2000q_demo/CMakeLists.txt b/boards/arm64/e2000q_demo/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..9881313609aae2c16a19dae665af4268bd54431d --- /dev/null +++ b/boards/arm64/e2000q_demo/CMakeLists.txt @@ -0,0 +1 @@ +# SPDX-License-Identifier: Apache-2.0 diff --git a/boards/arm64/e2000q_demo/Kconfig.board b/boards/arm64/e2000q_demo/Kconfig.board new file mode 100644 index 0000000000000000000000000000000000000000..023628c6e97354327ac961ec9a08cc8d0847e027 --- /dev/null +++ b/boards/arm64/e2000q_demo/Kconfig.board @@ -0,0 +1,18 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +config BOARD_E2000Q_DEMO + bool "phytium e2000q" + depends on SOC_E2000Q diff --git a/boards/arm64/e2000q_demo/Kconfig.defconfig b/boards/arm64/e2000q_demo/Kconfig.defconfig new file mode 100644 index 0000000000000000000000000000000000000000..bf74ea79982f6e3ed4f99e1d24e1d1b87131120e --- /dev/null +++ b/boards/arm64/e2000q_demo/Kconfig.defconfig @@ -0,0 +1,30 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + + +config BOARD + default "Phytium e2000q demo" + depends on BOARD_E2000Q_DEMO + + + +if NETWORKING + +config NET_L2_ETHERNET + default y + + + +endif # NETWORKING diff --git a/boards/arm64/e2000q_demo/board.cmake b/boards/arm64/e2000q_demo/board.cmake new file mode 100644 index 0000000000000000000000000000000000000000..9881313609aae2c16a19dae665af4268bd54431d --- /dev/null +++ b/boards/arm64/e2000q_demo/board.cmake @@ -0,0 +1 @@ +# SPDX-License-Identifier: Apache-2.0 diff --git a/boards/arm64/e2000q_demo/e2000q_demo.dts b/boards/arm64/e2000q_demo/e2000q_demo.dts new file mode 100644 index 0000000000000000000000000000000000000000..41eab11647af506f65c29221deb490e1b22ca296 --- /dev/null +++ b/boards/arm64/e2000q_demo/e2000q_demo.dts @@ -0,0 +1,54 @@ +/* + * Copyright 2023 honglin leng + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "e2000q_pinctrl.dtsi" + +/ { + model = "Phytium e2000q demo"; + compatible = "phytium,e2000q-demo", "phytium,e2000q"; + #address-cells = <2>; + #size-cells = <2>; + +chosen { + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + zephyr,sram = &sram0; + zephyr,pcie-controller = &pcie0; + }; +}; + +&sdhc1 { + status = "okay"; + sdmmc { + compatible = "zephyr,sdmmc-disk"; + status = "okay"; + }; +}; + +&xmac0 { + status = "okay"; + local-mac-address = [00 00 00 01 02 03]; +}; + +&uart1 { + current-speed = <115200>; + pinctrl-0 = <&uart1_rx_default &uart1_tx_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&uart2 { + current-speed = <115200>; + pinctrl-0 = <&uart2_rx_default &uart2_tx_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&pcie0 { + status = "okay"; +}; diff --git a/boards/arm64/e2000q_demo/e2000q_demo.yaml b/boards/arm64/e2000q_demo/e2000q_demo.yaml new file mode 100644 index 0000000000000000000000000000000000000000..115d5cdfd5656c5983901579c1fc93b817aa5851 --- /dev/null +++ b/boards/arm64/e2000q_demo/e2000q_demo.yaml @@ -0,0 +1,7 @@ +identifier: e2000q_demo +name: Phytium e2000q demo +type: mcu +arch: arm64 +toolchain: + - zephyr + - cross-compile diff --git a/boards/arm64/e2000q_demo/e2000q_demo_defconfig b/boards/arm64/e2000q_demo/e2000q_demo_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..640e01de1c188cb04da8b4ba1e2d013edeaa4b3e --- /dev/null +++ b/boards/arm64/e2000q_demo/e2000q_demo_defconfig @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Platform Configuration +CONFIG_SOC_E2000Q=y +CONFIG_BOARD_E2000Q_DEMO=y +CONFIG_ARM64_VA_BITS_42=y +CONFIG_ARM64_PA_BITS_42=y +# Main stack size +CONFIG_MAIN_STACK_SIZE=4096 + +CONFIG_ARMV8_A_NS=y + +# Zephyr Kernel Configuration +CONFIG_XIP=n +CONFIG_FLASH_SIZE=0 +CONFIG_FLASH_BASE_ADDRESS=0x0 + +# Serial Drivers +CONFIG_SERIAL=y + +# Enable Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + + +# Timer Drivers +CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME=y + + +#cache +CONFIG_CACHE_MANAGEMENT=y + +# PSCI is supported with NS +CONFIG_PM_CPU_OPS=y +CONFIG_PM_CPU_OPS_PSCI=y diff --git a/boards/arm64/e2000q_demo/e2000q_demo_smp.dts b/boards/arm64/e2000q_demo/e2000q_demo_smp.dts new file mode 100644 index 0000000000000000000000000000000000000000..e61f75fe266a43d7f54cb68a24dd0002a16e468b --- /dev/null +++ b/boards/arm64/e2000q_demo/e2000q_demo_smp.dts @@ -0,0 +1,49 @@ +/* + * Copyright 2023 honglin leng + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +/ { + model = "Phytium e2000q demo"; + compatible = "phytium,e2000q-demo", "phytium,e2000q"; + #address-cells = <2>; + #size-cells = <2>; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + +chosen { + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + zephyr,sram = &sram0; + }; +}; + +&sdhc1 { + status = "okay"; + sdmmc { + compatible = "zephyr,sdmmc-disk"; + status = "okay"; + }; +}; + +&uart1 { + status = "okay"; + current-speed = <115200>; +}; + +&uart2 { + status = "okay"; + current-speed = <115200>; +}; + +&xmac0 { + status = "okay"; + local-mac-address = [00 00 00 01 02 03]; +}; diff --git a/boards/arm64/e2000q_demo/e2000q_demo_smp.yaml b/boards/arm64/e2000q_demo/e2000q_demo_smp.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c3562a9b4c418a83a0dd4174121bc628bb12561f --- /dev/null +++ b/boards/arm64/e2000q_demo/e2000q_demo_smp.yaml @@ -0,0 +1,9 @@ +identifier: e2000q_demo +name: Phytium e2000q demo +type: mcu +arch: arm64 +toolchain: + - zephyr + - cross-compile +supported: + - smp \ No newline at end of file diff --git a/boards/arm64/e2000q_demo/e2000q_demo_smp_defconfig b/boards/arm64/e2000q_demo/e2000q_demo_smp_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..97bd10b01091dfaf67ffc2ea30b0df8848eb2af2 --- /dev/null +++ b/boards/arm64/e2000q_demo/e2000q_demo_smp_defconfig @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Platform Configuration +CONFIG_SOC_E2000Q=y +CONFIG_BOARD_E2000Q_DEMO=y +CONFIG_ARM64_VA_BITS_42=y +CONFIG_ARM64_PA_BITS_42=y +# Main stack size +CONFIG_MAIN_STACK_SIZE=4096 + +CONFIG_ARMV8_A_NS=y + +# Zephyr Kernel Configuration +CONFIG_XIP=n +CONFIG_FLASH_SIZE=0 +CONFIG_FLASH_BASE_ADDRESS=0x0 + +# Serial Drivers +CONFIG_SERIAL=y + +# Enable Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +#cache +CONFIG_CACHE_MANAGEMENT=y + +# Timer Drivers +CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME=y + +# PSCI is supported with NS +CONFIG_PM_CPU_OPS=y +CONFIG_PM_CPU_OPS_PSCI=y + +# SMP-related +CONFIG_SMP=y +CONFIG_MP_MAX_NUM_CPUS=4 +CONFIG_TIMEOUT_64BIT=y + +# CONFIG_SHELL=y +# CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN=n +# CONFIG_SHELL_BACKEND_SERIAL_RX_POLL_PERIOD=1 +# CONFIG_BOOT_BANNER=n diff --git a/boards/arm64/e2000q_demo/e2000q_pinctrl.dtsi b/boards/arm64/e2000q_demo/e2000q_pinctrl.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..7267e3b10c68630d4db478b629c8377b8455b60b --- /dev/null +++ b/boards/arm64/e2000q_demo/e2000q_pinctrl.dtsi @@ -0,0 +1,19 @@ + + +#include + +&pinctrl { + uart1_rx_default: uart1_rx_default { + pinmux = ; + }; + uart1_tx_default: uart1_tx_default { + pinmux = ; + }; + + uart2_rx_default: uart2_rx_default { + pinmux = ; + }; + uart2_tx_default: uart2_tx_default { + pinmux = ; + }; +}; \ No newline at end of file diff --git a/cmake/gcc-m-cpu.cmake b/cmake/gcc-m-cpu.cmake index ae10132dfc04c0b1351a27079915d1ae07558e51..ba6e73eefac3b8fcbdc475748dbe966dda1a0295 100644 --- a/cmake/gcc-m-cpu.cmake +++ b/cmake/gcc-m-cpu.cmake @@ -67,6 +67,8 @@ if("${ARCH}" STREQUAL "arm") endif() elseif(CONFIG_CPU_CORTEX_A9) set(GCC_M_CPU cortex-a9) + elseif(CONFIG_CPU_PHYTIUM_FT310) + set(GCC_M_CPU cortex-a9) else() message(FATAL_ERROR "Expected CONFIG_CPU_CORTEX_x to be defined") endif() diff --git a/cmake/gcc-m-fpu.cmake b/cmake/gcc-m-fpu.cmake index 0e231b2ae3b7b42387fe65c66f2e6573d269627a..3d660adaaacebc777632b9af4b4efbdeb079e366 100644 --- a/cmake/gcc-m-fpu.cmake +++ b/cmake/gcc-m-fpu.cmake @@ -23,6 +23,12 @@ if("${ARCH}" STREQUAL "arm") set(GCC_M_FPU fpv5-sp-d16) endif() endif() + elseif(CONFIG_CPU_CORTEX_A9) + if(CONFIG_VFP_FEATURE_DOUBLE_PRECISION) + set(GCC_M_FPU neon-fp-armv8) + elseif(CONFIG_VFP_FEATURE_SINGLE_PRECISION) + set(GCC_M_FPU fpv5-sp-d16) + endif() elseif(CONFIG_CPU_CORTEX_M) # Defines a mapping from GCC_M_CPU to FPU if(CONFIG_CPU_HAS_FPU_DOUBLE_PRECISION) @@ -41,6 +47,12 @@ if("${ARCH}" STREQUAL "arm") set(FPU_FOR_cortex-m55+nodsp auto) set(GCC_M_FPU ${FPU_FOR_${GCC_M_CPU}}) + else() + if(CONFIG_VFP_FEATURE_DOUBLE_PRECISION) + set(GCC_M_FPU neon-fp-armv8) + elseif(CONFIG_VFP_FEATURE_SINGLE_PRECISION) + set(GCC_M_FPU fpv5-sp-d16) + endif() endif() endif() diff --git a/drivers/ethernet/CMakeLists.txt b/drivers/ethernet/CMakeLists.txt index 6f963cd68d0fb02b31c2f51ce62c2af7d623e25e..28480629f2756da830c39a4f3f3f93a5dca09275 100644 --- a/drivers/ethernet/CMakeLists.txt +++ b/drivers/ethernet/CMakeLists.txt @@ -34,6 +34,7 @@ zephyr_library_sources_ifdef(CONFIG_SLIP_TAP eth_slip_tap.c) zephyr_library_sources_ifdef(CONFIG_ETH_SMSC91X eth_smsc91x.c) zephyr_library_sources_ifdef(CONFIG_ETH_IVSHMEM eth_ivshmem.c eth_ivshmem_queue.c) zephyr_library_sources_ifdef(CONFIG_ETH_ADIN2111 eth_adin2111.c) +zephyr_library_sources_ifdef(CONFIG_ETH_PHYTIUM_XMAC eth_phytium_xmac.c) if(CONFIG_ETH_NXP_S32_NETC) zephyr_library_sources(eth_nxp_s32_netc.c) diff --git a/drivers/ethernet/Kconfig b/drivers/ethernet/Kconfig index 8160fc74358be43e4f6766df60d939c9b76a1fb7..8bf7e7425589c403554b64f7a1759b4d8903e698 100644 --- a/drivers/ethernet/Kconfig +++ b/drivers/ethernet/Kconfig @@ -61,6 +61,7 @@ source "drivers/ethernet/Kconfig.nxp_s32_gmac" source "drivers/ethernet/Kconfig.smsc91x" source "drivers/ethernet/Kconfig.ivshmem" source "drivers/ethernet/Kconfig.adin2111" +source "drivers/ethernet/Kconfig.phytium_xmac" source "drivers/ethernet/phy/Kconfig" diff --git a/drivers/ethernet/Kconfig.phytium_xmac b/drivers/ethernet/Kconfig.phytium_xmac new file mode 100644 index 0000000000000000000000000000000000000000..e9d527492105e9d6b7c86271a9a62f19cc299ad9 --- /dev/null +++ b/drivers/ethernet/Kconfig.phytium_xmac @@ -0,0 +1,22 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +menuconfig ETH_PHYTIUM_XMAC + bool "Phytium ETH_PHYTIUM_XMAC Ethernet driver" + default y + depends on DT_HAS_PHYTIUM_XMAC_ENABLED + help + Enable Phytium XMAC Ethernet driver. + diff --git a/drivers/ethernet/eth_phytium_xmac.c b/drivers/ethernet/eth_phytium_xmac.c new file mode 100644 index 0000000000000000000000000000000000000000..dc6c3cdd68e1885f80afe53a6591022cc246b2c3 --- /dev/null +++ b/drivers/ethernet/eth_phytium_xmac.c @@ -0,0 +1,1466 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +// +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/license/apache-2-0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + + +#include "fxmac.h" +#include "fxmac_hw.h" +#include "fxmac_bdring.h" +#include "eth_ieee_reg.h" +#include "eth_phytium_xmac.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + + +#define LOG_MODULE_NAME phytium_xmac +#define LOG_LEVEL CONFIG_ETHERNET_LOG_LEVEL +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +#define DT_DRV_COMPAT phytium_xmac + + +/* dma buffer */ +#define ETH_PHYTIUM_BDL_ALIGNMENT 256 +#define ETH_PHYTIUM_BUFFER_ALIGNMENT ETH_PHYTIUM_BDL_ALIGNMENT +#define ETH_ALIGNMENT_OFFSET_DEFINED(buffer_size) ((buffer_size\ + + (ETH_PHYTIUM_BUFFER_ALIGNMENT - 1))\ + & ~(ETH_PHYTIUM_BUFFER_ALIGNMENT - 1)) + + +/* IRQ handler function type */ +typedef void (*eth_phytiium_xmac_config_irq_t)(const struct device *dev); + +typedef enum +{ + FXMAC_LWIP_PORT_INTERFACE_SGMII = 0, + FXMAC_LWIP_PORT_INTERFACE_RMII, + FXMAC_LWIP_PORT_INTERFACE_RGMII, + FXMAC_LWIP_PORT_INTERFACE_USXGMII, + FXMAC_LWIP_PORT_INTERFACE_LENGTH +} FXmacLwipPortInterface; + + +#define FXMAC_PHY_SPEED_10M 10 +#define FXMAC_PHY_SPEED_100M 100 +#define FXMAC_PHY_SPEED_1000M 1000 +#define FXMAC_PHY_SPEED_10G 10000 + + +/* phy link */ +enum eth_phytium_link_speed { + /* The values of this enum are consecutively numbered */ + LINK_DOWN = 0, + LINK_10MBIT, + LINK_100MBIT, + LINK_1GBIT +}; + +#define FXMAC_BD_TO_INDEX(ringptr, bdptr) \ + (((uintptr)bdptr - (uintptr)(ringptr)->base_bd_addr) / (ringptr)->separation) + +struct eth_phytium_xmac_dev_cfg { + DEVICE_MMIO_ROM; + uint32_t instance_id ; /* */ + eth_phytiium_xmac_config_irq_t config_func; + uint32_t pll_clock_frequency; + + uint32_t phy_poll_interval; + uint8_t defer_rxp_to_queue; + uint8_t defer_txd_to_queue; + + uint8_t rxbd_count; /* rx bdl count */ + uint8_t txbd_count; /* tx bdl count */ + uint16_t rx_buffer_size; /* per buffer size */ + uint16_t tx_buffer_size; + + /* dtc defined */ + uint32_t phy_speed ; /* FXMAC_PHY_SPEED_XX */ + uint32_t interface_mode ; /* followed by FXmacLwipPortInterface */ + uint32_t dma_brust_length ; + uint32_t max_queue_num; /* Number of Xmac Controller Queues */ + bool phy_autonegotiation : 1 ; + bool enable_fdx : 1 ; + bool enable_jumbo : 1; + bool enable_ucast_hash :1; + bool copy_all_frames :1; + bool disable_reject_fcs_crc_errors:1; + bool enable_mcast_hash :1; + +}; + + +struct eth_phytium_xmac_dev_data { + DEVICE_MMIO_RAM; /* used for controller base address */ + struct net_if *iface; + FXmac instance ; + uint8_t mac_addr[6]; + enum eth_phytium_link_speed eff_link_speed ; + struct k_work tx_done_work; + struct k_work rx_pend_work; + struct k_sem tx_done_sem; + + struct k_sem ring_sem; + + uint8_t phy_addr; + uint32_t phy_id; + struct k_work_delayable phy_poll_delayed_work; + +#ifdef CONFIG_NET_STATISTICS_ETHERNET + struct net_stats_eth stats; +#endif + + uint8_t *rx_bdspace ; + uint8_t *rx_bdspace_virt ; + uint8_t *tx_bdspace ; + uint8_t *tx_bdspace_virt ; + + uint8_t *first_rx_buffer ; + uint8_t *first_rx_buffer_virt ; + uint8_t *first_tx_buffer ; + uint8_t *first_tx_buffer_virt ; + + bool started; +}; + + +static int eth_phytium_xmac_dev_init(const struct device *dev) ; +static void eth_phytium_xmac_iface_init(struct net_if *iface) ; +static enum ethernet_hw_caps eth_phytium_xmac_get_capabilities(const struct device *dev) ; +static int eth_phytium_xmac_send(const struct device *dev, struct net_pkt *pkt) ; +static int eth_phytium_xmac_start_device(const struct device *dev) ; +static int eth_phytium_xmac_stop_device(const struct device *dev) ; +#ifdef CONFIG_NET_STATISTICS_ETHERNET +static struct net_stats_eth *eth_phytium_xmac_stats(const struct device *dev) ; +#endif + +static void eth_phytium_xmac_isr(const struct device *dev) ; + +static const struct ethernet_api eth_phytium_xmac_apis = { + .iface_api.init = eth_phytium_xmac_iface_init, + .get_capabilities = eth_phytium_xmac_get_capabilities, + .send = eth_phytium_xmac_send, + .start = eth_phytium_xmac_start_device, + .stop = eth_phytium_xmac_stop_device, +#if defined(CONFIG_NET_STATISTICS_ETHERNET) + .get_stats = eth_phytium_xmac_stats, +#endif +}; + + +/* + * Insert the configuration & run-time data for all GEM instances which + * are enabled in the device tree of the current target board. + */ +DT_INST_FOREACH_STATUS_OKAY(ETH_PHYTIUM_XMAC_INITIALIZE) + + +static void FXmacSetupIsr(const struct device *dev) ; + +static uint32_t phy_autoneg_status(FXmac *xmac_p, uint32_t phy_addr) +{ + u16 status; + + /* Read Phy Status register twice to get the confirmation of the current + * link status. + */ + FXmacPhyRead(xmac_p, phy_addr, PHY_STATUS_REG_OFFSET, &status); + + if (status & PHY_STATUS_AUTONEGOTIATE_COMPLETE) + return 1; + return 0; +} + +/** + * @name: phy_link_detect + * @msg: Get current link status + * @note: + * @param {FXmac} *fxmac_p + * @param {u32} phy_addr + * @return {*} 1 is link up , 0 is link down + */ +static u32 phy_link_detect(FXmac *xmac_p, u32 phy_addr) +{ + u16 status; + + /* Read Phy Status register twice to get the confirmation of the current + * link status. + */ + + FXmacPhyRead(xmac_p, phy_addr, PHY_STATUS_REG_OFFSET, &status); + + if (status & PHY_STAT_LINK_STATUS) + return 1; + return 0; +} + +FXmacLinkStatus FXmacRgmiiLinkDetect(const struct device *dev) +{ + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data ; + FXmac *instance_p; + instance_p = &dev_data->instance; + + u32 phy_link_status; + + + phy_link_status = phy_link_detect(instance_p, instance_p->phy_address); + + if ((instance_p->link_status == FXMAC_LINKUP) && (!phy_link_status)) + instance_p->link_status = FXMAC_LINKDOWN; + + switch (instance_p->link_status) + { + case FXMAC_LINKUP: + return FXMAC_LINKUP; + case FXMAC_LINKDOWN: + instance_p->link_status = FXMAC_NEGOTIATING; + LOG_DBG("Ethernet Link down"); + return FXMAC_LINKDOWN; + case FXMAC_NEGOTIATING: + if ((phy_link_status == FXMAC_LINKUP) && phy_autoneg_status(instance_p, instance_p->phy_address)) + { + if(FXmacPhyInit(instance_p, instance_p->config.speed, instance_p->config.duplex, instance_p->config.auto_neg,XMAC_PHY_RESET_DISABLE)) + { + return FXMAC_LINKDOWN; + } + + FXmacSelectClk(instance_p); + FXmacInitInterface(instance_p); + + /* Initiate Phy setup to get link speed */ + instance_p->link_status = FXMAC_LINKUP; + LOG_DBG("Ethernet Link up"); + return FXMAC_LINKUP; + } + return FXMAC_LINKDOWN; + default: + return FXMAC_LINKDOWN; + } +} + +FXmacLinkStatus FXmacSgmiiLinkDetect(const struct device *dev) +{ + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data ; + FXmac *instance_p; + u32 ctrl; + u32 link, link_status; + instance_p = &dev_data->instance; + + ctrl = FXMAC_READREG32(instance_p->config.base_address, FXMAC_PCS_AN_LP_OFFSET); + link = (ctrl & FXMAC_PCS_LINK_PARTNER_NEXT_PAGE_STATUS) >> FXMAC_PCS_LINK_PARTNER_NEXT_PAGE_OFFSET; + + switch (link) + { + case 0: + link_status = FXMAC_LINKDOWN; + break; + case 1: + link_status = FXMAC_LINKUP; + break; + default: + LOG_ERR("link status is error 0x%x \r\n", link); + return FXMAC_LINKDOWN; + } + + if (link_status == FXMAC_LINKUP) + { + if (link_status != instance_p->link_status) + { + instance_p->link_status = FXMAC_NEGOTIATING; + LOG_INF("need NEGOTIATING"); + } + } + else + { + instance_p->link_status = FXMAC_LINKDOWN; + } + + if (instance_p->link_status == FXMAC_NEGOTIATING) + { + /* renegotiate */ + if (FXmacPhyInit(instance_p, instance_p->config.speed, instance_p->config.duplex, instance_p->config.auto_neg,XMAC_PHY_RESET_DISABLE)) + { + LOG_ERR("FXmacPhyInit is error \r\n"); + return FXMAC_LINKDOWN; + } + else + { + FXmacSelectClk(instance_p); + FXmacInitInterface(instance_p); + instance_p->link_status = FXMAC_LINKUP; + return FXMAC_LINKUP; + } + } + return instance_p->link_status ; +} + +static void eth_phytium_xmac_poll_phy(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct eth_phytium_xmac_dev_data *dev_data = CONTAINER_OF(dwork, + struct eth_phytium_xmac_dev_data, phy_poll_delayed_work); + const struct device *dev = net_if_get_device(dev_data->iface); + const struct eth_phytium_xmac_dev_cfg *dev_conf = dev->config; + FXmacLinkStatus link_status = FXMAC_LINKDOWN ; + FXmac *instance_p; + instance_p = &dev_data->instance; + + if(instance_p->config.interface == FXMAC_PHY_INTERFACE_MODE_SGMII) + { + link_status = FXmacSgmiiLinkDetect(dev) ; + } + else if((instance_p->config.interface == FXMAC_PHY_INTERFACE_MODE_RMII) || (instance_p->config.interface == FXMAC_PHY_INTERFACE_MODE_RGMII)) + { + link_status = FXmacRgmiiLinkDetect(dev) ; + } + + if(link_status == FXMAC_LINKDOWN) + { + dev_data->eff_link_speed = LINK_DOWN; + net_eth_carrier_off(dev_data->iface); + + LOG_WRN("%s link down", dev->name); + } + else if(link_status == FXMAC_LINKUP) + { + switch(instance_p->config.speed) + { + case FXMAC_SPEED_10: + dev_data->eff_link_speed = LINK_10MBIT ; + break ; + case FXMAC_SPEED_100: + dev_data->eff_link_speed = LINK_100MBIT ; + break ; + case FXMAC_SPEED_1000: + dev_data->eff_link_speed = LINK_1GBIT ; + break ; + } + net_eth_carrier_on(dev_data->iface); + } + + k_work_reschedule(&dev_data->phy_poll_delayed_work, + K_MSEC(dev_conf->phy_poll_interval)); + +} + +/** + * @name: eth_phytium_xmac_get_capabilities + * @msg: Reports the hardware capabilities of the Ethernet device, such as supported speeds and duplex modes. + * @param {const struct device} *dev is a pointer to the device structure for the driver instance. + * @return {enum ethernet_hw_caps} A bitmask of supported features defined in `enum ethernet_hw_caps`. + */ +static enum ethernet_hw_caps eth_phytium_xmac_get_capabilities(const struct device *dev) +{ + struct eth_phytium_xmac_dev_cfg *dev_cfg = (struct eth_phytium_xmac_dev_cfg *)dev->config ; + enum ethernet_hw_caps caps = (enum ethernet_hw_caps)0; + + switch (dev_cfg->phy_speed) + { + case FXMAC_PHY_SPEED_10M: + caps |= ETHERNET_LINK_10BASE_T; + break; + case FXMAC_PHY_SPEED_100M: + caps |= (ETHERNET_LINK_100BASE_T | + ETHERNET_LINK_10BASE_T); + break; + case FXMAC_PHY_SPEED_1000M: + caps |= (ETHERNET_LINK_1000BASE_T | + ETHERNET_LINK_100BASE_T | + ETHERNET_LINK_10BASE_T); + break; + case FXMAC_PHY_SPEED_10G: + caps |= (ETHERNET_LINK_1000BASE_T | + ETHERNET_LINK_100BASE_T | + ETHERNET_LINK_10BASE_T); + break; + } + + if (dev_cfg->enable_fdx) { + caps |= ETHERNET_DUPLEX_SET; + } + + if (dev_cfg->copy_all_frames) { + caps |= ETHERNET_PROMISC_MODE; + } + return caps; +} + +static int eth_phytium_xmac_config_convert(struct eth_phytium_xmac_dev_cfg *dev_conf,FXmacConfig *mac_config,uint32_t *options) +{ + *options = 0 ; + switch (dev_conf->interface_mode) + { + case FXMAC_LWIP_PORT_INTERFACE_SGMII: + mac_config->interface = FXMAC_PHY_INTERFACE_MODE_SGMII; + LOG_INF("SGMII select"); + break; + case FXMAC_LWIP_PORT_INTERFACE_RMII: + mac_config->interface = FXMAC_PHY_INTERFACE_MODE_RMII; + LOG_INF("RMII select"); + break; + case FXMAC_LWIP_PORT_INTERFACE_RGMII: + LOG_INF("RGMII select"); + mac_config->interface = FXMAC_PHY_INTERFACE_MODE_RGMII; + break; + case FXMAC_LWIP_PORT_INTERFACE_USXGMII: + LOG_INF("USXGMII select"); + mac_config->interface = FXMAC_PHY_INTERFACE_MODE_USXGMII; + break; + default: + return -EINVAL; + } + + switch (dev_conf->phy_speed) + { + case FXMAC_PHY_SPEED_10M: + mac_config->speed = FXMAC_SPEED_10; + break; + case FXMAC_PHY_SPEED_100M: + mac_config->speed = FXMAC_SPEED_100; + break; + case FXMAC_PHY_SPEED_1000M: + mac_config->speed = FXMAC_SPEED_1000; + break; + case FXMAC_PHY_SPEED_10G: + LOG_INF("select FXMAC_PHY_SPEED_10G"); + mac_config->speed = FXMAC_SPEED_10000; + break; + default: + return -EINVAL; + } + + mac_config->duplex = dev_conf->enable_fdx? 1:0 ; /* 1 is full-duplex , 0 is half-duplex */ + mac_config->auto_neg = dev_conf->phy_autonegotiation ; /* Enable auto-negotiation - when set active high, + autonegotiation operation is enabled. */ + mac_config->pclk_hz = dev_conf->pll_clock_frequency ; + mac_config->max_queue_num = dev_conf->max_queue_num ; /* Number of Xmac Controller Queues */ + mac_config->tx_queue_id = 0 ; /* 0 ~ FXMAC_QUEUE_MAX_NUM ,Index queue number */ + mac_config->rx_queue_id = 0 ; /* 0 ~ FXMAC_QUEUE_MAX_NUM ,Index queue number */ + mac_config->dma_brust_length = dev_conf->dma_brust_length ; /* burst length */ + mac_config->network_default_config = FXMAC_DEFAULT_OPTIONS ; + mac_config->caps = 0 ; /* used to configure tail ptr feature */ + + /* options */ + if(dev_conf->enable_jumbo) + { + *options |= FXMAC_JUMBO_ENABLE_OPTION ; + } + + if(dev_conf->enable_ucast_hash) + { + *options |= FXMAC_UNICAST_OPTION; + } + + if(dev_conf->enable_mcast_hash) + { + *options |= FXMAC_MULTICAST_OPTION; + } + + if(dev_conf->copy_all_frames) + { + *options |= FXMAC_PROMISC_OPTION; + } + + if(dev_conf->disable_reject_fcs_crc_errors) + { + *options |= FXMAC_FCS_STRIP_OPTION; + } + + + return 0 ; +} + +/* irq init */ +static int eth_phytium_xmac_setuphandler(const struct device *dev) +{ + + struct eth_phytium_xmac_dev_cfg *dev_conf = (struct eth_phytium_xmac_dev_cfg *)dev->config ; + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data ; + FXmac *instance_p; + + FXmacBd bdtemplate; + FXmacBdRing *rxringptr, *txringptr; + FXmacBd *rxbd; + int i; + u32 bdindex; + u32 *temp; + instance_p = &dev_data->instance; + /* init buffer to data */ + /* Initial configuration of the RX/TX BD rings */ + DT_INST_FOREACH_STATUS_OKAY(ETH_PHYTIUM_XMAC_INIT_BD_RING) + rxringptr = &FXMAC_GET_RXRING((*instance_p)); + txringptr = &FXMAC_GET_TXRING((*instance_p)); + + /* Setup RxBD space. */ + FXMAC_BD_CLEAR(&bdtemplate); + + /* Create the RxBD ring */ + if(FXmacBdRingCreate(rxringptr, (uintptr)dev_data->rx_bdspace, + (uintptr)dev_data->rx_bdspace, + ETH_PHYTIUM_BDL_ALIGNMENT, + dev_conf->rxbd_count)) + { + LOG_ERR("Error setting up RxBD space\r\n"); + return -EIO ; + } + + if(FXmacBdRingClone(rxringptr, &bdtemplate, FXMAC_RECV)) + { + LOG_ERR("Error initializing RxBD space\r\n"); + return -EIO; + } + + FXMAC_BD_CLEAR(&bdtemplate); + FXMAC_BD_SET_STATUS(&bdtemplate, FXMAC_TXBUF_USED_MASK); + + + /* Create the TxBD ring */ + if (FXmacBdRingCreate(txringptr, (uintptr)dev_data->tx_bdspace, + (uintptr)dev_data->tx_bdspace, ETH_PHYTIUM_BDL_ALIGNMENT, + dev_conf->txbd_count)) + { + return -EIO; + } + + /* We reuse the bd template, as the same one will work for both rx and tx. */ + if(FXmacBdRingClone(txringptr, &bdtemplate, FXMAC_SEND)) + { + return -EIO; + } + + /* init rx buffer */ + for (i = 0; i < dev_conf->rxbd_count; i++) + { + if(FXmacBdRingAlloc(rxringptr, 1, &rxbd)) + { + LOG_ERR("InitDma: Error allocating RxBD\r\n"); + return -ERANGE; + } + + /* Enqueue to HW */ + if(FXmacBdRingToHw(rxringptr, 1, rxbd)) + { + LOG_ERR("Error: committing RxBD to HW\r\n"); + FXmacBdRingUnAlloc(rxringptr, 1, rxbd); + return -ERANGE; + } + + bdindex = FXMAC_BD_TO_INDEX(rxringptr, rxbd); + temp = (u32 *)rxbd; + *temp = 0; + if (bdindex == (dev_conf->rxbd_count - 1)) + { + *temp = 0x00000002; /* Marks last descriptor in receive buffer descriptor list */ + } + temp++; + *temp = 0; /* Clear word 1 in descriptor */ + + FXMAC_BD_SET_ADDRESS_RX(rxbd, (uintptr)(dev_data->first_rx_buffer_virt + ETH_ALIGNMENT_OFFSET_DEFINED(dev_conf->rx_buffer_size)*bdindex)); + + } + FXmacSetQueuePtr(instance_p, instance_p->tx_bd_queue.bdring.phys_base_addr, 0, (u16)FXMAC_SEND); + FXmacSetQueuePtr(instance_p, instance_p->rx_bd_queue.bdring.phys_base_addr, 0, (u16)FXMAC_RECV); + + return 0; +} + + + +static void eth_phytium_xmac_handle_tx_done(const struct device *dev) +{ + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data ; + struct eth_phytium_xmac_dev_cfg *dev_conf = (struct eth_phytium_xmac_dev_cfg *)dev->config ; + FXmac *instance_p; + FXmacBd *txbdset; + FXmacBd *curbdpntr; + u32 n_bds; + FError status; + u32 n_pbufs_freed = 0; + u32 bdindex; + u32 *temp; + instance_p = &dev_data->instance ; + FXmacBdRing *txring; + + if (dev_conf->defer_txd_to_queue) { + k_sem_take(&(dev_data->ring_sem), K_FOREVER); + } + txring = &(FXMAC_GET_TXRING((*instance_p))); + while (1) + { + /* obtain processed BD's */ + n_bds = FXmacBdRingFromHwTx(txring, dev_conf->txbd_count, &txbdset); + if (n_bds == 0) + { + break; + } + /* free the processed BD's */ + n_pbufs_freed = n_bds; + curbdpntr = txbdset; + while (n_pbufs_freed > 0) + { + bdindex = FXMAC_BD_TO_INDEX(txring, curbdpntr); + temp = (u32 *)curbdpntr; + *temp = 0; /* Word 0 */ + temp++; + + if (bdindex == (dev_conf->txbd_count - 1)) + { + *temp = 0xC0000000; /* Word 1 ,used/Wrap – marks last descriptor in transmit buffer descriptor list.*/ + } + else + { + *temp = 0x80000000; /* Word 1 , Used – must be zero for GEM to read data to the transmit buffer.*/ + } + + curbdpntr = FXMAC_BD_RING_NEXT(txring, curbdpntr); + n_pbufs_freed--; + + } + + status = FXmacBdRingFree(txring, n_bds, txbdset); + if (status != FT_SUCCESS) + { + LOG_ERR("Failure while freeing in Tx Done ISR\r\n"); + } + } + + if (dev_conf->defer_txd_to_queue) { + k_sem_give(&(dev_data->ring_sem)); + } + + /* Re-enable the TX complete interrupt source */ + FXMAC_WRITEREG32(instance_p->config.base_address,FXMAC_IER_OFFSET,FXMAC_IXR_TXCOMPL_MASK) ; + + /* Indicate completion to a blocking eth_xlnx_gem_send() call */ + k_sem_give(&dev_data->tx_done_sem); +} + +static void eth_phytium_xmac_tx_done_work(struct k_work *item) +{ + struct eth_phytium_xmac_dev_data *dev_data = CONTAINER_OF(item, struct eth_phytium_xmac_dev_data, tx_done_work); + const struct device *dev = net_if_get_device(dev_data->iface); + + eth_phytium_xmac_handle_tx_done(dev); +} + +/** + * @name: eth_phytium_xmac_send + * @msg: Sends an Ethernet frame. The frame is contained in a packet that is managed by the networking stack. + * @param {const struct device} *dev is a pointer to the device structure for the driver instance. + * @param {struct net_pkt} *pkt is a pointer to the network packet that contains the data to be sent. + * @return {int} Zero on success or negative error code on failure. + */ +static int eth_phytium_xmac_send(const struct device *dev, struct net_pkt *pkt) +{ + struct eth_phytium_xmac_dev_cfg *dev_conf = (struct eth_phytium_xmac_dev_cfg *)dev->config ; + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data ; + FXmac *instance_p; + + FXmacBd *txbdset, *txbd, *last_txbd = NULL; + FXmacBdRing *txring; + u32 bdindex; + + uint16_t tx_data_length; + uint16_t tx_data_remaining; + void *tx_buffer_offs; + uint32_t bds_reqd; + uint32_t tx_length = 0 ; + instance_p = &dev_data->instance; + txring = &FXMAC_GET_TXRING((*instance_p)); + + if (!dev_data->started || dev_data->eff_link_speed == LINK_DOWN || + (!net_if_flag_is_set(dev_data->iface, NET_IF_UP))) { +#ifdef CONFIG_NET_STATISTICS_ETHERNET + dev_data->stats.tx_dropped++; +#endif + return -EIO; + } + + tx_data_length = tx_data_remaining = net_pkt_get_len(pkt); + if (tx_data_length == 0) { + LOG_ERR("%s cannot TX, zero packet length", dev->name); +#ifdef CONFIG_NET_STATISTICS_ETHERNET + dev_data->stats.errors.tx++; +#endif + return -EINVAL; + } + + bds_reqd = (uint8_t)((tx_data_length + (dev_conf->tx_buffer_size - 1)) / + dev_conf->tx_buffer_size); + + if (dev_conf->defer_txd_to_queue) { + k_sem_take(&(dev_data->ring_sem), K_FOREVER); + } else { + FXMAC_WRITEREG32(instance_p->config.base_address,FXMAC_IDR_OFFSET,FXMAC_IXR_TXCOMPL_MASK) ; + } + + /* obtain as many BD's */ + if(FXmacBdRingAlloc(txring, bds_reqd, &txbdset)) + { + LOG_ERR("sgsend: Error allocating TxBD\r\n"); +#ifdef CONFIG_NET_STATISTICS_ETHERNET + dev_data->stats.tx_dropped++; +#endif + FXMAC_WRITEREG32(instance_p->config.base_address,FXMAC_IER_OFFSET,FXMAC_IXR_TXCOMPL_MASK) ; + return ERR_GENERAL; + } + + if (dev_conf->defer_txd_to_queue) { + k_sem_give(&(dev_data->ring_sem)); + } else { + FXMAC_WRITEREG32(instance_p->config.base_address,FXMAC_IER_OFFSET,FXMAC_IXR_TXCOMPL_MASK) ; + } + + /* + * Scatter the contents of the network packet's buffer to + * one or more DMA buffers. + */ + net_pkt_cursor_init(pkt); + txbd = txbdset ; + while (tx_data_remaining) + { + bdindex = FXMAC_BD_TO_INDEX(txring, txbd); + + /* Calculate the base pointer of the target TX buffer */ + tx_buffer_offs = (void *)(dev_data->first_tx_buffer + + (ETH_ALIGNMENT_OFFSET_DEFINED(dev_conf->tx_buffer_size) * bdindex)); + + /* Copy packet data to DMA buffer */ + tx_length = (tx_data_remaining < dev_conf->tx_buffer_size) ? + tx_data_remaining : dev_conf->tx_buffer_size ; + net_pkt_read(pkt, (void *)tx_buffer_offs,tx_length); + + FXMAC_BD_SET_ADDRESS_TX(txbd, (uintptr)tx_buffer_offs); + + FXMAC_BD_SET_LENGTH(txbd, tx_length & 0x3FFF); + + last_txbd = txbd; + FXMAC_BD_CLEAR_LAST(txbd); + txbd = FXMAC_BD_RING_NEXT(txring, txbd); + tx_data_remaining -= (tx_data_remaining < dev_conf->tx_buffer_size) ? + tx_data_remaining : dev_conf->tx_buffer_size; + } + FXMAC_BD_SET_LAST(last_txbd); + FXMAC_BD_CLEAR_TX_USED(last_txbd); + + if(FXmacBdRingToHw(txring, bds_reqd, txbdset)) + { + LOG_ERR("sgsend: Error submitting TxBD\r\n"); + } + + /* Start transmit */ + FXMAC_WRITEREG32(instance_p->config.base_address, + FXMAC_NWCTRL_OFFSET, + (FXMAC_READREG32(instance_p->config.base_address, + FXMAC_NWCTRL_OFFSET) | + FXMAC_NWCTRL_STARTTX_MASK)); + +#ifdef CONFIG_NET_STATISTICS_ETHERNET + dev_data->stats.bytes.sent += tx_data_length; + dev_data->stats.pkts.tx++; +#endif + + return 0 ; +} + +static void eth_phytium_xmac_setup_rx_bds(const struct device *dev,FXmacBdRing *rxring) +{ + const struct eth_phytium_xmac_dev_cfg *dev_conf = dev->config; + struct eth_phytium_xmac_dev_data *dev_data = dev->data; + FXmacBd *rxbd; + FError status; + u32 freebds; + u32 bdindex; + u32 *temp; + FXmac *instance_p; + instance_p = &dev_data->instance ; + + freebds = FXMAC_BD_RING_GET_FREE_CNT(rxring); + while (freebds > 0) + { + freebds --; + status = FXmacBdRingAlloc(rxring, 1, &rxbd); + if (status != FT_SUCCESS) + { + LOG_ERR("SetupRxBds: Error allocating RxBD\r\n"); + return; + } + status = FXmacBdRingToHw(rxring, 1, rxbd); + if (status != FT_SUCCESS) + { + LOG_ERR("Error committing RxBD to hardware: "); + if (status == FXMAC_ERR_SG_LIST) + { + LOG_ERR("XST_DMA_SG_LIST_ERROR: this function was called out of sequence with FXmacBdRingAlloc()\r\n"); + } + else + { + LOG_ERR("set of BDs was rejected because the first BD did not have its start-of-packet bit set, or the last BD did not have its end-of-packet bit set, or any one of the BD set has 0 as length value\r\n"); + } + + FXmacBdRingUnAlloc(rxring, 1, rxbd); + return; + } + + + bdindex = FXMAC_BD_TO_INDEX(rxring, rxbd); + temp = (u32 *)rxbd; + if (bdindex == (dev_conf->rxbd_count - 1)) + { + *temp = 0x00000002; /* Mask last descriptor in receive buffer list */ + } + else + { + *temp = 0; + } + temp++; + *temp = 0; + + FXMAC_BD_SET_ADDRESS_RX(rxbd, (uintptr)(dev_data->first_rx_buffer_virt + ETH_ALIGNMENT_OFFSET_DEFINED(dev_conf->rx_buffer_size)*bdindex)); + + } +} + +static void eth_phytium_xmac_handle_rx_pending(const struct device *dev) +{ + const struct eth_phytium_xmac_dev_cfg *dev_conf = dev->config; + struct eth_phytium_xmac_dev_data *dev_data = dev->data; + FXmacBd *rxbdset, *curbdptr; + FXmacBdRing *rxring; + volatile u32 bd_processed; + u32 k; + u32 bdindex; + FXmac *instance_p; + struct net_pkt *pkt; + uint32_t rx_data_length; + instance_p = &dev_data->instance ; + rxring = &FXMAC_GET_RXRING((*instance_p)); + + /* Re-enable the frame received interrupt source */ + FXMAC_WRITEREG32(instance_p->config.base_address,FXMAC_IER_OFFSET,FXMAC_IXR_RXCOMPL_MASK); + + while (1) + { + bd_processed = FXmacBdRingFromHwRx(rxring, dev_conf->rxbd_count, &rxbdset); + if (bd_processed <= 0) + { + break; + } + + for (k = 0, curbdptr = rxbdset; k < bd_processed; k++) + { + bdindex = FXMAC_BD_TO_INDEX(rxring, curbdptr); + rx_data_length = FXMAC_BD_GET_LENGTH(curbdptr); + if(rx_data_length > dev_conf->rx_buffer_size) + { + LOG_ERR("rx_data_length length is error: %u bytes \r\n", + rx_data_length); + goto error_exit ; + } + + pkt = net_pkt_rx_alloc_with_buffer(dev_data->iface, rx_data_length, + AF_UNSPEC, 0, K_FOREVER); + if (pkt == NULL) + { + LOG_ERR("RX packet buffer alloc failed: %u bytes", + rx_data_length); +#ifdef CONFIG_NET_STATISTICS_ETHERNET + dev_data->stats.errors.rx++; + dev_data->stats.error_details.rx_no_buffer_count++; +#endif + /* free up the BD's */ + goto error_exit ; + } + + net_pkt_write(pkt, (const void *) + (dev_data->first_rx_buffer_virt + ETH_ALIGNMENT_OFFSET_DEFINED(dev_conf->rx_buffer_size)*bdindex), + rx_data_length); + + if (net_recv_data(dev_data->iface, pkt) < 0) { + printf("%s RX packet hand-over to IP stack failed", dev->name); + net_pkt_unref(pkt); + } +#ifdef CONFIG_NET_STATISTICS_ETHERNET + else { + dev_data->stats.bytes.received += rx_data_length; + dev_data->stats.pkts.rx++; + } +#endif + curbdptr = FXMAC_BD_RING_NEXT(rxring, curbdptr); + } + FXmacBdRingFree(rxring, bd_processed, rxbdset); + eth_phytium_xmac_setup_rx_bds(dev,rxring) ; + } + + return; + +error_exit: + printf("eth_phytium_xmac_handle_rx_pending error exit \r\n") ; + FXmacBdRingFree(rxring, bd_processed, rxbdset); +} + +static void eth_phytium_xmac_rx_pending_work(struct k_work *item) +{ + struct eth_phytium_xmac_dev_data *dev_data = CONTAINER_OF(item, + struct eth_phytium_xmac_dev_data, rx_pend_work); + const struct device *dev = net_if_get_device(dev_data->iface); + + eth_phytium_xmac_handle_rx_pending(dev); +} + + +static void FXmacSendHandler(void *arg) +{ + const struct device *dev = (const struct device *)arg; + struct eth_phytium_xmac_dev_data *dev_data = dev->data; + const struct eth_phytium_xmac_dev_cfg *dev_conf = dev->config; + FXmac *instance_p; + instance_p = &dev_data->instance; + + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_IDR_OFFSET,FXMAC_IXR_TXCOMPL_MASK); + if (dev_conf->defer_txd_to_queue) + { + k_work_submit(&dev_data->tx_done_work); + } + else + { + eth_phytium_xmac_handle_tx_done(dev); + } +} + +static void FXmacRecvHandler(void *arg) +{ + const struct device *dev = (const struct device *)arg ; + struct eth_phytium_xmac_dev_data *dev_data = dev->data; + const struct eth_phytium_xmac_dev_cfg *dev_conf = dev->config; + FXmac *instance_p; + instance_p = &dev_data->instance ; + + FXMAC_WRITEREG32(instance_p->config.base_address,FXMAC_IDR_OFFSET,FXMAC_IXR_RXCOMPL_MASK) ; + + if (dev_conf->defer_rxp_to_queue) + { + k_work_submit(&dev_data->rx_pend_work); + } + else + { + printk("recv data \r\n") ; + eth_phytium_xmac_handle_rx_pending(dev); + printk("recv data exit \r\n") ; + } +} + +/* interrupt */ +static void FXmacHandleDmaTxError( const struct device *dev) +{ + u32 dmacrreg; + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data; + FXmac *instance_p; + instance_p = &dev_data->instance ; + /* initialize the mac */ + if (FXmacCfgInitialize(instance_p, &instance_p->config)) + { + LOG_ERR("In %s:EmacPs Configuration Failed....\r\n", __func__); + } + + /* set mac address */ + FXmacSetMacAddress(instance_p, (void *)(dev_data->mac_addr), 0) ; + + dmacrreg = FXMAC_READREG32(instance_p->config.base_address, FXMAC_DMACR_OFFSET); + dmacrreg = dmacrreg | (FXMAC_DMACR_ORCE_DISCARD_ON_ERR_MASK); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_DMACR_OFFSET, dmacrreg); + /* setup dma bdl */ + eth_phytium_xmac_setuphandler(dev) ; + FXmacSetupIsr(dev); + + FXmacStart(instance_p); +} + +static void eth_phytium_xmac_tx_dma_init(const struct device *dev) +{ + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data ; + struct eth_phytium_xmac_dev_cfg *dev_conf = (struct eth_phytium_xmac_dev_cfg *)dev->config ; + FXmac *instance_p; + instance_p = &dev_data->instance ; + FXmacBd bdtemplate; + FXmacBdRing *txringptr; + + txringptr = &FXMAC_GET_TXRING((*instance_p)); + FXMAC_BD_CLEAR(&bdtemplate); + FXMAC_BD_SET_STATUS(&bdtemplate, FXMAC_TXBUF_USED_MASK); + + if (FXmacBdRingCreate(txringptr, (uintptr)dev_data->tx_bdspace, + (uintptr)dev_data->tx_bdspace, ETH_PHYTIUM_BDL_ALIGNMENT, + dev_conf->txbd_count)) + { + LOG_ERR("FXmacBdRingCreate is error") ; + return ; + } + + FXmacBdRingClone(txringptr, &bdtemplate, FXMAC_SEND); +} + +static void FXmacHandleTxErrors( const struct device *dev) +{ + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data ; + FXmac *instance_p; + + instance_p = &dev_data->instance ; + + u32 netctrlreg; + + netctrlreg = FXMAC_READREG32(instance_p->config.base_address, + FXMAC_NWCTRL_OFFSET); + netctrlreg = netctrlreg & (~FXMAC_NWCTRL_TXEN_MASK); + FXMAC_WRITEREG32(instance_p->config.base_address, + FXMAC_NWCTRL_OFFSET, netctrlreg); + + eth_phytium_xmac_tx_dma_init(dev); + netctrlreg = FXMAC_READREG32(instance_p->config.base_address, FXMAC_NWCTRL_OFFSET); + netctrlreg = netctrlreg | (FXMAC_NWCTRL_TXEN_MASK); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_NWCTRL_OFFSET, netctrlreg); +} + +void FXmacErrorHandler(void *arg, u8 direction, u32 error_word) +{ + const struct device *dev = (const struct device *)arg ; + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data; + struct eth_phytium_xmac_dev_cfg *dev_conf = (struct eth_phytium_xmac_dev_cfg *)dev->config; + FXmac *instance_p; + instance_p = &dev_data->instance ; + + if (error_word != 0) + { + switch (direction) + { + case FXMAC_RECV: + if (error_word & FXMAC_RXSR_HRESPNOK_MASK) + { + LOG_ERR("Receive DMA error\r\n"); + FXmacHandleDmaTxError(dev); + } + if (error_word & FXMAC_RXSR_RXOVR_MASK) + { + LOG_ERR("Receive over run\r\n"); + FXmacRecvHandler((void *)dev) ; + } + if (error_word & FXMAC_RXSR_BUFFNA_MASK) + { + LOG_ERR("Receive buffer not available\r\n"); + FXmacRecvHandler((void *)dev) ; + } + break; + case FXMAC_SEND: + if (error_word & FXMAC_TXSR_HRESPNOK_MASK) + { + LOG_ERR("Transmit DMA error\r\n"); + FXmacHandleDmaTxError(dev); + } + if (error_word & FXMAC_TXSR_URUN_MASK) + { + LOG_ERR("Transmit under run\r\n"); + FXmacHandleTxErrors(dev); + } + if (error_word & FXMAC_TXSR_BUFEXH_MASK) + { + LOG_ERR("Transmit buffer exhausted\r\n"); + FXmacHandleTxErrors(dev); + } + if (error_word & FXMAC_TXSR_RXOVR_MASK) + { + LOG_ERR("Transmit retry excessed limits\r\n"); + FXmacHandleTxErrors(dev); + } + if (error_word & FXMAC_TXSR_FRAMERX_MASK) + { + LOG_ERR("Transmit collision\r\n"); + if (dev_conf->defer_txd_to_queue) { + k_work_submit(&dev_data->tx_done_work); + } + else + { + eth_phytium_xmac_handle_tx_done(dev); + } + } + break; + } + } +} + +#ifdef CONFIG_NET_STATISTICS_ETHERNET +/** + * @name: eth_phytium_xmac_stats + * @msg: Retrieves the Ethernet statistics for the device. + * @param {const struct device} *dev is a pointer to the device structure for the driver instance. + * @return {struct net_stats_eth} * A pointer to the statistics structure. + */ +static struct net_stats_eth *eth_phytium_xmac_stats(const struct device *dev) +{ + struct eth_phytium_xmac_dev_data *dev_data = dev->data; + + return &dev_data->stats; +} +#endif + +/** + * @name: FXmacSetupIsr + * @msg: Sets up the interrupt service routine handlers for transmit, receive, and error events. + * @param {const struct device} *dev is a pointer to the device structure for the driver instance. + */ +static void FXmacSetupIsr(const struct device *dev) +{ + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data ; + /* Setup callbacks */ + FXmac *instance_p; + instance_p = &dev_data->instance; + + FXmacSetHandler(instance_p, FXMAC_HANDLER_DMASEND, FXmacSendHandler, (void *)dev); + FXmacSetHandler(instance_p, FXMAC_HANDLER_DMARECV, FXmacRecvHandler,(void *) (void *)dev); + FXmacSetHandler(instance_p, FXMAC_HANDLER_ERROR, FXmacErrorHandler, (void *)dev); +} + +/** + * @name: eth_phytium_xmac_start_device + * @msg: Starts the Ethernet device, enabling packet transmission and reception. + * @param {const struct device} *dev is a pointer to the device structure for the driver instance. + * @return {int} Zero on success or negative error code on failure. + */ +static int eth_phytium_xmac_start_device(const struct device *dev) +{ + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data; + /* Setup callbacks */ + if (dev_data->started) { + return 0; + } + dev_data->started = true; + + FXmac *instance_p; + instance_p = &dev_data->instance; + FXmacStart(instance_p) ; + return 0 ; +} + +/** + * @name: eth_phytium_xmac_stop_device + * @msg: Stops the Ethernet device, disabling packet transmission and reception. + * @param {const struct device} *dev is a pointer to the device structure for the driver instance. + * @return {int} Zero on success or negative error code on failure. + */ +static int eth_phytium_xmac_stop_device(const struct device *dev) +{ + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data; + FXmac *instance_p; + instance_p = &dev_data->instance; + + if (!dev_data->started) { + return 0; + } + dev_data->started = false; + + /* Cancel the delayed work that polls the link state */ + if (k_work_delayable_remaining_get(&dev_data->phy_poll_delayed_work) != 0) + { + k_work_cancel_delayable(&dev_data->phy_poll_delayed_work); + } + + FXmacStop(instance_p) ; + + return 0 ; +} + +/** + * @name: eth_phytium_xmac_isr + * @msg: Interrupt service routine for handling all interrupts from the Ethernet device. + * @param {const struct device} *dev is a pointer to the device structure for the driver instance. + */ +static void eth_phytium_xmac_isr(const struct device *dev) +{ + u32 reg_isr; + u32 reg_temp; + u32 reg_ctrl; + + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data; + /* Setup callbacks */ + FXmac *instance_p; + instance_p = &dev_data->instance; + + reg_isr = FXMAC_READREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET); + { + if ((reg_isr & FXMAC_IXR_TXCOMPL_MASK) != 0x00000000U) + { + /* Clear TX status register TX complete indication but preserve + * error bits if there is any */ + FXMAC_WRITEREG32(instance_p->config.base_address, + FXMAC_TXSR_OFFSET, + ((u32)FXMAC_TXSR_TXCOMPL_MASK | + (u32)FXMAC_TXSR_USEDREAD_MASK)); + if (instance_p->send_irq_handler) + { + /* code */ + instance_p->send_irq_handler(instance_p->send_args); + } + /* add */ + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TXCOMPL_MASK); + } + } + + /* Transmit error conditions interrupt */ + if (((reg_isr & FXMAC_IXR_TX_ERR_MASK) != 0x00000000U) && + (!(reg_isr & FXMAC_IXR_TXCOMPL_MASK) != 0x00000000U)) + { + /* Clear TX status register */ + reg_temp = FXMAC_READREG32(instance_p->config.base_address, FXMAC_TXSR_OFFSET); + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_TXSR_OFFSET, reg_temp); + if (instance_p->error_irq_handler) + { + instance_p->error_irq_handler(instance_p->error_args, FXMAC_SEND, reg_temp); + } + /* add */ + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TX_ERR_MASK); + } + } + + /* add restart */ + if ((reg_isr & FXMAC_IXR_TXUSED_MASK) != 0x00000000U) + { + /* add */ + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TXUSED_MASK); + } + if (instance_p->restart_handler) + { + instance_p->restart_handler(instance_p->restart_args); + } + } + + /* link changed */ + if ((reg_isr & FXMAC_IXR_LINKCHANGE_MASK) != 0x00000000U) + { + if (instance_p->link_change_handler) + { + instance_p->link_change_handler(instance_p->link_change_args); + } + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_LINKCHANGE_MASK); + } + } + } + + + { + /* Receive complete interrupt */ + if ((reg_isr & FXMAC_IXR_RXCOMPL_MASK) != 0x00000000U) + { + /* Clear RX status register RX complete indication but preserve + * error bits if there is any */ + FXMAC_WRITEREG32(instance_p->config.base_address, + FXMAC_RXSR_OFFSET, + ((u32)FXMAC_RXSR_FRAMERX_MASK | + (u32)FXMAC_RXSR_BUFFNA_MASK)); + instance_p->recv_irq_handler(instance_p->recv_args); + /* add */ + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_RXCOMPL_MASK); + } + } + + /* Receive error conditions interrupt */ + if ((reg_isr & FXMAC_IXR_RX_ERR_MASK) != 0x00000000U) + { + /* Clear RX status register */ + reg_temp = FXMAC_READREG32(instance_p->config.base_address, + FXMAC_RXSR_OFFSET); + FXMAC_WRITEREG32(instance_p->config.base_address, + FXMAC_RXSR_OFFSET, reg_temp); + if ((reg_isr & FXMAC_IXR_RXUSED_MASK) != 0x00000000U) + { + reg_ctrl = FXMAC_READREG32(instance_p->config.base_address, + FXMAC_NWCTRL_OFFSET); + reg_ctrl |= (u32)FXMAC_NWCTRL_FLUSH_DPRAM_MASK; + /* add */ + reg_ctrl &= (u32)(~FXMAC_NWCTRL_RXEN_MASK); + FXMAC_WRITEREG32(instance_p->config.base_address, + FXMAC_NWCTRL_OFFSET, reg_ctrl); + /* add */ + reg_ctrl |= (u32)FXMAC_NWCTRL_RXEN_MASK; + FXMAC_WRITEREG32(instance_p->config.base_address, + FXMAC_NWCTRL_OFFSET, reg_ctrl); + + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_RXUSED_MASK); + } + } + /* add */ + if ((reg_isr & FXMAC_IXR_RXOVR_MASK) != 0x00000000U) + { + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_RXOVR_MASK); + } + } + /* add */ + if ((reg_isr & FXMAC_IXR_HRESPNOK_MASK) != 0x00000000U) + { + if(instance_p->caps& FXMAC_CAPS_ISR_CLEAR_ON_WRITE) + { + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_HRESPNOK_MASK); + } + } + if (reg_temp != 0) + { + instance_p->error_irq_handler(instance_p->error_args, + FXMAC_RECV, reg_temp); + } + } + } +} + +/** + * @name: eth_phytium_xmac_iface_init + * @msg: Initializes the network interface for the Ethernet driver. Sets the link address and registers the Ethernet interface with the network stack. + * @param {struct net_if} *iface is a pointer to the network interface structure. + */ +static void eth_phytium_xmac_iface_init(struct net_if *iface) +{ + const struct device *dev = net_if_get_device(iface); + const struct eth_phytium_xmac_dev_cfg *dev_conf = dev->config; + struct eth_phytium_xmac_dev_data *dev_data = dev->data; + + /* Set the initial contents of the current instance's run-time data */ + dev_data->iface = iface; + net_if_set_link_addr(iface, dev_data->mac_addr, 6, NET_LINK_ETHERNET); + ethernet_init(iface); + net_if_carrier_off(iface); + + /* + * Initialize the (delayed) work items for RX pending, TX done + * and PHY status polling handlers + */ + k_work_init(&dev_data->tx_done_work, eth_phytium_xmac_tx_done_work); + k_work_init(&dev_data->rx_pend_work, eth_phytium_xmac_rx_pending_work); + k_work_init_delayable(&dev_data->phy_poll_delayed_work, + eth_phytium_xmac_poll_phy); + + /* Initialize TX completion semaphore */ + k_sem_init(&dev_data->tx_done_sem, 0, 1); + + /* + * Initialize semaphores in the RX/TX BD rings which have not + * yet been initialized + */ + k_sem_init(&dev_data->ring_sem, 1, 1); + /* RX BD ring semaphore is not required at the time being */ + + /* Initialize the device's interrupt */ + dev_conf->config_func(dev); + + /* Submit initial PHY status polling delayed work */ + k_work_reschedule(&dev_data->phy_poll_delayed_work, K_NO_WAIT); + +} + +/** + * @name: eth_phytium_xmac_dev_init + * @msg: Initializes the Ethernet device, including hardware configuration and MAC address setting. + * @param {const struct device} *dev is a pointer to the device structure for the driver instance. + * @return {int} Zero on success or negative error code on failure. + */ +static int eth_phytium_xmac_dev_init(const struct device *dev) +{ + struct eth_phytium_xmac_dev_data *dev_data = (struct eth_phytium_xmac_dev_data *)dev->data ; + struct eth_phytium_xmac_dev_cfg *dev_conf = (struct eth_phytium_xmac_dev_cfg *)dev->config ; + FXmacConfig mac_config; + FXmac *instance_p; + uint32_t xmac_options ; + uint32_t dmacrreg; + int ret ; + + /* init base */ + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); + + /* config init */ + mac_config.base_address = DEVICE_MMIO_GET(dev) ; + mac_config.instance_id = 0; + + ret = eth_phytium_xmac_config_convert(dev_conf,&mac_config,&xmac_options) ; + if(ret) + { + return -EINVAL; + } + + instance_p = &dev_data->instance; + if(FXmacCfgInitialize(instance_p, &mac_config)) + { + return -EIO; + } + + FXmacSetOptions(instance_p, xmac_options, 0); + + /* set mac address */ + if(FXmacSetMacAddress(instance_p, (void *)(dev_data->mac_addr), 0)) + { + return -EIO; + } + + if(mac_config.interface != FXMAC_PHY_INTERFACE_MODE_USXGMII) + { + /* initialize phy */ + if(FXmacPhyInit(instance_p, instance_p->config.speed, instance_p->config.duplex, instance_p->config.auto_neg,XMAC_PHY_RESET_ENABLE)) + { + LOG_WRN("FXmacPhyInit is error \r\n"); + } + } + + FXmacSelectClk(instance_p); + FXmacInitInterface(instance_p); + + /* initialize dma */ + dmacrreg = FXMAC_READREG32(instance_p->config.base_address, FXMAC_DMACR_OFFSET); + dmacrreg &= ~(FXMAC_DMACR_BLENGTH_MASK); + dmacrreg = dmacrreg | FXMAC_DMACR_INCR16_AHB_AXI_BURST; /* Attempt to use bursts of up to 16. */ + FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_DMACR_OFFSET, dmacrreg); + /* setup dma bdl */ + eth_phytium_xmac_setuphandler(dev) ; + instance_p->mask = ((u32)FXMAC_IXR_TX_ERR_MASK + | (u32)FXMAC_IXR_RX_ERR_MASK + | (u32)FXMAC_IXR_RXCOMPL_MASK + | (u32)FXMAC_IXR_TXCOMPL_MASK); + /* setup tx、rx intr */ + FXmacSetupIsr(dev) ; + + return 0 ; +} + + + + diff --git a/drivers/ethernet/eth_phytium_xmac.h b/drivers/ethernet/eth_phytium_xmac.h new file mode 100644 index 0000000000000000000000000000000000000000..33cc1ecb7134e676abacbb3745ee00d134813946 --- /dev/null +++ b/drivers/ethernet/eth_phytium_xmac.h @@ -0,0 +1,117 @@ +#ifndef _ZEPHYR_DRIVERS_ETHERNET_ETH_PHYTIUM_XMAC_H_ +#define _ZEPHYR_DRIVERS_ETHERNET_ETH_PHYTIUM_XMAC_H_ + +#include "fxmac_bd.h" + +/* DMA memory area instantiation macro */ +#define ETH_PHYTIUM_XMAC_DMA_AREA_INST(port) \ +static struct eth_phytium_dma_area_gem##port eth_phytium_xmac##port##_dma_area\ + __aligned(4096); + +/* DMA memory area declaration macro */ +#define ETH_PHYTIUM_XMAC_DMA_AREA_DECL(port) \ +struct eth_phytium_dma_area_gem##port {\ + uint8_t rx_bd[DT_INST_PROP(port, rx_buffer_descriptors) * (u32)sizeof(FXmacBd)] __attribute__((aligned(256))) ;\ + uint8_t tx_bd[DT_INST_PROP(port, tx_buffer_descriptors) * (u32)sizeof(FXmacBd)] __attribute__((aligned(256)));\ + uint8_t rx_buffer\ + [DT_INST_PROP(port, rx_buffer_descriptors)]\ + [((DT_INST_PROP(port, rx_buffer_size)\ + + (ETH_PHYTIUM_BUFFER_ALIGNMENT - 1))\ + & ~(ETH_PHYTIUM_BUFFER_ALIGNMENT - 1))];\ + uint8_t tx_buffer\ + [DT_INST_PROP(port, tx_buffer_descriptors)]\ + [((DT_INST_PROP(port, tx_buffer_size)\ + + (ETH_PHYTIUM_BUFFER_ALIGNMENT - 1))\ + & ~(ETH_PHYTIUM_BUFFER_ALIGNMENT - 1))];\ +}; + + +/* RX/TX BD Ring initialization macro */ +#define ETH_PHYTIUM_XMAC_INIT_BD_RING(port) \ + dev_data->rx_bdspace = &(eth_phytium_xmac##port##_dma_area.rx_bd[0]);\ + dev_data->tx_bdspace = &(eth_phytium_xmac##port##_dma_area.tx_bd[0]);\ + dev_data->first_rx_buffer = (uint8_t *)eth_phytium_xmac##port##_dma_area.rx_buffer;\ + dev_data->first_rx_buffer_virt = dev_data->first_rx_buffer ;\ + dev_data->first_tx_buffer = (uint8_t *)eth_phytium_xmac##port##_dma_area.tx_buffer; \ + dev_data->first_tx_buffer_virt =dev_data->first_tx_buffer ; + + + + +#define ETH_PHYTIUM_XMAC_NET_DEV_INIT(port) \ +ETH_NET_DEVICE_DT_INST_DEFINE(port,\ + eth_phytium_xmac_dev_init,\ + NULL,\ + ð_phytium_xmac##port##_dev_data,\ + ð_phytium_xmac##port##_dev_cfg,\ + CONFIG_ETH_INIT_PRIORITY,\ + ð_phytium_xmac_apis,\ + NET_ETH_MTU); + + + +/* Device configuration data declaration macro */ +#define ETH_PHYTIUM_XMAC_DEV_CONFIG(port) \ +static const struct eth_phytium_xmac_dev_cfg eth_phytium_xmac##port##_dev_cfg = {\ + DEVICE_MMIO_ROM_INIT(DT_DRV_INST(port)), \ + .instance_id = port, \ + .config_func = eth_phytium_xmac##port##_irq_config,\ + .pll_clock_frequency = DT_INST_PROP(port, clock_frequency),\ + .phy_poll_interval = DT_INST_PROP(port, phy_poll_interval),\ + .defer_rxp_to_queue = !DT_INST_PROP(port, handle_rx_in_isr),\ + .defer_txd_to_queue = DT_INST_PROP(port, handle_tx_in_workq),\ + .rxbd_count = (uint8_t)\ + (DT_INST_PROP(port, rx_buffer_descriptors)),\ + .txbd_count = (uint8_t)\ + (DT_INST_PROP(port, tx_buffer_descriptors)),\ + .rx_buffer_size = (((uint16_t)(DT_INST_PROP(port, rx_buffer_size)) +\ + (ETH_PHYTIUM_BUFFER_ALIGNMENT-1)) & ~(ETH_PHYTIUM_BUFFER_ALIGNMENT-1)),\ + .tx_buffer_size = (((uint16_t)(DT_INST_PROP(port, tx_buffer_size)) +\ + (ETH_PHYTIUM_BUFFER_ALIGNMENT-1)) & ~(ETH_PHYTIUM_BUFFER_ALIGNMENT-1)),\ + .phy_speed = DT_INST_PROP(port, phy_speed),\ + .interface_mode = DT_INST_PROP(port, interface_mode),\ + .dma_brust_length = DT_INST_PROP(port, dma_brust_length),\ + .max_queue_num = DT_INST_PROP(port, max_queue_num),\ + .phy_autonegotiation = DT_INST_PROP(port, phy_autonegotiation),\ + .enable_fdx = DT_INST_PROP(port, enable_fdx),\ + .enable_jumbo = DT_INST_PROP(port, enable_jumbo),\ + .enable_ucast_hash = DT_INST_PROP(port, enable_ucast_hash),\ + .copy_all_frames = DT_INST_PROP(port, copy_all_frames),\ + .disable_reject_fcs_crc_errors = DT_INST_PROP(port, disable_reject_fcs_crc_errors),\ + .enable_mcast_hash = DT_INST_PROP(port, enable_mcast_hash),\ +}; + +/* Device run-time data declaration macro */ +#define ETH_PHYTIUM_XMAC_DEV_DATA(port) \ +static struct eth_phytium_xmac_dev_data eth_phytium_xmac##port##_dev_data = {\ + .mac_addr = DT_INST_PROP(port, local_mac_address),\ + .started = 0,\ + .eff_link_speed = LINK_DOWN,\ + .phy_addr = 0,\ + .phy_id = 0,\ + .first_rx_buffer = NULL,\ + .first_tx_buffer = NULL\ +}; + +/* Interrupt configuration function macro */ +#define ETH_PHYTIUM_XMAC_CONFIG_IRQ_FUNC(port) \ +static void eth_phytium_xmac##port##_irq_config(const struct device *dev)\ +{\ + ARG_UNUSED(dev);\ + IRQ_CONNECT(DT_INST_IRQN(port), DT_INST_IRQ(port, priority),\ + eth_phytium_xmac_isr, DEVICE_DT_INST_GET(port), 0);\ + irq_enable(DT_INST_IRQN(port));\ +} + + +/* Top-level device initialization macro - bundles all of the above */ +#define ETH_PHYTIUM_XMAC_INITIALIZE(port) \ +ETH_PHYTIUM_XMAC_CONFIG_IRQ_FUNC(port);\ +ETH_PHYTIUM_XMAC_DEV_CONFIG(port);\ +ETH_PHYTIUM_XMAC_DEV_DATA(port);\ +ETH_PHYTIUM_XMAC_DMA_AREA_DECL(port);\ +ETH_PHYTIUM_XMAC_DMA_AREA_INST(port);\ +ETH_PHYTIUM_XMAC_NET_DEV_INIT(port);\ + + +#endif diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index c46cf3691f7051a4ddb8bcf4d0650e28012cd7c9..4074f99e62bb4cd7c14aa81dd032e7f7382e05c3 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_PHYTIUM pinctrl_phytium.c) \ No newline at end of file diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 164cbd110892e0eb0223eb8fad7cceeeaa7b4b97..092e94d3d748c4538db243ce34280324d1e07bad 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.phytium" endif # PINCTRL diff --git a/drivers/pinctrl/Kconfig.phytium b/drivers/pinctrl/Kconfig.phytium new file mode 100644 index 0000000000000000000000000000000000000000..e0c80c267d120028668f5231085270494c9dacba --- /dev/null +++ b/drivers/pinctrl/Kconfig.phytium @@ -0,0 +1,22 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +config PINCTRL_PHYTIUM + bool "Pin controller driver for phytium" + default n + depends on DT_HAS_PHYTIUM_PINCTRL_ENABLED + + help + Enable pin controller driver for phytium . \ No newline at end of file diff --git a/drivers/pinctrl/pinctrl_phytium.c b/drivers/pinctrl/pinctrl_phytium.c new file mode 100644 index 0000000000000000000000000000000000000000..e80da694d4bb412130d395ccb37db8e08a55cfbb --- /dev/null +++ b/drivers/pinctrl/pinctrl_phytium.c @@ -0,0 +1,99 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +// +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/license/apache-2-0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT phytium_pinctrl +LOG_MODULE_REGISTER(pinctrl, CONFIG_PINCTRL_LOG_LEVEL); + +FIOPadCtrl iopad_ctrl; + +static FError pinctrl_configure_pin(const pinctrl_soc_pin_t *pin) +{ + FError ret; + ret = FIOPadSetFunc(&iopad_ctrl, pin->pin_reg_offset, pin->func_num); + if (ret != FIOPAD_SUCCESS) + { + LOG_ERR("FIOPadSetFunc error."); + } + + return ret; +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + FError ret; + ARG_UNUSED(reg); + for (uint8_t i = 0U; i < pin_cnt; i++) + { + ret = pinctrl_configure_pin(pins++); + if (ret != FIOPAD_SUCCESS) + { + LOG_ERR("pinctrl_configure_pin error."); + } + } + return 0; +} + +struct pinctrl_config { + DEVICE_MMIO_ROM; +}; + +struct pinctrl_data { + DEVICE_MMIO_RAM; +}; + +static int phytium_pinctrl_init(const struct device *dev) +{ + FIOPadConfig config_p; + config_p.instance_id = 0; + + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); + FIOPadCfgInitialize(&iopad_ctrl, &config_p); + + iopad_ctrl.config.base_address = DEVICE_MMIO_GET(dev); + + return 0; +} + +#define PHYTIUM_PINCTRL_INIT(n) \ + static const struct pinctrl_config pinctrl_##n##_config = { \ + DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), \ + }; \ + \ + static struct pinctrl_data pinctrl_##n##_data = { \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + &phytium_pinctrl_init, \ + NULL, \ + &pinctrl_##n##_data, \ + &pinctrl_##n##_config, \ + PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(PHYTIUM_PINCTRL_INIT) + diff --git a/drivers/pm_cpu_ops/CMakeLists.txt b/drivers/pm_cpu_ops/CMakeLists.txt index 15643f4702a3fbd21cb4cf8cf195d9910b35c500..876be71d9715f37b06449871bbef57766cd6f32d 100644 --- a/drivers/pm_cpu_ops/CMakeLists.txt +++ b/drivers/pm_cpu_ops/CMakeLists.txt @@ -2,8 +2,8 @@ zephyr_library() -zephyr_library_sources_ifdef(CONFIG_PM_CPU_OPS pm_cpu_ops_weak_impl.c) - zephyr_library_sources_ifdef(CONFIG_PM_CPU_OPS_PSCI pm_cpu_ops_psci.c) +zephyr_library_sources_ifdef(CONFIG_PM_CPU_OPS pm_cpu_ops_weak_impl.c) + zephyr_library_sources_ifdef(CONFIG_PSCI_SHELL psci_shell.c) diff --git a/drivers/sdhc/CMakeLists.txt b/drivers/sdhc/CMakeLists.txt index a43e3f54806f9ea4fcc6249579d6bc2b88347469..9de7258163fb63aa8e42565247c4b9028b5aa17e 100644 --- a/drivers/sdhc/CMakeLists.txt +++ b/drivers/sdhc/CMakeLists.txt @@ -8,4 +8,5 @@ zephyr_library_sources_ifdef(CONFIG_SPI_SDHC sdhc_spi.c) zephyr_library_sources_ifdef(CONFIG_MCUX_SDIF mcux_sdif.c) zephyr_library_sources_ifdef(CONFIG_SAM_HSMCI sam_hsmci.c) zephyr_library_sources_ifdef(CONFIG_INTEL_EMMC_HOST intel_emmc_host.c) +zephyr_library_sources_ifdef(CONFIG_PHYTIUM_USDHC phytium_sdhc.c) endif() diff --git a/drivers/sdhc/Kconfig b/drivers/sdhc/Kconfig index 69a942238e4aaf868d8f10e965fb1b8800020baa..adad51d18c547e6241c5e46e6b3fe43633e41710 100644 --- a/drivers/sdhc/Kconfig +++ b/drivers/sdhc/Kconfig @@ -13,6 +13,7 @@ source "drivers/sdhc/Kconfig.spi" source "drivers/sdhc/Kconfig.mcux_sdif" source "drivers/sdhc/Kconfig.sam_hsmci" source "drivers/sdhc/Kconfig.intel" +source "drivers/sdhc/Kconfig.phytium_sdhc" config SDHC_INIT_PRIORITY int "SDHC driver init priority" diff --git a/drivers/sdhc/Kconfig.phytium_sdhc b/drivers/sdhc/Kconfig.phytium_sdhc new file mode 100644 index 0000000000000000000000000000000000000000..9018be571cc7adc8cc84094e573038ddc517152c --- /dev/null +++ b/drivers/sdhc/Kconfig.phytium_sdhc @@ -0,0 +1,49 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +config PHYTIUM_USDHC + bool "PHYTIUM SDHC Driver" + default y + depends on DT_HAS_PHYTIUM_SDHC_ENABLED + select SDHC_SUPPORTS_NATIVE_MODE + select EVENTS + select PHYTIUM_PINCTRL + help + Enable the PHYTIUM SD Host controller driver + + +if PHYTIUM_USDHC + +config PHYTIUM_USDHC_DMA_SUPPORT + bool "DMA support for USDHC" + default y + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT + help + Enable DMA support for USDHC + +config PHYTIUM_PINCTRL + bool + +# SDIF DMA needs 32 bit aligned buffers +config SDHC_BUFFER_ALIGNMENT + int "Size of DMA descriptor buffer in bytes" + default 512 + +config PHYTIUM_SDIF_DMA_DESC_LENGTH + int "Length of DMA descriptor length" + default 256 + help + Size of PHYTIUM SDIF DMA descriptor length +endif \ No newline at end of file diff --git a/drivers/sdhc/phytium_sdhc.c b/drivers/sdhc/phytium_sdhc.c new file mode 100644 index 0000000000000000000000000000000000000000..b2be77b446f217592819cb50cba2e3b10e11486d --- /dev/null +++ b/drivers/sdhc/phytium_sdhc.c @@ -0,0 +1,1003 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +// +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/license/apache-2-0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#define DT_DRV_COMPAT phytium_sdhc + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +static void card_stoptrans(const struct device *dev) ; + +static int card_setblcok(const struct device *dev, uint32_t num_blocks) ; + + +LOG_MODULE_REGISTER(sdhc, CONFIG_SDHC_LOG_LEVEL); + +#define FSDIF_IRQ_BIT_CMD_DONE 1 +#define FSDIF_IRQ_BIT_DATA_DONE 2 +#define FSDIF_IRQ_BIT_ERROR_OCCUR 4 +#define FSDIF_IRQ_CMD_BIT_MASK (FSDIF_IRQ_BIT_CMD_DONE|FSDIF_IRQ_BIT_ERROR_OCCUR) +#define FSDIF_IRQ_DATA_BIT_MASK (FSDIF_IRQ_BIT_CMD_DONE|FSDIF_IRQ_BIT_DATA_DONE|FSDIF_IRQ_BIT_ERROR_OCCUR) + +typedef enum +{ + FSDIF_CLK_SPEED_400KHZ_IDX = 0, + FSDIF_CLK_SPEED_25_MHZ_IDX , + FSDIF_CLK_SPEED_26_MHZ_IDX , + FSDIF_CLK_SPEED_50_MHZ_IDX , + FSDIF_CLK_SPEED_52_MHZ_IDX , + FSDIF_CLK_SPEED_100_MHZ_IDX , + FSDIF_CLK_SPEED_200_MHZ_IDX , + FSDIF_CLK_SPEED_NUM +} sdhc_speed_mod ; + +typedef struct +{ + boolean use_hold; /* 1: CMD[29] = 1, equal to add one sampling time delay */ + uint32_t clk_div; /* for reg 0x8 */ + uint32_t clk_src; /* for reg 0x108 */ + uint32_t shift; /* for reg 0x110 */ +} sdhc_static_timming ; + + + +struct usdhc_config { + DEVICE_MMIO_ROM; + const struct device *clock_dev; + uint32_t pio_id ; + uint32_t pio_base ; + uint32_t pio_length; + uint32_t instance_id ; + uint32_t is_enable_irq ; + uint32_t enable_dma ; + /* smaple timing data */ + sdhc_static_timming static_timming[FSDIF_CLK_SPEED_NUM] ; + bool detect_dat3; + bool no_180_vol; + uint32_t data_timeout; + uint32_t write_watermark; + bool mmc_hs200_1_8v; + bool mmc_hs400_1_8v; + void (*irq_config_func)(const struct device *dev); + +}; + +struct usdhc_data { + DEVICE_MMIO_RAM; + struct sdhc_host_props props; + bool card_present; + struct sdhc_io host_io; + struct k_mutex access_mutex; +#ifdef CONFIG_PHYTIUM_USDHC_DMA_SUPPORT + FSdifIDmaDesc *usdhc_dma_descriptor; /* ADMA descriptor table (noncachable) */ + uint32_t dma_descriptor_len; /* DMA descriptor table length in words */ +#endif + /* pin ctrl */ + FIOPadCtrl iopad_ctrl; + FSdif instance ; + FSdifCmdData cmd_data ; + FSdifData trans_data ; + u32 is_enable_dma ; + struct k_event irq_event; /* include err、cmd、data event */ + +}; + +typedef struct +{ + boolean use_hold; /* 1: CMD[29] = 1, equal to add one sampling time delay */ + u32 clk_div; /* for reg 0x8 */ + u32 clk_src; /* for reg 0x108 */ + u32 shift; /* for reg 0x110 */ + void (*pad_delay)(void *instance); /* method to adjust pad delay ,with args*/ +} fsdhc_timming; /* SDIF timing configuration */ + + + +#define FSDIF_0_SD_CCLK_OUT_DELAY FIOPAD_AJ49_REG1_OFFSET +#define FSDIF_1_SD_CCLK_OUT_DELAY FIOPAD_J57_REG1_OFFSET + +/** + * @name: FSdifUpdateExternalClk + * @msg: update uhs clock value and wait clock ready + * @return {FError} + * @param {uintptr} base_addr + * @param {u32} uhs_reg_val + */ +static FError FSdifUpdateExternalClk(uintptr base_addr, u32 uhs_reg_val) +{ + u32 reg_val; + int retries = FSDIF_TIMEOUT; + FSDIF_WRITE_REG(base_addr, FSDIF_CLK_SRC_OFFSET, 0U); + FSDIF_WRITE_REG(base_addr, FSDIF_CLK_SRC_OFFSET, uhs_reg_val); + + do + { + reg_val = FSDIF_READ_REG(base_addr, FSDIF_CKSTS_OFFSET); + if (--retries <= 0) + { + break; + } + } + while (!(reg_val & FSDIF_CLK_READY)); + + return (retries <= 0) ? FSDIF_ERR_TIMEOUT : FSDIF_SUCCESS; +} + +/* irq test */ +static void FSDIFHOST_CardDetected(FSdif *const instance_p, void *args, u32 status, u32 dmac_status) +{ + (void)instance_p; + (void)status; + (void)dmac_status; + LOG_DBG("Card detected !!!"); +} + +static void FSDIFHOST_CmdDone(FSdif *const instance_p, void *args, u32 status, u32 dmac_status) +{ + struct usdhc_data *data = (struct usdhc_data *)args; + (void)instance_p; + (void)status; + (void)dmac_status; + /*Replace cmd_done by event */ + k_event_post(&data->irq_event,FSDIF_IRQ_BIT_CMD_DONE) ; +} + +static void FSDIFHOST_DataDone(FSdif *const instance_p, void *args, u32 status, u32 dmac_status) +{ + struct usdhc_data *data = (struct usdhc_data *)args; + + uint32_t check_status = status & (FSDIF_INT_DTO_BIT | FSDIF_INT_RCRC_BIT | + FSDIF_INT_DCRC_BIT | FSDIF_INT_RE_BIT | + FSDIF_INT_DRTO_BIT | FSDIF_INT_EBE_BIT | + FSDIF_INT_SBE_BCI_BIT | FSDIF_INT_RTO_BIT); + uint32_t check_dmac = dmac_status & (FSDIF_DMAC_STATUS_AIS | FSDIF_DMAC_STATUS_DU); + + if (check_status | check_dmac) + { + if (check_status & FSDIF_INT_DTO_BIT) + { + /* Replace data_done by event */ + k_event_post(&data->irq_event,FSDIF_IRQ_BIT_DATA_DONE) ; + } + else + { + LOG_DBG("Xfer data error, status: 0x%x, dmac status: 0x%x", + check_status, check_dmac); + } + } +} + +static void FSDIFHOST_ErrorOccur(FSdif *const instance_p, void *args, u32 status, u32 dmac_status) +{ + struct usdhc_data *data = (struct usdhc_data *)args; + LOG_ERR("Error occur !!!"); + LOG_ERR("Status: 0x%x, dmac status: 0x%x.", status, dmac_status); + + if (status & FSDIF_INT_RE_BIT) + LOG_ERR("Response err. 0x%x", (uint32_t)FSDIF_INT_RE_BIT); + + if (status & FSDIF_INT_RTO_BIT) + LOG_ERR("Response timeout. 0x%x", (uint32_t)FSDIF_INT_RTO_BIT); + + if (dmac_status & FSDIF_DMAC_STATUS_DU) + LOG_ERR("Descriptor un-readable. 0x%x", (uint32_t)FSDIF_DMAC_STATUS_DU); + + if (status & FSDIF_INT_DCRC_BIT) + LOG_ERR("Data CRC error. 0x%x", (uint32_t)FSDIF_INT_DCRC_BIT); + + if (status & FSDIF_INT_RCRC_BIT) + LOG_ERR("Data CRC error. 0x%x", (uint32_t)FSDIF_INT_RCRC_BIT); + + /* Replace data_done by event */ + k_event_post(&data->irq_event,FSDIF_IRQ_BIT_CMD_DONE|FSDIF_IRQ_BIT_ERROR_OCCUR) ; +} + + + +static void FSdifSetSDIFDelay(void * instance) +{ + /* + for SD-0: 0x32b31120 = 0x1f00 + SD-1: 0x32b31178 = 0x1f00 + */ + FIOPadCtrl * iopad_ctrl = (FIOPadCtrl * )instance; + u32 reg; + + if (FSDIF0_ID == iopad_ctrl->config.instance_id) + { + reg = FSDIF_0_SD_CCLK_OUT_DELAY; + } + else + { + reg = FSDIF_1_SD_CCLK_OUT_DELAY; + } + + FIOPadSetDelay(iopad_ctrl, reg, FIOPAD_OUTPUT_DELAY, FIOPAD_DELAY_COARSE_TUNING, FIOPAD_DELAY_1); + FIOPadSetDelay(iopad_ctrl, reg, FIOPAD_OUTPUT_DELAY, FIOPAD_DELAY_FINE_TUNING, FIOPAD_DELAY_7); + FIOPadSetDelayEn(iopad_ctrl, reg, FIOPAD_OUTPUT_DELAY, TRUE); +} + +static void FSdifUnsetSDIFDelay(void * instance) +{ + /* + for SD-0: 0x32b31120 = 0x0 + SD-1: 0x32b31178 = 0x0 + */ + FIOPadCtrl * iopad_ctrl = (FIOPadCtrl *)instance; + u32 reg; + + if (FSDIF0_ID == iopad_ctrl->config.instance_id) + { + reg = FSDIF_0_SD_CCLK_OUT_DELAY; + } + else + { + reg = FSDIF_1_SD_CCLK_OUT_DELAY; + } + + FIOPadSetDelay(iopad_ctrl, reg, FIOPAD_OUTPUT_DELAY, FIOPAD_DELAY_COARSE_TUNING, FIOPAD_DELAY_NONE); + FIOPadSetDelay(iopad_ctrl, reg, FIOPAD_OUTPUT_DELAY, FIOPAD_DELAY_FINE_TUNING, FIOPAD_DELAY_NONE); + FIOPadSetDelayEn(iopad_ctrl, reg, FIOPAD_OUTPUT_DELAY, FALSE); +} + +/* default timing settings in e2000q demo board */ +static fsdhc_timming mmc_sd_400khz = +{ + .use_hold = 1, + .clk_div = 0x7e7dfa, + .clk_src = 0x000502, + .shift = 0x0, + .pad_delay = FSdifUnsetSDIFDelay, +}; + +static fsdhc_timming sd_25mhz = +{ + .use_hold = 1, + .clk_div = 0x030204, + .clk_src = 0x000302, + .shift = 0x0, + .pad_delay = FSdifUnsetSDIFDelay, +}; + +static fsdhc_timming sd_50mhz = +{ + .use_hold = 1, + .clk_div = 0x030204, + .clk_src = 0x000502, + .shift = 0x0, + .pad_delay = FSdifSetSDIFDelay +}; + +static fsdhc_timming sd_100mhz = +{ + .use_hold = 0, + .clk_div = 0x010002, + .clk_src = 0x000202, + .shift = 0x0, + .pad_delay = FSdifSetSDIFDelay, +}; + +static fsdhc_timming mmc_26mhz = +{ + .use_hold = 1, + .clk_div = 0x030204, + .clk_src = 0x000302, + .shift = 0x0, + .pad_delay = FSdifSetSDIFDelay, +}; + +static fsdhc_timming mmc_52mhz = +{ + .use_hold = 0, + .clk_div = 0x030204, + .clk_src = 0x000202, + .shift = 0x0, + .pad_delay = FSdifSetSDIFDelay, +}; + +const fsdhc_timming *fsdif_hc_get_timming(FSdifClkSpeed clock_freq, boolean non_removable) +{ + const fsdhc_timming * tuning = NULL; + + if (clock_freq == FSDIF_CLK_SPEED_400KHZ) + { + return &mmc_sd_400khz; + } + + if (non_removable) + { + /* for emmc card */ + switch (clock_freq) + { + case FSDIF_CLK_SPEED_26_MHZ: + tuning = &mmc_26mhz; + break; + case FSDIF_CLK_SPEED_52_MHZ: + tuning = &mmc_52mhz; + break; + /* TODO: more clock freq for tuning */ + default: + break; + } + } + else + { + /* for sd card */ + switch (clock_freq) + { + case FSDIF_CLK_SPEED_25_MHZ: + tuning = &sd_25mhz; + break; + case FSDIF_CLK_SPEED_50_MHZ: + tuning = &sd_50mhz; + break; + case FSDIF_CLK_SPEED_100_MHZ: + tuning = &sd_100mhz; + break; + /* TODO: more clock freq for tuning */ + default: + break; + } + } + + return tuning; +} + + +/* + * Reset USDHC controller + */ +static int phytium_sdhc_reset(const struct device *dev) +{ + struct usdhc_data *data = dev->data; + FSdif *instance = &data->instance ; + + return FSdifRestart(instance) == 0 ? 0 : -ETIMEDOUT; + +} + + +static int phytium_sdhc_set_io(const struct device *dev, struct sdhc_io *ios) +{ + struct usdhc_data *data = dev->data; + FSdif *instance = &data->instance ; + FIOPadCtrl *pin_ctrl = &data->iopad_ctrl ; + struct sdhc_io *host_io = &data->host_io; + const fsdhc_timming *target_timing; + u32 mci_cmd_bits = FSDIF_CMD_UPD_CLK; + FError ret ; + uint32_t cmd_reg; + uint32_t cur_cmd_index; + + LOG_DBG("SDHC I/O: bus width %d, clock %dHz, card power %s, voltage %s \r\n", + ios->bus_width, + ios->clock, + ios->power_mode == SDHC_POWER_ON ? "ON" : "OFF", + ios->signal_voltage == SD_VOL_1_8_V ? "1.8V" : "3.3V" + ); + + /* host clock , must have */ + if(ios->clock > 0) + { + cmd_reg = FSDIF_READ_REG(instance->config.base_addr, FSDIF_CMD_OFFSET); + cur_cmd_index = FSDIF_CMD_INDX_GET(cmd_reg); + + if (FSDIF_SWITCH_VOLTAGE == cur_cmd_index) + { + mci_cmd_bits |= FSDIF_CMD_VOLT_SWITCH; + } + + target_timing = fsdif_hc_get_timming(ios->clock,instance->config.non_removable) ; + if (NULL == target_timing) + { + LOG_ERR("No available timeing !!!"); + return -ENOTSUP; + } + + /* update pad delay */ + if (target_timing->pad_delay) + { + target_timing->pad_delay(pin_ctrl); + } + + /* update clock source setting */ + if (FSDIF_SUCCESS != FSdifUpdateExternalClk(instance->config.base_addr, target_timing->clk_src)) + { + LOG_ERR("update clock source failed !!!"); + return -ENOTSUP; + } + + FSdifSetClock(instance->config.base_addr, FALSE); + + /* update clock for clock source */ + if (FSDIF_SWITCH_VOLTAGE == cur_cmd_index) + { + ret = FSdifSendPrivateCmd11(instance->config.base_addr, mci_cmd_bits | cmd_reg); + } + else + { + ret = FSdifSendPrivateCmd(instance->config.base_addr, mci_cmd_bits, 0); + } + + if (FSDIF_SUCCESS != ret) + { + LOG_ERR("update ext clock failed !!!"); + return -ret; + } + + /* set clock divider */ + FSDIF_WRITE_REG(instance->config.base_addr, FSDIF_CLKDIV_OFFSET, target_timing->clk_div); + + FSDIF_WRITE_REG(instance->config.base_addr, FSDIF_ENABLE_SHIFT_OFFSET, target_timing->shift); + + LOG_DBG("clk_src: 0x%x clk_div: 0x%x, shift: 0x%x", + FSDIF_READ_REG(instance->config.base_addr, FSDIF_CLK_SRC_OFFSET), + FSDIF_READ_REG(instance->config.base_addr, FSDIF_CLKDIV_OFFSET), + FSDIF_READ_REG(instance->config.base_addr, FSDIF_ENABLE_SHIFT_OFFSET)); + + FSdifSetClock(instance->config.base_addr, TRUE); + + /* sd card issue */ + if (FSDIF_SWITCH_VOLTAGE == cur_cmd_index) + { + ret = FSdifSendPrivateCmd11(instance->config.base_addr, mci_cmd_bits | cmd_reg); + } + else + { + ret = FSdifSendPrivateCmd(instance->config.base_addr, mci_cmd_bits, 0); + } + + + instance->curr_timing = (const FSdifTiming *)target_timing; + + } + + /* bus width */ + if (host_io->bus_width != ios->bus_width) { + switch (ios->bus_width) { + case SDHC_BUS_WIDTH1BIT: + FSdifSetBusWidth(instance->config.base_addr, 1); + break; + case SDHC_BUS_WIDTH4BIT: + FSdifSetBusWidth(instance->config.base_addr, 4); + break; + case SDHC_BUS_WIDTH8BIT: + FSdifSetBusWidth(instance->config.base_addr, 8); + break; + default: + return -ENOTSUP; + } + host_io->bus_width = ios->bus_width; + } + /* only surpport 3.3V */ + /* Set host signal voltage */ + if (ios->signal_voltage != host_io->signal_voltage) { + switch (ios->signal_voltage) { + case SD_VOL_3_3_V: + case SD_VOL_3_0_V: + FSdifSetVoltage1_8V(instance->config.base_addr, FALSE); + break; + case SD_VOL_1_8_V: + break; + default: + return -ENOTSUP; + } + /* Save new host voltage */ + host_io->signal_voltage = ios->signal_voltage; + } + return 0; +} + + +static int phytium_sdhc_card_busy(const struct device *dev) +{ + struct usdhc_data *device_data = dev->data; + FSdif *instance = &device_data->instance ; + + return FSdifCheckIfCardBusy(instance->config.base_addr) ? 1 : 0; +} + + +#define SPI_MASK ((1U << 4) | (2U << 4) | (3U << 4) | (4U << 4) | (5U << 4) | (6U << 4) | (7U << 4)) + +static void phytium_cmddata_convert_dri_data(struct sdhc_command *cmd, struct sdhc_data *data, FSdifCmdData *cmd_data) +{ + cmd->response_type &= ~SPI_MASK ; + + if(cmd->opcode == SD_GO_IDLE_STATE) + { + cmd_data->flag |= FSDIF_CMD_FLAG_NEED_INIT; + } + + if((cmd->opcode == SD_GO_INACTIVE_STATE) && + ((cmd->arg >> 9) & 0x1FFFF) == SD_SWITCH) + { + cmd_data->flag |= FSDIF_CMD_FLAG_ABORT; + } + + if(SD_RSP_TYPE_NONE != cmd->response_type) + { + cmd_data->flag |= FSDIF_CMD_FLAG_EXP_RESP; + + if(cmd->response_type == SD_RSP_TYPE_R2) + { + cmd_data->flag |= FSDIF_CMD_FLAG_EXP_LONG_RESP; + } + + if((cmd->response_type != SD_RSP_TYPE_R3) && + (cmd->response_type != SD_RSP_TYPE_R4)) + { + cmd_data->flag |= FSDIF_CMD_FLAG_NEED_RESP_CRC; + } + } + + if(cmd->opcode == SD_VOL_SWITCH) + { + cmd_data->flag |= FSDIF_CMD_FLAG_SWITCH_VOLTAGE; + } + + if(cmd->opcode == SD_GO_INACTIVE_STATE) + { + /* CMD15 go inactive and abort current transfer */ + cmd_data->flag |= FSDIF_CMD_FLAG_ABORT; + } + + if(data) + { + cmd_data->flag |= FSDIF_CMD_FLAG_EXP_DATA; + + switch(cmd->opcode) + { + case SD_WRITE_SINGLE_BLOCK: + case SD_WRITE_MULTIPLE_BLOCK: + cmd_data->flag |= FSDIF_CMD_FLAG_WRITE_DATA; + cmd_data->data_p->buf = data->data; + cmd_data->data_p->buf_dma = (uintptr_t)data->data; + break; + default: + cmd_data->flag |= FSDIF_CMD_FLAG_READ_DATA; + cmd_data->data_p->buf = data->data; + // This assumes that the data pointer can be used as a DMA address, which might not always be correct. + cmd_data->data_p->buf_dma = (uintptr_t)data->data; + break; + } + + cmd_data->data_p->blksz = data->block_size; + cmd_data->data_p->blkcnt = data->blocks; + cmd_data->data_p->datalen = data->block_size * data->blocks; + } + + cmd_data->cmdidx = cmd->opcode; + cmd_data->cmdarg = cmd->arg; + +} + +static int phytium_sdhc_request(const struct device *dev, struct sdhc_command *cmd, struct sdhc_data *data) +{ + struct usdhc_data *device_data = dev->data; + struct usdhc_config *device_config = (struct usdhc_config *)dev->config; + FSdif *instance = &device_data->instance ; + FSdifCmdData *cmd_data = &device_data->cmd_data ; + uint32_t timeout = 5000U ; + uint32_t wait_timeout_cnt = 0 ; + uint32_t events = 0; + uint32_t end_event = 0; /* 0 is init ,1 is finish ,2 is err ocurr */ + uint32_t wait_mask = 0; + + /* add send cmd23 */ + if(cmd->opcode == SD_WRITE_MULTIPLE_BLOCK||cmd->opcode == SD_READ_MULTIPLE_BLOCK) + { + if(card_setblcok(dev,data->blocks)) + { + LOG_ERR("FSdifDMATransfer is error") ; + return -EHOSTUNREACH; + } + } + + /* init event data is zero */ + if(device_config->is_enable_irq) + { + k_event_set(&device_data->irq_event,0) ; + } + + memset(&device_data->cmd_data,0,sizeof(FSdifCmdData)) ; + if(data) + { + memset(&device_data->trans_data,0,sizeof(FSdifData)) ; + cmd_data->data_p = &device_data->trans_data ; + wait_mask = FSDIF_IRQ_BIT_CMD_DONE | FSDIF_IRQ_BIT_DATA_DONE ; + } + else + { + cmd_data->data_p = NULL ; + wait_mask = FSDIF_IRQ_BIT_CMD_DONE ; + } + + phytium_cmddata_convert_dri_data(cmd,data,cmd_data) ; + + if(device_data->is_enable_dma) + { + if (0 != FSdifDMATransfer(instance, cmd_data)) + { + LOG_ERR("FSdifDMATransfer is error") ; + return -EHOSTUNREACH; + } + } + else + { + if (FSDIF_SUCCESS != FSdifPIOTransfer(instance, cmd_data)) + { + LOG_ERR("FSdifPIOTransfer is error") ; + return -EHOSTUNREACH; + } + } + + if(device_config->is_enable_irq) + { + do + { + events = k_event_wait(&device_data->irq_event,wait_mask|FSDIF_IRQ_BIT_ERROR_OCCUR,false,K_MSEC(1)) ; + if(events & FSDIF_IRQ_BIT_ERROR_OCCUR) + { + end_event = 2 ; + break ; + } + else if((events & wait_mask) == wait_mask) + { + end_event = 1 ; + break ; + } + else + { + wait_timeout_cnt ++ ; + end_event = 3 ; + } + }while (wait_timeout_cnt < 0xffffff) ; + + if(end_event == 2) + { + return -EIO ; + } + else if(end_event == 3) + { + return -ETIME ; + } + + } + else + { + /* If the interrupt is not enabled */ + if(device_data->is_enable_dma) + { + /* If the interrupt is not enabled */ + if (0 != FSdifPollWaitDMAEnd(instance, cmd_data)) + { + LOG_ERR("FSdifPollWaitDMAEnd is error") ; + return -ETIMEDOUT; + } + } + else + { + /* If the interrupt is not enabled */ + if (FSDIF_SUCCESS != FSdifPollWaitPIOEnd(instance,cmd_data)) + { + LOG_ERR("FSdifPollWaitPIOEnd is error") ; + return -ETIMEDOUT; + } + } + } + /* wait event is over */ + if(0 != FSdifGetCmdResponse(instance, cmd_data)) + { + LOG_ERR("FSdifGetCmdResponse is error") ; + + if(cmd_data->data_p) + { + card_stoptrans(dev) ; + + while (timeout > 0) { + if (!phytium_sdhc_card_busy(dev)) { + break; + } + /* Wait 125us before polling again */ + k_busy_wait(125); + timeout -= 125; + } + if (timeout <= 0) { + LOG_DBG("Card did not idle after CMD12"); + k_mutex_unlock(&device_data->access_mutex); + return -ETIMEDOUT; + } + + return -ETIMEDOUT; + } + + return -ETIMEDOUT; + } + + if(SD_RSP_TYPE_NONE != cmd->response_type) + { + memcpy(cmd->response,&cmd_data->response,sizeof(u32) * 4) ; + } + + return 0; +} + + + +/* Stops transmission after failed command with CMD12 */ +static void card_stoptrans(const struct device *dev) +{ + struct sdhc_command cmd = {0}; + + cmd.opcode = SD_STOP_TRANSMISSION; + cmd.arg = 0; + + cmd.response_type = (SD_RSP_TYPE_R1b); + + phytium_sdhc_request(dev, &cmd, NULL) ; + +} + +static int card_setblcok(const struct device *dev, uint32_t num_blocks) +{ + struct sdhc_command cmd = {0}; + + /* + * See the note in card_read() above. We will not issue CMD23 + * or CMD12, and expect the host to handle those details. + */ + cmd.opcode = SD_SET_BLOCK_COUNT; + + cmd.arg = num_blocks; + + cmd.response_type = (SD_RSP_TYPE_R1); + + return phytium_sdhc_request(dev, &cmd, NULL) ; +} + + + + +static int phytium_sdhc_get_card_present(const struct device *dev) +{ + struct usdhc_data *data = dev->data; + FSdif *instance = &data->instance ; + + data->card_present = FSdifCheckIfCardExists(instance->config.base_addr) ? true : false ; + return data->card_present ; +} + + +static int phytium_sdhc_get_host_props(const struct device *dev, + struct sdhc_host_props *props) +{ + struct usdhc_data *data = dev->data; + + memcpy(props, &data->props, sizeof(struct sdhc_host_props)); + return 0; +} + +static int phytium_sdhc_isr(const struct device *dev) +{ + // const struct usdhc_config *cfg = dev->config; + struct usdhc_data *data = dev->data; + FSdif *instance = &data->instance ; + + FSdifInterruptHandler(0, instance); + return 0; +} + + +static void phytium_sdhc_init_host_props(const struct device *dev) +{ + struct usdhc_data *data = dev->data; + struct sdhc_host_props *props = &data->props; + + memset(props, 0, sizeof(struct sdhc_host_props)); + props->f_max = 50000000U; + props->f_min = 400000; + + props->host_caps.vol_180_support = false; + props->host_caps.vol_300_support = true; + props->host_caps.vol_330_support = true; + props->host_caps.suspend_res_support = false; + props->host_caps.high_spd_support = true; + + props->host_caps.ddr50_support = false; + props->host_caps.sdr104_support = false; + props->host_caps.sdr50_support = false; + + props->host_caps.bus_4_bit_support = true; + props->host_caps.bus_8_bit_support = false; + props->host_caps.hs200_support = false; + props->host_caps.hs400_support = false; +} + + +void phytium_relax_delay(void) +{ + k_usleep(1); +} + + +static int phytium_usdhc_init(const struct device *dev) +{ + struct usdhc_config *cfg = (struct usdhc_config *)dev->config; + struct usdhc_data *data = (struct usdhc_data *)dev->data; + FSdifConfig sdhc_cfg; + FIOPadConfig io_config = {0} ; + + /* init base */ + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); + /* control init */ + sdhc_cfg.base_addr = DEVICE_MMIO_GET(dev) ; + sdhc_cfg.instance_id = cfg->instance_id; /* Device instance id */ + LOG_DBG("sdhc_cfg.instance_id is %d \r\n",sdhc_cfg.instance_id) ; + + sdhc_cfg.non_removable = FALSE ; /* No removeable media, e.g eMMC */ + sdhc_cfg.get_tuning = NULL ; /* Get time-tuning related parameters and method */ +#if defined(CONFIG_PHYTIUM_USDHC_DMA_SUPPORT) + data->is_enable_dma = 1 ; +#else + data->is_enable_dma = 0 ; +#endif + + if(data->is_enable_dma) + { + sdhc_cfg.trans_mode = FSDIF_IDMA_TRANS_MODE ; /* Trans mode, PIO/DMA */ + } + else + { + sdhc_cfg.trans_mode = FSDIF_PIO_TRANS_MODE ; /* Trans mode, PIO/DMA */ + } + + /* init pio init */ + io_config.instance_id = cfg->pio_id ; + + device_map(&io_config.base_address, + cfg->pio_base, + cfg->pio_length, + K_MEM_CACHE_NONE); + + if(0 != FIOPadCfgInitialize(&data->iopad_ctrl, &io_config)) + { + LOG_ERR("FIOPadCfgInitialize is error") ; + } + + if(0 != FSdifCfgInitialize(&data->instance,&sdhc_cfg)) + { + LOG_ERR("FSdifCfgInitialize is error") ; + } + data->instance.relax_handler = phytium_relax_delay ; + + phytium_sdhc_init_host_props(dev) ; + /* irq init */ + if(cfg->is_enable_irq) + { + if(cfg->irq_config_func) + { + FSdifRegisterEvtHandler(&data->instance, FSDIF_EVT_CARD_DETECTED, FSDIFHOST_CardDetected, (void *)data); + FSdifRegisterEvtHandler(&data->instance, FSDIF_EVT_ERR_OCCURE, FSDIFHOST_ErrorOccur, (void *)data); + FSdifRegisterEvtHandler(&data->instance, FSDIF_EVT_CMD_DONE, FSDIFHOST_CmdDone, (void *)data); + FSdifRegisterEvtHandler(&data->instance, FSDIF_EVT_DATA_DONE, FSDIFHOST_DataDone, (void *)data); + cfg->irq_config_func(dev) ; + } + } + +#if defined(CONFIG_PHYTIUM_USDHC_DMA_SUPPORT) + + if(data->is_enable_dma) + { + + if(FSdifSetIDMAList(&data->instance,data->usdhc_dma_descriptor,(uintptr)data->usdhc_dma_descriptor,CONFIG_PHYTIUM_SDIF_DMA_DESC_LENGTH)) + { + LOG_ERR("Init dma is error ") ; + return -EPERM; + } + } + +#endif + + /* init host_io */ + memset(&data->host_io, 0, sizeof(data->host_io)); + /* access_mutex */ + k_mutex_init(&data->access_mutex); + /* transfer_sem */ + k_event_init(&data->irq_event) ; + return 0 ; +} + +static const struct sdhc_driver_api usdhc_api = { + .reset = phytium_sdhc_reset, + .request = phytium_sdhc_request, + .set_io = phytium_sdhc_set_io, + .get_card_present = phytium_sdhc_get_card_present, + .execute_tuning = NULL, + .card_busy = phytium_sdhc_card_busy, + .get_host_props = phytium_sdhc_get_host_props, +}; + +#ifdef CONFIG_NOCACHE_MEMORY +#define PHYTIUM_USDHC_NOCACHE_TAG __attribute__((__section__(".nocache"))); +#else +#define PHYTIUM_USDHC_NOCACHE_TAG +#endif + +#ifdef CONFIG_PHYTIUM_USDHC_DMA_SUPPORT +#define PHYTIUM_USDHC_DMA_BUFFER_DEFINE(n) \ + static FSdifIDmaDesc __aligned(512) \ + usdhc_##n##_dma_descriptor[CONFIG_PHYTIUM_SDIF_DMA_DESC_LENGTH]\ + PHYTIUM_USDHC_NOCACHE_TAG; +#define PHYTIUM_USDHC_DMA_BUFFER_INIT(n) \ + .usdhc_dma_descriptor = usdhc_##n##_dma_descriptor, \ + .dma_descriptor_len = CONFIG_PHYTIUM_SDIF_DMA_DESC_LENGTH, + +#else +#define PHYTIUM_USDHC_DMA_BUFFER_DEFINE(n) +#define PHYTIUM_USDHC_DMA_BUFFER_INIT(n) +#endif /* CONFIG_PHYTIUM_USDHC_DMA_SUPPORT */ + +#define PHYTIUM_SDHC_INIT(n) \ + static void usdhc_##n##_irq_config_func(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + phytium_sdhc_isr, DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } \ + \ + static const struct usdhc_config usdhc_##n##_config = { \ + DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), \ + .instance_id = n, \ + .no_180_vol = DT_INST_PROP(n, no_1_8_v), \ + .mmc_hs200_1_8v = DT_INST_PROP(n, mmc_hs200_1_8v), \ + .mmc_hs400_1_8v = DT_INST_PROP(n, mmc_hs400_1_8v), \ + .pio_id = DT_INST_PROP(n, pio_id), \ + .pio_base = DT_INST_PROP(n, pio_base), \ + .pio_length = DT_INST_PROP(n, pio_length), \ + .is_enable_irq = DT_INST_PROP(n, is_enable_irq),\ + .irq_config_func = usdhc_##n##_irq_config_func ,\ + }; \ + \ + \ + PHYTIUM_USDHC_DMA_BUFFER_DEFINE(n) \ + \ + static struct usdhc_data usdhc_##n##_data = { \ + .card_present = false, \ + PHYTIUM_USDHC_DMA_BUFFER_INIT(n) \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + &phytium_usdhc_init, \ + NULL, \ + &usdhc_##n##_data, \ + &usdhc_##n##_config, \ + POST_KERNEL, \ + CONFIG_SDHC_INIT_PRIORITY, \ + &usdhc_api); + +DT_INST_FOREACH_STATUS_OKAY(PHYTIUM_SDHC_INIT) + + + diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 658ab50a71d6a045749cf06727188dff1266bcda..224501769e507d1d65af118c677bc13f3b45919b 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -35,6 +35,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_STM32 uart_stm32.c) zephyr_library_sources_ifdef(CONFIG_UART_SAM0 uart_sam0.c) zephyr_library_sources_ifdef(CONFIG_UART_PSOC6 uart_psoc6.c) zephyr_library_sources_ifdef(CONFIG_UART_PL011 uart_pl011.c) +# zephyr_library_sources_ifdef(CONFIG_PHYTIUM_UART_PL011 uart_phytium_pl011.c) zephyr_library_sources_ifdef(CONFIG_UART_QUICKLOGIC_USBSERIALPORT_S3B uart_ql_usbserialport_s3b.c) zephyr_library_sources_ifdef(CONFIG_UART_RV32M1_LPUART uart_rv32m1_lpuart.c) zephyr_library_sources_ifdef(CONFIG_UART_RPI_PICO uart_rpi_pico.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index e4ab095386183318233d8cc720f0b082a23e95ef..68105be5c034a871c2cba97120e4f4136b47eb4b 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -185,6 +185,8 @@ source "drivers/serial/Kconfig.psoc6" source "drivers/serial/Kconfig.pl011" +source "drivers/serial/kconfig.phytium_pl011" + source "drivers/serial/Kconfig.ql_usbserialport_s3b" source "drivers/serial/Kconfig.rv32m1_lpuart" diff --git a/drivers/serial/kconfig.phytium_pl011 b/drivers/serial/kconfig.phytium_pl011 new file mode 100644 index 0000000000000000000000000000000000000000..6e9a7912524394f61188a3f9021966464eae2aa3 --- /dev/null +++ b/drivers/serial/kconfig.phytium_pl011 @@ -0,0 +1,21 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +menuconfig PHYTIUM_UART_PL011 + bool "PHYTIUM PL011 UART Driver" + default y + select SERIAL_HAS_DRIVER + help + This option enables the UART driver for the PL011 diff --git a/drivers/serial/uart_phytium_pl011.c b/drivers/serial/uart_phytium_pl011.c new file mode 100644 index 0000000000000000000000000000000000000000..e6f04b16b47563309ea534a2d2356ad8039e05a4 --- /dev/null +++ b/drivers/serial/uart_phytium_pl011.c @@ -0,0 +1,148 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +// +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/license/apache-2-0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#define DT_DRV_COMPAT phytium_pl011 /* phytium,pl011 */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct phytium_pl011_data { + DEVICE_MMIO_RAM; + uint32_t baud_rate; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t irq_cb; + void *irq_cb_data; +#endif + FPl011 instance ; +}; + +struct phytium_pl011_config { + DEVICE_MMIO_ROM; + uint32_t instance_id; + uint32_t sys_clk_freq; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + /*Interrupt initialization function through the device tree*/ + uart_irq_config_func_t irq_config_func; +#endif +}; + +static int pl011_poll_in(const struct device *dev, unsigned char *c) +{ + struct phytium_pl011_data *data = dev->data; + FPl011 *uart_p = &data->instance ; + + if(FUART_RECEIVEDATAEMPTY(uart_p->config.base_address)) + { + return -1 ; + } + + *c = FPl011RecvByte(uart_p->config.base_address) ; + + return (FUART_RECEIVEDATAEMPTY(uart_p->config.base_address) == 0); +} + +static void pl011_poll_out(const struct device *dev, + unsigned char c) +{ + struct phytium_pl011_data *data = dev->data; + FPl011 *uart_p = &data->instance ; + + FPl011SendByte(uart_p->config.base_address,c) ; +} + +static const struct uart_driver_api pl011_driver_api = { + .poll_in = pl011_poll_in, + .poll_out = pl011_poll_out, +}; + +static int pl011_init(const struct device *dev) +{ + const struct phytium_pl011_config *config = dev->config; + struct phytium_pl011_data *data = dev->data; + FPl011Config pl011_config = {0} ; + FError driver_ret ; + + FPl011Format format = + { + .baudrate = FPL011_BAUDRATE, + .data_bits = FPL011_FORMAT_WORDLENGTH_8BIT, + .parity = FPL011_FORMAT_NO_PARITY, + .stopbits = FPL011_FORMAT_1_STOP_BIT + }; + + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); + + /* Id of device*/ + pl011_config.instance_id = config->instance_id; + pl011_config.base_address = DEVICE_MMIO_GET(dev) ; + pl011_config.ref_clock_hz = config->sys_clk_freq; + pl011_config.baudrate = data->baud_rate; + + driver_ret = FPl011CfgInitialize(&data->instance,&pl011_config) ; + + if(driver_ret) + { + return -1 ; + } + + driver_ret = FPl011SetDataFormat(&data->instance, &format); + + if(driver_ret) + { + return -2 ; + } + + /* set UART */ + FPl011SetOptions(&data->instance, FPL011_OPTION_UARTEN | FPL011_OPTION_FIFOEN | FPL011_OPTION_RXEN | FPL011_OPTION_TXEN | FPL011_OPTION_DTR | FPL011_OPTION_RTS); + + return 0; +} + + + + +#define PL011_CONFIG_PORT(n) \ + static struct phytium_pl011_config pl011_cfg_port_##n = { \ + DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), \ + .sys_clk_freq = DT_INST_PROP_BY_PHANDLE(n, clocks, clock_frequency), \ + .instance_id = n \ + }; + + +#define PHYTIUM_PL011_INIT(n) \ + PL011_CONFIG_PORT(n) \ + \ + static struct phytium_pl011_data pl011_data_port_##n = { \ + .baud_rate = DT_INST_PROP(n, current_speed), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, &pl011_init, \ + NULL, \ + &pl011_data_port_##n, \ + &pl011_cfg_port_##n, \ + PRE_KERNEL_1, \ + CONFIG_SERIAL_INIT_PRIORITY, \ + &pl011_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PHYTIUM_PL011_INIT) \ No newline at end of file diff --git a/dts/arm/phytium/e2000q.dtsi b/dts/arm/phytium/e2000q.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..5c28ddcc4fc14ecf61f92df59f74a6b0b69c6e6c --- /dev/null +++ b/dts/arm/phytium/e2000q.dtsi @@ -0,0 +1,149 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +// +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/license/apache-2-0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include +#include +#include + + +/ { + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "phytium,ftc310"; + reg = <0 0x200>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "phytium,ftc310"; + reg = <0 0x201>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "phytium,ftc664"; + reg = <0 0>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "phytium,ftc664"; + reg = <0 0x100>; + }; + }; + + + + uartclk: apb-pclk { + compatible = "fixed-clock"; + clock-frequency = <100000000>; + #clock-cells = <0>; + }; + + soc { + interrupt-parent = <&gic>; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + // ppi =+ 16, 13 == 29 Security physical timer interrupt, 14 == 30 Non secure physical timer interrupt + interrupts = , + , + , + ; + }; + + + uart1: uart@2800d000 { + compatible = "arm,pl011"; + reg = <0x2800d000 0x1000>; + status = "disabled"; + interrupts = ; + interrupt-names = "irq_0"; + clocks = <&uartclk>; + }; + + gic: interrupt-controller@30800000 { + compatible = "arm,gic-v3", "arm,gic"; + reg = <0x30800000 0x40000>, + <0x30880000 0x80000>; + interrupt-controller; + #interrupt-cells = <4>; + status = "okay"; + #size-cells = <0x02>; + #address-cells = <0x02>; + }; + + + + sram0: memory@80100000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0x80100000 0x20000000>; + }; + + xmac0: xmac@3200C000 { + compatible = "phytium,xmac"; + reg = <0x3200C000 0x2000>; + status = "disabled"; + interrupts = ; + interrupt-names = "irq_0"; + phy-poll-interval = <1000>; + clock-frequency = <50000000> ; + phy-speed = <1000> ; + interface-mode = <0> ; + dma-brust-length = <16> ; + max-queue-num = <1> ; + rx-buffer-descriptors = <128>; + tx-buffer-descriptors = <32>; + rx-buffer-size = <1600>; + tx-buffer-size = <1600>; + phy-autonegotiation; + enable-fdx; + disable-reject-fcs-crc-errors ; + } ; + + sdhc0: sdhc@28000000 { + compatible = "phytium,sdhc"; + reg = <0x28000000 0x1000>; + status = "disabled"; + interrupts = ; + max-current-330 = <1020>; + max-bus-freq = <25000000>; + min-bus-freq = <400000>; + }; + + + sdhc1: sdhc@28001000 { + compatible = "phytium,sdhc"; + reg = <0x28001000 0x1000>; + status = "disabled"; + interrupts = ; + max-current-330 = <1020>; + max-bus-freq = <25000000>; + min-bus-freq = <400000>; + }; + + }; +}; diff --git a/dts/arm64/phytium/e2000d.dtsi b/dts/arm64/phytium/e2000d.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..397540ea202ce85ed4fdbbd837d7ea3bd5d34de6 --- /dev/null +++ b/dts/arm64/phytium/e2000d.dtsi @@ -0,0 +1,149 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +// +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/license/apache-2-0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include +#include +#include + +/ { + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "phytium,ftc310"; + reg = <0 0x200>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "phytium,ftc310"; + reg = <0 0x201>; + }; + + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + // ppi =+ 16, 13 == 29 安全物理定时器中断, 14 == 30 非安全物理定时器中断 + interrupts = , + , + , + ; + }; + + uartclk: apb-pclk { + compatible = "fixed-clock"; + clock-frequency = <100000000>; + #clock-cells = <0>; + }; + + soc { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + interrupt-parent = <&gic>; + + gic: interrupt-controller@30800000 { + compatible = "arm,gic-v3", "arm,gic"; + reg = <0x00 0x30800000 0x00 0x40000>, + <0x00 0x30880000 0x00 0x80000>; + interrupt-controller; + #interrupt-cells = <4>; + status = "okay"; + #size-cells = <0x02>; + #address-cells = <0x02>; + }; + + uart1: uart@2800d000 { + compatible = "arm,pl011"; + reg = <0x00 0x2800d000 0x00 0x1000>; + status = "disabled"; + interrupts = ; + interrupt-names = "irq_0"; + clocks = <&uartclk>; + }; + + uart2: uart@2800E000 { + compatible = "arm,pl011"; + reg = <0x00 0x2800E000 0x00 0x1000>; + status = "disabled"; + interrupts = ; + interrupt-names = "irq_1"; + clocks = <&uartclk>; + }; + + sdhc0: sdhc@28000000 { + compatible = "phytium,sdhc"; + reg = <0x00 0x28000000 0x00 0x1000>; + status = "disabled"; + interrupts = ; + max-current-330 = <1020>; + max-bus-freq = <25000000>; + min-bus-freq = <400000>; + }; + + + sdhc1: sdhc@28001000 { + compatible = "phytium,sdhc"; + reg = <0x00 0x28001000 0x00 0x1000>; + status = "disabled"; + interrupts = ; + max-current-330 = <1020>; + max-bus-freq = <25000000>; + min-bus-freq = <400000>; + }; + + + xmac0: xmac@3200C000 { + compatible = "phytium,xmac"; + reg = <0x00 0x3200C000 0x00 0x2000>; + status = "disabled"; + interrupts = ; + interrupt-names = "irq_0"; + phy-poll-interval = <1000>; + clock-frequency = <50000000> ; + phy-speed = <1000> ; + interface-mode = <0> ; + dma-brust-length = <16> ; + max-queue-num = <1> ; + rx-buffer-descriptors = <128>; + tx-buffer-descriptors = <32>; + rx-buffer-size = <1600>; + tx-buffer-size = <1600>; + phy-autonegotiation; + enable-fdx; + disable-reject-fcs-crc-errors ; + } ; + + /* 256MB DDR */ + sram0: memory@80100000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0x00 0x80100000 0x00 0x10000000>; + }; + }; +}; diff --git a/dts/arm64/phytium/e2000q.dtsi b/dts/arm64/phytium/e2000q.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..8724b329e976cf20a6baf1a6332e111f16d5050b --- /dev/null +++ b/dts/arm64/phytium/e2000q.dtsi @@ -0,0 +1,177 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +// +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/license/apache-2-0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include +#include +#include + +/ { + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "phytium,ftc310"; + reg = <0 0x200>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "phytium,ftc310"; + reg = <0 0x201>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "phytium,ftc664"; + reg = <0 0>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "phytium,ftc664"; + reg = <0 0x100>; + }; + + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + // ppi =+ 16, 13 == 29 Security physical timer interrupt, 14 == 30 Non secure physical timer interrupt + interrupts = , + , + , + ; + }; + + uartclk: apb-pclk { + compatible = "fixed-clock"; + clock-frequency = <100000000>; + #clock-cells = <0>; + }; + + soc { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + interrupt-parent = <&gic>; + + gic: interrupt-controller@30800000 { + compatible = "arm,gic-v3", "arm,gic"; + reg = <0x00 0x30800000 0x00 0x40000>, + <0x00 0x30880000 0x00 0x80000>; + interrupt-controller; + #interrupt-cells = <4>; + status = "okay"; + #size-cells = <0x02>; + #address-cells = <0x02>; + }; + + pinctrl: pinctrl@32B30000 { + compatible = "phytium,pinctrl"; + reg = <0x00 0x32B30000 0x00 0x2000>; + status = "okay"; + }; + + uart1: uart@2800d000 { + compatible = "arm,pl011"; + reg = <0x00 0x2800d000 0x00 0x1000>; + status = "disabled"; + interrupts = ; + interrupt-names = "irq_0"; + clocks = <&uartclk>; + }; + + uart2: uart@2800E000 { + compatible = "arm,pl011"; + reg = <0x00 0x2800E000 0x00 0x1000>; + status = "disabled"; + interrupts = ; + interrupt-names = "irq_1"; + clocks = <&uartclk>; + }; + + sdhc0: sdhc@28000000 { + compatible = "phytium,sdhc"; + reg = <0x00 0x28000000 0x00 0x1000>; + status = "disabled"; + interrupts = ; + max-current-330 = <1020>; + max-bus-freq = <25000000>; + min-bus-freq = <400000>; + }; + + xmac0: xmac@3200C000 { + compatible = "phytium,xmac"; + reg = <0x00 0x3200C000 0x00 0x2000>; + status = "disabled"; + interrupts = ; + interrupt-names = "irq_0"; + phy-poll-interval = <5000>; + clock-frequency = <50000000> ; + phy-speed = <1000> ; + interface-mode = <0> ; + dma-brust-length = <16> ; + max-queue-num = <1> ; + rx-buffer-descriptors = <128>; + tx-buffer-descriptors = <128>; + rx-buffer-size = <1600>; + tx-buffer-size = <1600>; + phy-autonegotiation; + enable-fdx; + disable-reject-fcs-crc-errors ; + } ; + + sdhc1: sdhc@28001000 { + compatible = "phytium,sdhc"; + reg = <0x00 0x28001000 0x00 0x1000>; + status = "disabled"; + interrupts = ; + max-current-330 = <1020>; + max-bus-freq = <25000000>; + min-bus-freq = <400000>; + }; + + /* 512MB DDR */ + sram0: memory@80100000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0x00 0x80100000 0x00 0x20000000>; + }; + + pcie0: pcie@40000000 { + compatible = "pci-host-ecam-generic"; + device_type = "pci"; + reg = <0x00 0x40000000 0x00 0x10000000>; + #size-cells = <0x02>; + #address-cells = <0x03>; + ranges = <0x1000000 0x00 0x50000000 0x00 0x50000000 0x00 0x08000000 + 0x2000000 0x00 0x58000000 0x00 0x58000000 0x00 0x27ffffff + 0x3000000 0x10 0x00 0x10 0x00 0x1f 0xffffffff>; + bus-range = <0x00 0xff>; + }; + }; +}; diff --git a/dts/arm64/qemu/qemu-virt-a53.dtsi b/dts/arm64/qemu/qemu-virt-a53.dtsi index cb96eba2874ff42af0e27e6c0c828141ef7649f5..9294e44b898fd6295c524f9f48dccf614322d4f6 100644 --- a/dts/arm64/qemu/qemu-virt-a53.dtsi +++ b/dts/arm64/qemu/qemu-virt-a53.dtsi @@ -29,7 +29,7 @@ cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a53"; - reg = <0>; + reg = <2>; }; cpu@1 { diff --git a/dts/bindings/cpu/phytium,ftc310.yaml b/dts/bindings/cpu/phytium,ftc310.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e1f9c01fcc313fa75f9ebecb668cdb6c1e1de3f8 --- /dev/null +++ b/dts/bindings/cpu/phytium,ftc310.yaml @@ -0,0 +1,20 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +description: Phytium ftc310 arm CPU + +compatible: "phytium,ftc310" + +include: cpu.yaml \ No newline at end of file diff --git a/dts/bindings/cpu/phytium,ftc631.yaml b/dts/bindings/cpu/phytium,ftc631.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c4d2bcdcc3f48eff542084707bb2e88b774fa681 --- /dev/null +++ b/dts/bindings/cpu/phytium,ftc631.yaml @@ -0,0 +1,20 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +description: Phytium ftc310 arm CPU + +compatible: "phytium,ftc631" + +include: cpu.yaml \ No newline at end of file diff --git a/dts/bindings/ethernet/phytium,xmac.yaml b/dts/bindings/ethernet/phytium,xmac.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a17038ebbe8f60e4c00f91a034e0a7732809d06b --- /dev/null +++ b/dts/bindings/ethernet/phytium,xmac.yaml @@ -0,0 +1,233 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +description: Phytium xmac Ethernet controller + +compatible: "phytium,xmac" + +include: ethernet-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clock-frequency: + type: int + required: true + description: | + Specifies the base clock frequency from which the XMAC's TX clock + frequency . + + phy-poll-interval: + type: int + required: true + description: | + PHY status polling interval in milliseconds for a driver instance + managing an associated PHY. + + phy-speed: + type: int + required: true + description: | + Nominal link speed. If no PHY is managed by an instance of this driver, + the respective controller will be configured to match the link speed + specified here. If a PHY is managed by the driver, advertisement of + the link speed specified here will be requested. If the optional pro- + perty advertise-lower-link-speeds is set, advertisement of the link + speed specified here plus any valid link speed below this value will + be requested. + enum: + - 10 + - 100 + - 1000 + - 10000 + + + interface-mode: + type: int + required: true + description: | + Specifies the interface mode for the Xmac. Each mode corresponds to a different type of media-independent interface that determines how the Ethernet PHY is connected to the MAC. The available modes are: + - 0: SGMII (Serial Gigabit Media Independent Interface), a serial version of the Gigabit Media Independent Interface that is used for Gigabit Ethernet connections. + - 1: RMII (Reduced Media Independent Interface), a reduced version of the Media Independent Interface designed for 10/100Mbps Ethernet connections with a reduced number of signal lines. + - 2: RGMII (Reduced Gigabit Media Independent Interface), a version of the Gigabit Media Independent Interface designed for 10/100/1000Mbps Ethernet connections with a reduced number of signal lines. + - 3: USXGMII (Universal Serial 10 Gigabit Media Independent Interface), a serial interface designed for speeds beyond 1Gbps, supporting a range of speeds up to 10Gbps over a single pair of copper or optical fiber. + enum: + - 0 + - 1 + - 2 + - 3 + + + + dma-brust-length: + type: int + required: true + description: | + Defines the burst length for DMA (Direct Memory Access) operations in the Xmac driver. + The burst length specifies the maximum number of words the DMA controller can transfer in a single burst. + Adjusting this parameter can impact the efficiency of data transfers between the Ethernet MAC and the system memory, + potentially affecting overall throughput and latency. A value of 16 indicates that the DMA controller is configured to transfer up to 16 words in a single burst. + Choosing the optimal burst length depends on the specific characteristics of the system, including the DMA controller's capabilities and the memory system's response to burst accesses. + enum: + - 16 + + + max-queue-num: + type: int + required: true + description: | + Specifies the maximum number of queue slots available for managing Ethernet frames in the Xmac driver. + This parameter determines the capacity of the driver to handle multiple Ethernet frames concurrently, + which can influence the efficiency of packet processing, especially under high network traffic conditions. + A value of 1 indicates that the driver is configured to manage Ethernet frames using a single queue. + This configuration is suitable for simpler network setups or systems with lower traffic demands. + Implementing multiple queues can be advantageous in systems that require high throughput and efficient traffic management, + but this comes at the cost of increased complexity in queue management. + enum: + - 1 + + + phy-autonegotiation: + type: boolean + description: | + Determines whether the PHY (Physical Layer Transceiver) should use autonegotiation to automatically select the speed and duplex mode of the Ethernet connection. + When enabled (`true`), the PHY will communicate with the link partner (typically a switch, router, or another network device) to determine the best mutual settings for speed (10/100/1000 Mbps) and duplex mode (half or full duplex). + This process ensures compatibility and optimizes the connection for the best possible performance. + When disabled (`false`), the PHY will not initiate or respond to autonegotiation attempts, and the speed and duplex mode must be manually configured to match the link partner's settings, potentially reducing flexibility and compatibility. + + + enable-fdx: + type: boolean + description: | + Indicates whether the PHY (Physical Layer Transceiver) should operate in full-duplex mode. + In full-duplex mode (`true`), the Ethernet connection supports simultaneous bi-directional data transmission, allowing data to be sent and received at the same time, + effectively doubling the potential throughput compared to half-duplex. + This mode is ideal for high-speed networks where data collisions are managed and can significantly enhance network performance. + When set to `false`, the PHY operates in half-duplex mode, where data transmission and reception cannot occur simultaneously, + leading to a possible increase in data collisions and retransmissions, especially in high traffic conditions. + Selecting the appropriate duplex mode depends on network infrastructure, cable types, and the capabilities of the network devices involved in the connection. + + + enable-jumbo: + type: boolean + description: | + Specifies whether Jumbo Frames are enabled for the Ethernet device. Jumbo Frames are Ethernet frames with a payload greater than the standard maximum of 1500 bytes, + often up to 9000 bytes (9 KB). Enabling Jumbo Frames (`true`) can significantly increase data transfer efficiency by reducing the number of frames needed to transmit large amounts of data, + thereby decreasing CPU usage, increasing throughput, and improving network performance. + However, all devices in the network path must support Jumbo Frames to avoid fragmentation or dropped packets. + Disabling this feature (`false`) restricts the Ethernet frames to standard sizes, ensuring compatibility with network devices that do not support Jumbo Frames. + + + enable-ucast-hash: + type: boolean + description: | + Determines whether unicast hash filtering is enabled for the Ethernet device. + When activated (`true`), this feature allows the network interface to filter incoming unicast packets based on a hash function applied to the destination MAC address. + This mechanism is particularly useful in managing network traffic by ensuring that the Ethernet device processes only those unicast packets that match its hash criteria, + effectively reducing unnecessary packet processing and improving overall network efficiency. + This is beneficial in environments with high traffic levels or when the network interface is part of a larger, segmented network setup. + Disabling this feature (`false`) means the device will not use hash-based filtering for incoming unicast frames, + potentially leading to increased processing of irrelevant packets. + + + copy-all-frames: + type: boolean + description: | + Controls whether the Ethernet device is set to copy all incoming frames to system memory, + regardless of their destination MAC address. When enabled (`true`), + this feature instructs the device to pass all observed frames to the higher layers of the network stack, + effectively putting the network interface in a promiscuous mode. This mode is essential for network monitoring, + packet sniffing, and debugging tasks, where it's necessary to examine all traffic passing through the network segment the device is attached to. + However, it can lead to increased processing overhead due to the higher volume of data being passed up the stack. When disabled (`false`), + the device filters incoming frames, processing only those addressed to it or broadcast/multicast frames, + depending on its configuration, which is the normal operation mode for most network interfaces. + + + disable-reject-fcs-crc-errors: + type: boolean + description: | + Optional feature flag - Disable rejection of FCS/CRC errors. + When set, frames with FCS/CRC errors will not be rejected. FCS error + statistics will still be collected for frames with bad FCS and FCS + status will be recorded in the frame's DMA descriptor. This option + should not be activated for normal operation. + + enable-mcast-hash: + type: boolean + description: | + Enables multicast hash filtering for the Ethernet device. + When set to `true`, this feature allows the network interface to utilize a hash function on the destination MAC address of incoming multicast packets to determine if they should be passed to the system for processing. + This targeted approach helps manage multicast traffic more efficiently by ensuring the device processes only those multicast packets that match predefined criteria, + reducing unnecessary data processing and enhancing network throughput. This is especially beneficial in environments with substantial multicast traffic, such as multimedia streaming or multicast group communications. When disabled (`false`), + the device may not use hash-based filtering for multicast frames, which could result in increased processing of multicast packets that are not of interest to the receiving system. + + + handle-rx-in-isr: + type: boolean + description: | + Moves the handling of the frame received interrupt including the + transfer of packet data from the DMA to network packet buffers and + the subsequent propagation of the received packets to the network + stack into the context of the ISR. Due to the unpredictability of + the runtime of the ISR whenever large amounts of data are received, + handling of the RX interrupt is normally deferred to the context + of the system work queue. + + + handle-tx-in-workq: + type: boolean + description: | + Moves the handling of the frame transmission done interrupt into the + context of the system work queue. By default, TX done handling is per- + formed in the context of the ISR, as it only involves a limited number + of memory accesses. This option CAN NOT be used if any component ex- + ists within the current system setup that triggers the transmission + of packets from within the context of the system work queue! + + + rx-buffer-descriptors: + type: int + required: true + description: | + The number of descriptors to be allocated in the RX buffer descriptor + ring. Must be <= 255. + + + rx-buffer-size: + type: int + required: true + description: | + The size of each receive data buffer, must be a multiple of 8, highest + valid value is 16320, values less than 64 are not really useful. + + + tx-buffer-descriptors: + type: int + required: true + description: | + The number of descriptors to be allocated in the TX buffer descriptor + ring. Must be <= 255. + + tx-buffer-size: + type: int + required: true + description: | + The size of each transmit data buffer, highest valid value is 16380, + values less than 64 are not really useful. + diff --git a/dts/bindings/pinctrl/phytium,pinctrl.yaml b/dts/bindings/pinctrl/phytium,pinctrl.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3a2e5da838d3e9d2227fe1b473eaf659c3f7c16c --- /dev/null +++ b/dts/bindings/pinctrl/phytium,pinctrl.yaml @@ -0,0 +1,38 @@ + +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +description: | + Phytium pinctrl node + +compatible: "phytium,pinctrl" + +include: base.yaml + +properties: + reg: + required: true + +child-binding: + description: | + This binding gives a base representation of the Phytium + pin configuration. + + properties: + pinmux: + required: true + type: array + description: | + Phytium pin configuration. diff --git a/dts/bindings/sdhc/phytium,sdhc.yaml b/dts/bindings/sdhc/phytium,sdhc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..152f92213b68b765039b1dd54bb909ceda97d568 --- /dev/null +++ b/dts/bindings/sdhc/phytium,sdhc.yaml @@ -0,0 +1,61 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +description: Phytium SDHC controller + +compatible: "phytium,sdhc" + +include: [sdhc.yaml] + +properties: + reg: + required: true + + pio-id: + type: int + + default: 0 + description: | + pio id + + pio-base: + type: int + default: 0x28008000 + description: | + pio base + + pio-length: + type: int + default: 0x1000 + description: | + pio length + + is-enable-irq: + type: int + default: 1 + description: | + enable irq + + data-timeout: + type: int + default: 0xF + description: | + Data timeout, as multiple of the SD clock. See DTOCV field of USDHC + + no-1-8-v: + type: boolean + description: | + When the external SD card circuit does not support 1.8V, add this + property to disable 1.8v card voltage of SD card controller. diff --git a/dts/bindings/serial/arm,pl011.yaml b/dts/bindings/serial/arm,pl011.yaml index e823638ede0492eca7db306ab09f8e7fc8561a3c..80b4f2a7c18a78da20c173a93f2ecdebd6f308f9 100644 --- a/dts/bindings/serial/arm,pl011.yaml +++ b/dts/bindings/serial/arm,pl011.yaml @@ -10,3 +10,5 @@ properties: interrupts: required: true + + diff --git a/dts/bindings/serial/phytium,pl011.yaml b/dts/bindings/serial/phytium,pl011.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8b5804e7e4511ffc90c62b5c2428bd11773ea15d --- /dev/null +++ b/dts/bindings/serial/phytium,pl011.yaml @@ -0,0 +1,27 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +description: PHYTIUM PL011 UART + +compatible: "phytium,pl011" + +include: [uart-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true diff --git a/include/zephyr/arch/arm/arch.h b/include/zephyr/arch/arm/arch.h index a726bba8502adde60b6d6fa95f650e1f0fc5c36e..5dda2459cd72e19656776689aced5375b0bad317 100644 --- a/include/zephyr/arch/arm/arch.h +++ b/include/zephyr/arch/arm/arch.h @@ -40,7 +40,7 @@ #elif defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A) #include #include -#if defined(CONFIG_AARCH32_ARMV8_R) +#if defined(CONFIG_AARCH32_ARMV8_R) || defined(CONFIG_CPU_AARCH32_ARMV8) #include #include #else diff --git a/include/zephyr/arch/arm/cortex_a_r/cpu.h b/include/zephyr/arch/arm/cortex_a_r/cpu.h index 806d28247ac57d3c3e511a18e2d6e4a8a6c56c13..8848a042f35fe9dd894d3e78ce56ac3ec9514d0e 100644 --- a/include/zephyr/arch/arm/cortex_a_r/cpu.h +++ b/include/zephyr/arch/arm/cortex_a_r/cpu.h @@ -84,7 +84,7 @@ #define ICC_SRE_EL3_EN_BIT BIT(3) /* MPIDR */ -#define MPIDR_AFFLVL_MASK (0xff) +#define MPIDR_AFFLVL_MASK (0xfff) #define MPIDR_AFF0_SHIFT (0) #define MPIDR_AFF1_SHIFT (8) diff --git a/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld b/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld index a27dd55a8cf29ae9c4212dab18150d3be17716a3..2c1d07bf3cd82e3d18753530ab2abdcc7013252a 100644 --- a/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld +++ b/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld @@ -74,6 +74,7 @@ _region_min_align = 4; #endif #define BSS_ALIGN ALIGN(_region_min_align) +#define MMU_ALIGN . = ALIGN(_region_min_align) MEMORY { diff --git a/include/zephyr/dt-bindings/pinctrl/phytium-e2000q-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/phytium-e2000q-pinctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..9bf9b8a8fd9091bec72f05316fb91a7b24a0c2e0 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/phytium-e2000q-pinctrl.h @@ -0,0 +1,278 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +// +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/license/apache-2-0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_PHYTIUM_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_PHYTIUM_PINCTRL_H_ + +#define FIOPAD_AN59_REG0_OFFSET 0x0000U +#define FIOPAD_AW47_REG0_OFFSET 0x0004U +#define FIOPAD_AR55_REG0_OFFSET 0x0020U +#define FIOPAD_AJ55_REG0_OFFSET 0x0024U +#define FIOPAD_AL55_REG0_OFFSET 0x0028U +#define FIOPAD_AL53_REG0_OFFSET 0x002CU +#define FIOPAD_AN51_REG0_OFFSET 0x0030U +#define FIOPAD_AR51_REG0_OFFSET 0x0034U +#define FIOPAD_BA57_REG0_OFFSET 0x0038U +#define FIOPAD_BA59_REG0_OFFSET 0x003CU +#define FIOPAD_AW57_REG0_OFFSET 0x0040U +#define FIOPAD_AW59_REG0_OFFSET 0x0044U +#define FIOPAD_AU55_REG0_OFFSET 0x0048U +#define FIOPAD_AN57_REG0_OFFSET 0x004CU +#define FIOPAD_AL59_REG0_OFFSET 0x0050U +#define FIOPAD_AJ59_REG0_OFFSET 0x0054U +#define FIOPAD_AJ57_REG0_OFFSET 0x0058U +#define FIOPAD_AG59_REG0_OFFSET 0x005CU +#define FIOPAD_AG57_REG0_OFFSET 0x0060U +#define FIOPAD_AE59_REG0_OFFSET 0x0064U +#define FIOPAD_AC59_REG0_OFFSET 0x0068U +#define FIOPAD_AC57_REG0_OFFSET 0x006CU +#define FIOPAD_AR49_REG0_OFFSET 0x0070U +#define FIOPAD_BA55_REG0_OFFSET 0x0074U +#define FIOPAD_BA53_REG0_OFFSET 0x0078U +#define FIOPAD_AR59_REG0_OFFSET 0x007CU +#define FIOPAD_AU59_REG0_OFFSET 0x0080U +#define FIOPAD_AR57_REG0_OFFSET 0x0084U +#define FIOPAD_BA49_REG0_OFFSET 0x0088U +#define FIOPAD_AW55_REG0_OFFSET 0x008CU +#define FIOPAD_A35_REG0_OFFSET 0x0090U +#define FIOPAD_R57_REG0_OFFSET 0x0094U +#define FIOPAD_R59_REG0_OFFSET 0x0098U +#define FIOPAD_U59_REG0_OFFSET 0x009CU +#define FIOPAD_W59_REG0_OFFSET 0x00A0U +#define FIOPAD_U57_REG0_OFFSET 0x00A4U +#define FIOPAD_AA57_REG0_OFFSET 0x00A8U +#define FIOPAD_AA59_REG0_OFFSET 0x00ACU +#define FIOPAD_AW51_REG0_OFFSET 0x00B0U +#define FIOPAD_AU51_REG0_OFFSET 0x00B4U +#define FIOPAD_A39_REG0_OFFSET 0x00B8U +#define FIOPAD_C39_REG0_OFFSET 0x00BCU +#define FIOPAD_C37_REG0_OFFSET 0x00C0U +#define FIOPAD_A37_REG0_OFFSET 0x00C4U +#define FIOPAD_A41_REG0_OFFSET 0x00C8U +#define FIOPAD_A43_REG0_OFFSET 0x00CCU +#define FIOPAD_A45_REG0_OFFSET 0x00D0U +#define FIOPAD_C45_REG0_OFFSET 0x00D4U +#define FIOPAD_A47_REG0_OFFSET 0x00D8U +#define FIOPAD_A49_REG0_OFFSET 0x00DCU +#define FIOPAD_C49_REG0_OFFSET 0x00E0U +#define FIOPAD_A51_REG0_OFFSET 0x00E4U +#define FIOPAD_A33_REG0_OFFSET 0x00E8U +#define FIOPAD_C33_REG0_OFFSET 0x00ECU +#define FIOPAD_C31_REG0_OFFSET 0x00F0U +#define FIOPAD_A31_REG0_OFFSET 0x00F4U +#define FIOPAD_AJ53_REG0_OFFSET 0x00F8U +#define FIOPAD_AL49_REG0_OFFSET 0x00FCU +#define FIOPAD_AL47_REG0_OFFSET 0x0100U +#define FIOPAD_AN49_REG0_OFFSET 0x0104U +#define FIOPAD_AG51_REG0_OFFSET 0x0108U +#define FIOPAD_AJ51_REG0_OFFSET 0x010CU +#define FIOPAD_AG49_REG0_OFFSET 0x0110U +#define FIOPAD_AE55_REG0_OFFSET 0x0114U +#define FIOPAD_AE53_REG0_OFFSET 0x0118U +#define FIOPAD_AG55_REG0_OFFSET 0x011CU +#define FIOPAD_AJ49_REG0_OFFSET 0x0120U +#define FIOPAD_AC55_REG0_OFFSET 0x0124U +#define FIOPAD_AC53_REG0_OFFSET 0x0128U +#define FIOPAD_AE51_REG0_OFFSET 0x012CU +#define FIOPAD_W51_REG0_OFFSET 0x0130U +#define FIOPAD_W55_REG0_OFFSET 0x0134U +#define FIOPAD_W53_REG0_OFFSET 0x0138U +#define FIOPAD_U55_REG0_OFFSET 0x013CU +#define FIOPAD_U53_REG0_OFFSET 0x0140U +#define FIOPAD_AE49_REG0_OFFSET 0x0144U +#define FIOPAD_AC49_REG0_OFFSET 0x0148U +#define FIOPAD_AE47_REG0_OFFSET 0x014CU +#define FIOPAD_AA47_REG0_OFFSET 0x0150U +#define FIOPAD_AA49_REG0_OFFSET 0x0154U +#define FIOPAD_W49_REG0_OFFSET 0x0158U +#define FIOPAD_AA51_REG0_OFFSET 0x015CU +#define FIOPAD_U49_REG0_OFFSET 0x0160U +#define FIOPAD_G59_REG0_OFFSET 0x0164U +#define FIOPAD_J59_REG0_OFFSET 0x0168U +#define FIOPAD_L57_REG0_OFFSET 0x016CU +#define FIOPAD_C59_REG0_OFFSET 0x0170U +#define FIOPAD_E59_REG0_OFFSET 0x0174U +#define FIOPAD_J57_REG0_OFFSET 0x0178U +#define FIOPAD_L59_REG0_OFFSET 0x017CU +#define FIOPAD_N59_REG0_OFFSET 0x0180U +#define FIOPAD_C57_REG0_OFFSET 0x0184U +#define FIOPAD_E57_REG0_OFFSET 0x0188U +#define FIOPAD_E31_REG0_OFFSET 0x018CU +#define FIOPAD_G31_REG0_OFFSET 0x0190U +#define FIOPAD_N41_REG0_OFFSET 0x0194U +#define FIOPAD_N39_REG0_OFFSET 0x0198U +#define FIOPAD_J33_REG0_OFFSET 0x019CU +#define FIOPAD_N33_REG0_OFFSET 0x01A0U +#define FIOPAD_L33_REG0_OFFSET 0x01A4U +#define FIOPAD_N45_REG0_OFFSET 0x01A8U +#define FIOPAD_N43_REG0_OFFSET 0x01ACU +#define FIOPAD_L31_REG0_OFFSET 0x01B0U +#define FIOPAD_J31_REG0_OFFSET 0x01B4U +#define FIOPAD_J29_REG0_OFFSET 0x01B8U +#define FIOPAD_E29_REG0_OFFSET 0x01BCU +#define FIOPAD_G29_REG0_OFFSET 0x01C0U +#define FIOPAD_N27_REG0_OFFSET 0x01C4U +#define FIOPAD_L29_REG0_OFFSET 0x01C8U +#define FIOPAD_J37_REG0_OFFSET 0x01CCU +#define FIOPAD_J39_REG0_OFFSET 0x01D0U +#define FIOPAD_G41_REG0_OFFSET 0x01D4U +#define FIOPAD_E43_REG0_OFFSET 0x01D8U +#define FIOPAD_L43_REG0_OFFSET 0x01DCU +#define FIOPAD_C43_REG0_OFFSET 0x01E0U +#define FIOPAD_E41_REG0_OFFSET 0x01E4U +#define FIOPAD_L45_REG0_OFFSET 0x01E8U +#define FIOPAD_J43_REG0_OFFSET 0x01ECU +#define FIOPAD_J41_REG0_OFFSET 0x01F0U +#define FIOPAD_L39_REG0_OFFSET 0x01F4U +#define FIOPAD_E37_REG0_OFFSET 0x01F8U +#define FIOPAD_E35_REG0_OFFSET 0x01FCU +#define FIOPAD_G35_REG0_OFFSET 0x0200U +#define FIOPAD_J35_REG0_OFFSET 0x0204U +#define FIOPAD_L37_REG0_OFFSET 0x0208U +#define FIOPAD_N35_REG0_OFFSET 0x020CU +#define FIOPAD_R51_REG0_OFFSET 0x0210U +#define FIOPAD_R49_REG0_OFFSET 0x0214U +#define FIOPAD_N51_REG0_OFFSET 0x0218U +#define FIOPAD_N55_REG0_OFFSET 0x021CU +#define FIOPAD_L55_REG0_OFFSET 0x0220U +#define FIOPAD_J55_REG0_OFFSET 0x0224U +#define FIOPAD_J45_REG0_OFFSET 0x0228U +#define FIOPAD_E47_REG0_OFFSET 0x022CU +#define FIOPAD_G47_REG0_OFFSET 0x0230U +#define FIOPAD_J47_REG0_OFFSET 0x0234U +#define FIOPAD_J49_REG0_OFFSET 0x0238U +#define FIOPAD_N49_REG0_OFFSET 0x023CU +#define FIOPAD_L51_REG0_OFFSET 0x0240U +#define FIOPAD_L49_REG0_OFFSET 0x0244U +#define FIOPAD_N53_REG0_OFFSET 0x0248U +#define FIOPAD_J53_REG0_OFFSET 0x024CU + +#define FIOPAD_REG0_BEG_OFFSET FIOPAD_AN59_REG0_OFFSET +#define FIOPAD_REG0_END_OFFSET FIOPAD_J53_REG0_OFFSET + +/* register offset of iopad delay */ +#define FIOPAD_AJ55_REG1_OFFSET 0x1024U +#define FIOPAD_AL55_REG1_OFFSET 0x1028U +#define FIOPAD_AL53_REG1_OFFSET 0x102CU +#define FIOPAD_AN51_REG1_OFFSET 0x1030U +#define FIOPAD_AR51_REG1_OFFSET 0x1034U +#define FIOPAD_AJ57_REG1_OFFSET 0x1058U +#define FIOPAD_AG59_REG1_OFFSET 0x105CU +#define FIOPAD_AG57_REG1_OFFSET 0x1060U +#define FIOPAD_AE59_REG1_OFFSET 0x1064U +#define FIOPAD_BA55_REG1_OFFSET 0x1074U +#define FIOPAD_BA53_REG1_OFFSET 0x1078U +#define FIOPAD_AR59_REG1_OFFSET 0x107CU +#define FIOPAD_AU59_REG1_OFFSET 0x1080U +#define FIOPAD_A45_REG1_OFFSET 0x10D0U +#define FIOPAD_C45_REG1_OFFSET 0x10D4U +#define FIOPAD_A47_REG1_OFFSET 0x10D8U +#define FIOPAD_A49_REG1_OFFSET 0x10DCU +#define FIOPAD_C49_REG1_OFFSET 0x10E0U +#define FIOPAD_A51_REG1_OFFSET 0x10E4U +#define FIOPAD_A33_REG1_OFFSET 0x10E8U +#define FIOPAD_C33_REG1_OFFSET 0x10ECU +#define FIOPAD_C31_REG1_OFFSET 0x10F0U +#define FIOPAD_A31_REG1_OFFSET 0x10F4U +#define FIOPAD_AJ53_REG1_OFFSET 0x10F8U +#define FIOPAD_AL49_REG1_OFFSET 0x10FCU +#define FIOPAD_AL47_REG1_OFFSET 0x1100U +#define FIOPAD_AN49_REG1_OFFSET 0x1104U +#define FIOPAD_AG51_REG1_OFFSET 0x1108U +#define FIOPAD_AJ51_REG1_OFFSET 0x110CU +#define FIOPAD_AG49_REG1_OFFSET 0x1110U +#define FIOPAD_AE55_REG1_OFFSET 0x1114U +#define FIOPAD_AE53_REG1_OFFSET 0x1118U +#define FIOPAD_AG55_REG1_OFFSET 0x111CU +#define FIOPAD_AJ49_REG1_OFFSET 0x1120U +#define FIOPAD_AC55_REG1_OFFSET 0x1124U +#define FIOPAD_AC53_REG1_OFFSET 0x1128U +#define FIOPAD_AE51_REG1_OFFSET 0x112CU +#define FIOPAD_W51_REG1_OFFSET 0x1130U +#define FIOPAD_W53_REG1_OFFSET 0x1138U +#define FIOPAD_U55_REG1_OFFSET 0x113CU +#define FIOPAD_U53_REG1_OFFSET 0x1140U +#define FIOPAD_AE49_REG1_OFFSET 0x1144U +#define FIOPAD_AC49_REG1_OFFSET 0x1148U +#define FIOPAD_AE47_REG1_OFFSET 0x114CU +#define FIOPAD_AA47_REG1_OFFSET 0x1150U +#define FIOPAD_AA49_REG1_OFFSET 0x1154U +#define FIOPAD_W49_REG1_OFFSET 0x1158U +#define FIOPAD_AA51_REG1_OFFSET 0x115CU +#define FIOPAD_U49_REG1_OFFSET 0x1160U +#define FIOPAD_J59_REG1_OFFSET 0x1168U +#define FIOPAD_L57_REG1_OFFSET 0x116CU +#define FIOPAD_C59_REG1_OFFSET 0x1170U +#define FIOPAD_E59_REG1_OFFSET 0x1174U +#define FIOPAD_J57_REG1_OFFSET 0x1178U +#define FIOPAD_L59_REG1_OFFSET 0x117CU +#define FIOPAD_N59_REG1_OFFSET 0x1180U +#define FIOPAD_E31_REG1_OFFSET 0x118CU +#define FIOPAD_G31_REG1_OFFSET 0x1190U +#define FIOPAD_N41_REG1_OFFSET 0x1194U +#define FIOPAD_N39_REG1_OFFSET 0x1198U +#define FIOPAD_J33_REG1_OFFSET 0x119CU +#define FIOPAD_N33_REG1_OFFSET 0x11A0U +#define FIOPAD_L33_REG1_OFFSET 0x11A4U +#define FIOPAD_N45_REG1_OFFSET 0x11A8U +#define FIOPAD_N43_REG1_OFFSET 0x11ACU +#define FIOPAD_L31_REG1_OFFSET 0x11B0U +#define FIOPAD_J31_REG1_OFFSET 0x11B4U +#define FIOPAD_J29_REG1_OFFSET 0x11B8U +#define FIOPAD_E29_REG1_OFFSET 0x11BCU +#define FIOPAD_G29_REG1_OFFSET 0x11C0U +#define FIOPAD_J37_REG1_OFFSET 0x11CCU +#define FIOPAD_J39_REG1_OFFSET 0x11D0U +#define FIOPAD_G41_REG1_OFFSET 0x11D4U +#define FIOPAD_E43_REG1_OFFSET 0x11D8U +#define FIOPAD_L43_REG1_OFFSET 0x11DCU +#define FIOPAD_C43_REG1_OFFSET 0x11E0U +#define FIOPAD_E41_REG1_OFFSET 0x11E4U +#define FIOPAD_L45_REG1_OFFSET 0x11E8U +#define FIOPAD_J43_REG1_OFFSET 0x11ECU +#define FIOPAD_J41_REG1_OFFSET 0x11F0U +#define FIOPAD_L39_REG1_OFFSET 0x11F4U +#define FIOPAD_E37_REG1_OFFSET 0x11F8U +#define FIOPAD_E35_REG1_OFFSET 0x11FCU +#define FIOPAD_G35_REG1_OFFSET 0x1200U +#define FIOPAD_L55_REG1_OFFSET 0x1220U +#define FIOPAD_J55_REG1_OFFSET 0x1224U +#define FIOPAD_J45_REG1_OFFSET 0x1228U +#define FIOPAD_E47_REG1_OFFSET 0x122CU +#define FIOPAD_G47_REG1_OFFSET 0x1230U +#define FIOPAD_J47_REG1_OFFSET 0x1234U +#define FIOPAD_J49_REG1_OFFSET 0x1238U +#define FIOPAD_N49_REG1_OFFSET 0x123CU +#define FIOPAD_L51_REG1_OFFSET 0x1240U +#define FIOPAD_L49_REG1_OFFSET 0x1244U +#define FIOPAD_N53_REG1_OFFSET 0x1248U +#define FIOPAD_J53_REG1_OFFSET 0x124CU + +#define FIOPAD_REG1_BEG_OFFSET FIOPAD_AJ55_REG1_OFFSET +#define FIOPAD_REG1_END_OFFSET FIOPAD_J53_REG1_OFFSET + + +#define FIOPAD_FUNC0 0x0 +#define FIOPAD_FUNC1 0x1 +#define FIOPAD_FUNC2 0x2 +#define FIOPAD_FUNC3 0x3 +#define FIOPAD_FUNC4 0x4 +#define FIOPAD_FUNC5 0x5 +#define FIOPAD_FUNC6 0x6 +#define FIOPAD_FUNC7 0x7 + +#define PHYTIUM_PINMUX(pin_reg_offset, func_num) (pin_reg_offset) (func_num) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_TI_K3_PINCTRL_H_ */ diff --git a/makefile b/makefile new file mode 100644 index 0000000000000000000000000000000000000000..0aa37f3c41ddec51ec3b6712bcf57db75325b511 --- /dev/null +++ b/makefile @@ -0,0 +1,28 @@ + + +boot_smp: + west build -b e2000q_demo_smp samples/arch/smp/pktqueue + cp ./build/zephyr/zephyr.elf /mnt/d/tftboot/ + +boot: + west build -b e2000q_demo samples/hello_world + cp ./build/zephyr/zephyr.elf /mnt/d/tftboot/ + +menuconfig: + west build -t menuconfig + +boot_gdb: + west build -b qemu_cortex_a53_smp samples/arch/smp/pi + +clean: + west build -t clean + +debug_qemu: + west build -t debugserver_qemu + +gdb: + gdb-multiarch -x .gdbinit + + +gdb_qemu: + gdb-multiarch -x .gitlint_qemu \ No newline at end of file diff --git a/modules/Kconfig b/modules/Kconfig index 687ce19da818abf831e6ea011517c990a6621763..9b1110d337945d3b446f1067d58b7ccaf8c9bd63 100644 --- a/modules/Kconfig +++ b/modules/Kconfig @@ -45,6 +45,7 @@ source "modules/Kconfig.xtensa" source "modules/zcbor/Kconfig" source "modules/Kconfig.mcuboot" source "modules/Kconfig.intel" +source "modules/Kconfig.phytium" comment "Unavailable modules, please install those via the project manifest." diff --git a/modules/Kconfig.phytium b/modules/Kconfig.phytium new file mode 100644 index 0000000000000000000000000000000000000000..ca36693353a4198591ed5a9411fd08557468d367 --- /dev/null +++ b/modules/Kconfig.phytium @@ -0,0 +1,52 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +config PHYTIUM_SOFT + bool + +config PHYTIUM_STANDALONE_SDK + bool + depends on PHYTIUM_SOFT + +if PHYTIUM_STANDALONE_SDK + +config USE_SERIAL + bool + prompt "Use serial" + default y + help + Include serial modules and enable serial + +if USE_SERIAL + config ENABLE_Pl011_UART + bool + prompt "Use Pl011 uart" + default y +endif + +config USE_SDHC + bool + prompt "Use SDHC" + default y + +if USE_SDHC + config ENABLE_PHYTIUM_SDHC + bool + prompt "Use phytium sdhc" + default y + +endif + +endif \ No newline at end of file diff --git a/samples/arch/smp/pktqueue/src/main.h b/samples/arch/smp/pktqueue/src/main.h index 20020563ca1641d939ed5aea95e1b443891581e4..34ac6f475a0c387b1880c896341e6e99bd727c2c 100644 --- a/samples/arch/smp/pktqueue/src/main.h +++ b/samples/arch/smp/pktqueue/src/main.h @@ -29,4 +29,4 @@ #define CRC_BYTE_1 10 #define CRC_BYTE_2 11 -#define STACK_SIZE 2048 +#define STACK_SIZE 4096 diff --git a/soc/arm/phytium_e2000/CMakeLists.txt b/soc/arm/phytium_e2000/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2884c89fcc6884319943c4e56161ee5eab4092e6 --- /dev/null +++ b/soc/arm/phytium_e2000/CMakeLists.txt @@ -0,0 +1,17 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +add_subdirectory(${SOC_SERIES}) + diff --git a/soc/arm/phytium_e2000/Kconfig b/soc/arm/phytium_e2000/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..f8733577f1e643f0a29530f00d3feb9191d3b756 --- /dev/null +++ b/soc/arm/phytium_e2000/Kconfig @@ -0,0 +1,31 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +config SOC_FAMILY_PHYTIUM_E2000 + bool + +if SOC_FAMILY_PHYTIUM_E2000 + +config SOC_FAMILY + string + default "phytium_e2000" + +source "soc/arm/phytium_e2000/*/Kconfig.soc" + +config TEST_EXTRA_STACK_SIZE + default 2048 + + +endif # SOC_FAMILY_PHYTIUM_E2000 diff --git a/soc/arm/phytium_e2000/Kconfig.defconfig b/soc/arm/phytium_e2000/Kconfig.defconfig new file mode 100644 index 0000000000000000000000000000000000000000..bafc96471fe29ecc875394c425b3e5970b25d1cf --- /dev/null +++ b/soc/arm/phytium_e2000/Kconfig.defconfig @@ -0,0 +1,31 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +source "soc/arm/phytium_e2000/*/Kconfig.defconfig.series" + +config FLASH_SIZE + default 256 + +config FLASH_BASE_ADDRESS + default 0 + +if SOC_FAMILY_PHYTIUM_E2000 + +config NUM_IRQS + int + # must be >= the highest interrupt number used + default 256 + +endif # SOC_FAMILY_PHYTIUM_E2000 diff --git a/soc/arm/phytium_e2000/Kconfig.soc b/soc/arm/phytium_e2000/Kconfig.soc new file mode 100644 index 0000000000000000000000000000000000000000..e74ce47d90de7f809ccf04be573d29c926c24a1f --- /dev/null +++ b/soc/arm/phytium_e2000/Kconfig.soc @@ -0,0 +1,17 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + + +source "soc/arm/phytium_e2000/*/Kconfig.series" diff --git a/soc/arm/phytium_e2000/e2000q/CMakeLists.txt b/soc/arm/phytium_e2000/e2000q/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..ccf3e57d599a7e24d20a3e6be09ec0388c4f0afe --- /dev/null +++ b/soc/arm/phytium_e2000/e2000q/CMakeLists.txt @@ -0,0 +1,16 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +zephyr_sources(soc.c) diff --git a/soc/arm/phytium_e2000/e2000q/Kconfig.defconfig.e2000q b/soc/arm/phytium_e2000/e2000q/Kconfig.defconfig.e2000q new file mode 100644 index 0000000000000000000000000000000000000000..1c630ae55e642c7dab6c1537fc500f8096ea7092 --- /dev/null +++ b/soc/arm/phytium_e2000/e2000q/Kconfig.defconfig.e2000q @@ -0,0 +1,18 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +#config SOC +# default "E2000Q" +# depends on SOC_PHYTIUM_E2000Q diff --git a/soc/arm/phytium_e2000/e2000q/Kconfig.defconfig.series b/soc/arm/phytium_e2000/e2000q/Kconfig.defconfig.series new file mode 100644 index 0000000000000000000000000000000000000000..84cf93619b8a475dca5717f4bf3a3a2a2fc8c051 --- /dev/null +++ b/soc/arm/phytium_e2000/e2000q/Kconfig.defconfig.series @@ -0,0 +1,30 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +if SOC_SERIES_PHYTIUM_E2000Q + +rsource "Kconfig.defconfig.e2000q" + +config SOC_SERIES + default "e2000q" + +# Zephyr does not support SMP on aarch32 yet, so we default to 1 CPU core +config MP_MAX_NUM_CPUS + default 1 + + + + +endif # SOC_SERIES_PHYTIUM_E2000Q diff --git a/soc/arm/phytium_e2000/e2000q/Kconfig.series b/soc/arm/phytium_e2000/e2000q/Kconfig.series new file mode 100644 index 0000000000000000000000000000000000000000..9f74de2806f53ccb85189eb9e5d85a868627c2cb --- /dev/null +++ b/soc/arm/phytium_e2000/e2000q/Kconfig.series @@ -0,0 +1,31 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +config SOC_SERIES_PHYTIUM_E2000Q + bool "Phytium E2000 Soc series" + select SOC_FAMILY_PHYTIUM_E2000 + select ARM + select CPU_PHYTIUM_FT310 + select PLATFORM_SPECIFIC_INIT + select GIC_SINGLE_SECURITY_STATE + select CACHE_MANAGEMENT + select AARCH64_2_AARCH32 + select PHYTIUM_STANDALONE_SDK + select PHYTIUM_SOFT + #select CPU_HAS_FPU + select VFP_DP_D16 + help + Enable support for the Phytium e2000q + SoC series (4-core Armv8 cpu). diff --git a/soc/arm/phytium_e2000/e2000q/Kconfig.soc b/soc/arm/phytium_e2000/e2000q/Kconfig.soc new file mode 100644 index 0000000000000000000000000000000000000000..bf78726f984c0a963bed69bee908a8508815213a --- /dev/null +++ b/soc/arm/phytium_e2000/e2000q/Kconfig.soc @@ -0,0 +1,41 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +# +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# https://opensource.org/license/apache-2-0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +#choice +# prompt "E2000 SoC Selection" +# depends on SOC_SERIES_PHYTIUM_E2000Q +# default SOC_PHYTIUM_E2000Q + +config SOC_PHYTIUM_E2000Q + bool "E2000Q_AARCH32" + help + e2000q + + +config HAL_STANDALONE_SDK_DEBUG + bool "standalone_sdk_debug" + + + +#endchoice + +if NETWORKING + +config NET_L2_ETHERNET + default y + + + +endif # NETWORKING diff --git a/soc/arm/phytium_e2000/e2000q/linker.ld b/soc/arm/phytium_e2000/e2000q/linker.ld new file mode 100644 index 0000000000000000000000000000000000000000..1a59fc546a24670957c90308d262a64e72720cf0 --- /dev/null +++ b/soc/arm/phytium_e2000/e2000q/linker.ld @@ -0,0 +1,16 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +// +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/license/apache-2-0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include diff --git a/soc/arm/phytium_e2000/e2000q/soc.c b/soc/arm/phytium_e2000/e2000q/soc.c new file mode 100644 index 0000000000000000000000000000000000000000..e03d37e8511b7a504a628e2f7484ccbcc76c1244 --- /dev/null +++ b/soc/arm/phytium_e2000/e2000q/soc.c @@ -0,0 +1,57 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +// +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/license/apache-2-0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include +#include +#include +extern void *_vector_table[]; + + +static const struct arm_mmu_region mmu_regions[] = { + MMU_REGION_FLAT_ENTRY("GIC", + DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 0), + DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 0), + MT_DEVICE | MATTR_SHARED | MPERM_R | MPERM_W), + + MMU_REGION_FLAT_ENTRY("GIC", + DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 1), + DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 1), + MT_DEVICE | MATTR_SHARED | MPERM_R | MPERM_W), + +}; + +const struct arm_mmu_config mmu_config = { + .num_regions = ARRAY_SIZE(mmu_regions), + .mmu_regions = mmu_regions, +}; + + +void z_arm_platform_init(void) +{ + /* + * Use normal exception vectors address range (0x0-0x1C). + */ + unsigned int sctlr; + + __set_VBAR(_vector_table); + + sctlr = 0; + __set_SCTLR(sctlr); +} + +void relocate_vector_table(void) +{ + +} \ No newline at end of file diff --git a/soc/arm/phytium_e2000/e2000q/soc.h b/soc/arm/phytium_e2000/e2000q/soc.h new file mode 100644 index 0000000000000000000000000000000000000000..061ed3d7ea850a64f5bde5955ff22eee59a649bd --- /dev/null +++ b/soc/arm/phytium_e2000/e2000q/soc.h @@ -0,0 +1,22 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +// +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/license/apache-2-0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef _BOARD__H_ +#define _BOARD__H_ + +/* Define CMSIS configurations */ +#define __GIC_PRESENT 0 +#define __TIM_PRESENT 0 +#endif /* _BOARD__H_ */ diff --git a/soc/arm64/e2000q/CMakeLists.txt b/soc/arm64/e2000q/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..f80b4f3524eccf312cba2b9483f057a50d89dc66 --- /dev/null +++ b/soc/arm64/e2000q/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +zephyr_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) +zephyr_sources( + soc.c +) +zephyr_include_directories(.) \ No newline at end of file diff --git a/soc/arm64/e2000q/Kconfig.defconfig b/soc/arm64/e2000q/Kconfig.defconfig new file mode 100644 index 0000000000000000000000000000000000000000..d1bdd2b525d3ef62d5c9c0a1eb43921432ba3c2e --- /dev/null +++ b/soc/arm64/e2000q/Kconfig.defconfig @@ -0,0 +1,29 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. + +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at + +# https://opensource.org/license/apache-2-0 + +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +if SOC_E2000Q + +config SOC + default "e2000q" + +config NUM_IRQS + int + default 266 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + int + default 50000000 + +endif diff --git a/soc/arm64/e2000q/Kconfig.soc b/soc/arm64/e2000q/Kconfig.soc new file mode 100644 index 0000000000000000000000000000000000000000..4597a2a9e0d1ed87372cc2d102c1c0e9c77a6af2 --- /dev/null +++ b/soc/arm64/e2000q/Kconfig.soc @@ -0,0 +1,28 @@ +# Phytium is pleased to support the open source community by making Zephyr-SDK available. + +# +# Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. + +# Licensed under the Apache-2.0 License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at + +# https://opensource.org/license/apache-2-0 + +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. + +config SOC_E2000Q + bool "e2000q" + select ARM64 + select CPU_CORTEX_A53 + select ARM_ARCH_TIMER if SYS_CLOCK_EXISTS + select PHYTIUM_STANDALONE_SDK + select PHYTIUM_SOFT + +if SOC_E2000Q +config HAL_STANDALONE_SDK_DEBUG + bool "standalone_sdk_debug" + +endif \ No newline at end of file diff --git a/soc/arm64/e2000q/linker.ld b/soc/arm64/e2000q/linker.ld new file mode 100644 index 0000000000000000000000000000000000000000..8a59f8d9efb4547eb71acbf614568644e9d0e6bb --- /dev/null +++ b/soc/arm64/e2000q/linker.ld @@ -0,0 +1,16 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + + +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. + +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at + +// https://opensource.org/license/apache-2-0 + +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include diff --git a/soc/arm64/e2000q/linker_a53.ld b/soc/arm64/e2000q/linker_a53.ld new file mode 100644 index 0000000000000000000000000000000000000000..409cf76879e78c4faf902198d90a5be32e22ec78 --- /dev/null +++ b/soc/arm64/e2000q/linker_a53.ld @@ -0,0 +1,16 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + + +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. + +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at + +// https://opensource.org/license/apache-2-0 + +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include diff --git a/soc/arm64/e2000q/mmu_regions.c b/soc/arm64/e2000q/mmu_regions.c new file mode 100644 index 0000000000000000000000000000000000000000..5f2a0000ad8a916b452bffe0c3425891b7951862 --- /dev/null +++ b/soc/arm64/e2000q/mmu_regions.c @@ -0,0 +1,38 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. + +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at + +// https://opensource.org/license/apache-2-0 + +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include +#include +#include + +static const struct arm_mmu_region mmu_regions[] = { + MMU_REGION_FLAT_ENTRY("GIC", + DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 0), + DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 0), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), + + MMU_REGION_FLAT_ENTRY("GIC", + DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 1), + DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 1), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), +}; + +const struct arm_mmu_config mmu_config = { + .num_regions = ARRAY_SIZE(mmu_regions), + .mmu_regions = mmu_regions, +}; + + + diff --git a/soc/arm64/e2000q/pinctrl_soc.h b/soc/arm64/e2000q/pinctrl_soc.h new file mode 100644 index 0000000000000000000000000000000000000000..bff54a600c10b46807b47bc87d8c3fbe1e9210e5 --- /dev/null +++ b/soc/arm64/e2000q/pinctrl_soc.h @@ -0,0 +1,51 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. +// +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/license/apache-2-0 +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef ZEPHYR_SOC_ARM64_PHYTIUM_E2000_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM64_PHYTIUM_E2000_PINCTRL_SOC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct pinctrl_soc_pin { + + uint32_t pin_reg_offset; + uint32_t func_num; +}; + +typedef struct pinctrl_soc_pin pinctrl_soc_pin_t; + +#define PHYTIUM_E2000_DT_PIN(node_id) \ + { \ + .pin_reg_offset = DT_PROP_BY_IDX(node_id, pinmux, 0), \ + .func_num = DT_PROP_BY_IDX(node_id, pinmux, 1) \ + }, + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + PHYTIUM_E2000_DT_PIN(DT_PROP_BY_IDX(node_id, prop, idx)) + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + { DT_FOREACH_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT) } + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/soc/arm64/e2000q/soc.c b/soc/arm64/e2000q/soc.c new file mode 100644 index 0000000000000000000000000000000000000000..839b79b83430aa9f86f13330d50fc5a2583184e7 --- /dev/null +++ b/soc/arm64/e2000q/soc.c @@ -0,0 +1,30 @@ +// Phytium is pleased to support the open source community by making Zephyr-SDK available. + +// +// Copyright (C) 2024 Phytium Technology Co., Ltd. All rights reserved. + +// Licensed under the Apache-2.0 License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at + +// https://opensource.org/license/apache-2-0 + +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include +#include +#include +#include +#include +#include + +#include + +/* Boot-time static default printk handler, possibly to be overridden later. */ +int arch_printk_char_out(int c) +{ + putchar(c) ; + return 0; +} \ No newline at end of file diff --git a/subsys/sd/sd.c b/subsys/sd/sd.c index 87ec7a29910a7ad0d0a706cb6d547025a0b12950..bde72ee792508d062994cf23a015a529b4e75f40 100644 --- a/subsys/sd/sd.c +++ b/subsys/sd/sd.c @@ -206,6 +206,7 @@ static int sd_command_init(struct sd_card *card) } #endif /* CONFIG_SDIO_STACK */ #ifdef CONFIG_SDMMC_STACK + LOG_DBG("sdmmc_card_init is start"); /* Attempt to initialize SDMMC card */ if (!sdmmc_card_init(card)) { return 0; @@ -258,7 +259,7 @@ int sd_init(const struct device *sdhc_dev, struct sd_card *card) k_mutex_unlock(&card->lock); return ret; } - + LOG_DBG("start sd_command_init"); /* * SD protocol is stateful, so we must account for the possibility * that the card is in a bad state. The return code SD_RESTART diff --git a/west.yml b/west.yml index 8866ec48a78394927715cbbec4e71c8f80ec463f..0f21305c7ca7695f531f197bbc2615f741ec17ca 100644 --- a/west.yml +++ b/west.yml @@ -23,6 +23,8 @@ manifest: url-base: https://github.com/zephyrproject-rtos - name: babblesim url-base: https://github.com/BabbleSim + - name: phytium + url-base: https://gitee.com/phytium_embedded group-filter: [-babblesim, -optional] @@ -336,6 +338,12 @@ manifest: - name: zcbor revision: 67fd8bb88d3136738661fa8bb5f9989103f4599e path: modules/lib/zcbor + - name: phytium-standalone-sdk + remote: phytium + revision: 0f31ca6f028af44e999e986157388f655d1f528e + path: modules/hal/phytium/hal/phytium-standalone-sdk + groups: + - hal self: path: zephyr