From cf5e9e8a5426e75a9bc02e6d5f5551cc65be6ed6 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 6 Jun 2023 18:04:15 +0200 Subject: [PATCH 39/41] example: adding sample code for ethernet This include: - CR52 initialization taken from MCAL - serdes initialization taken from MCAL and compared against the User Manual Signed-off-by: Valerio Setti --- .../cortex-a/armv8/spider/ethernet/build.sh | 15 + .../armv8/spider/ethernet/err_codes.h | 6 + .../cortex-a/armv8/spider/ethernet/eth.oil | 80 ++++ .../armv8/spider/ethernet/eth_serdes.c | 357 ++++++++++++++++++ .../armv8/spider/ethernet/eth_serdes.h | 7 + .../cortex-a/armv8/spider/ethernet/main.c | 137 +++++++ .../cortex-a/armv8/spider/ethernet/rswitch.c | 29 ++ .../cortex-a/armv8/spider/ethernet/rswitch.h | 6 + .../cortex-a/armv8/spider/ethernet/utils.c | 104 +++++ .../cortex-a/armv8/spider/ethernet/utils.h | 9 + 10 files changed, 750 insertions(+) create mode 100755 examples/cortex-a/armv8/spider/ethernet/build.sh create mode 100644 examples/cortex-a/armv8/spider/ethernet/err_codes.h create mode 100644 examples/cortex-a/armv8/spider/ethernet/eth.oil create mode 100644 examples/cortex-a/armv8/spider/ethernet/eth_serdes.c create mode 100644 examples/cortex-a/armv8/spider/ethernet/eth_serdes.h create mode 100644 examples/cortex-a/armv8/spider/ethernet/main.c create mode 100644 examples/cortex-a/armv8/spider/ethernet/rswitch.c create mode 100644 examples/cortex-a/armv8/spider/ethernet/rswitch.h create mode 100644 examples/cortex-a/armv8/spider/ethernet/utils.c create mode 100644 examples/cortex-a/armv8/spider/ethernet/utils.h diff --git a/examples/cortex-a/armv8/spider/ethernet/build.sh b/examples/cortex-a/armv8/spider/ethernet/build.sh new file mode 100755 index 00000000..7c6f7158 --- /dev/null +++ b/examples/cortex-a/armv8/spider/ethernet/build.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +#stop on errors +set -e + +if [[ ! -d "_build" ]] +then + mkdir _build +fi + +echo "*** Run Goil ***" +goil --target=cortex-a/armv8/spider --templates=../../../../../goil/templates/ eth.oil + +echo "*** Run Make ***" +./make.py diff --git a/examples/cortex-a/armv8/spider/ethernet/err_codes.h b/examples/cortex-a/armv8/spider/ethernet/err_codes.h new file mode 100644 index 00000000..6bfc7b43 --- /dev/null +++ b/examples/cortex-a/armv8/spider/ethernet/err_codes.h @@ -0,0 +1,6 @@ +#ifndef _ERR_CODES_H_ +#define _ERR_CODES_H_ + +#define ERR_TIMEOUT (-1) + +#endif /* _ERR_CODES_H_ */ \ No newline at end of file diff --git a/examples/cortex-a/armv8/spider/ethernet/eth.oil b/examples/cortex-a/armv8/spider/ethernet/eth.oil new file mode 100644 index 00000000..15c28c20 --- /dev/null +++ b/examples/cortex-a/armv8/spider/ethernet/eth.oil @@ -0,0 +1,80 @@ +OIL_VERSION = "4.2"; + +IMPLEMENTATION trampoline { + TASK { + UINT32 STACKSIZE = 2048 ; + } ; + + ISR { + UINT32 STACKSIZE = 2048 ; + } ; +}; + +CPU eth { + OS config { + STATUS = EXTENDED; + + BUILD = TRUE { + TRAMPOLINE_BASE_PATH = "../../../../.."; + APP_SRC = "main.c"; + APP_SRC = "utils.c"; + APP_SRC = "eth_serdes.c"; + APP_SRC = "rswitch.c"; + APP_NAME = "eth_exe.elf"; + CFLAGS = "-O0"; + LDFLAGS = "-Map=eth_exe.map"; + COMPILER = "arm-none-eabi-gcc"; + CPPCOMPILER = "arm-none-eabi-g++"; + ASSEMBLER = "arm-none-eabi-as"; + LINKER = "arm-none-eabi-ld"; + COPIER = "arm-none-eabi-objcopy"; + SYSTEM = PYTHON; + }; + SYSTEM_CALL = TRUE; + MEMMAP = TRUE { + COMPILER = gcc; + LINKER = gnu_ld { SCRIPT = "script.ld"; }; + ASSEMBLER = gnu_as; + MEMORY_PROTECTION = FALSE; + }; + }; + + APPMODE std {}; + + TASK sample_init { + PRIORITY = 1; + AUTOSTART = TRUE { APPMODE = std; }; + ACTIVATION = 1; + SCHEDULE = FULL; + }; + + ISR gwca1_rx_tx_int { + CATEGORY = 2; + PRIORITY = 1; + SOURCE = GWCA1_RX_TX_INT; + }; + + ISR gwca1_rx_ts_int { + CATEGORY = 2; + PRIORITY = 1; + SOURCE = GWCA1_RX_TS_INT; + }; + + ISR coma_err_int { + CATEGORY = 2; + PRIORITY = 1; + SOURCE = COMA_ERR_INT; + }; + + ISR gwca1_err_int { + CATEGORY = 2; + PRIORITY = 1; + SOURCE = GWCA1_ERR_INT; + }; + + ISR etha0_err_int { + CATEGORY = 2; + PRIORITY = 1; + SOURCE = ETHA0_ERR_INT; + }; +}; diff --git a/examples/cortex-a/armv8/spider/ethernet/eth_serdes.c b/examples/cortex-a/armv8/spider/ethernet/eth_serdes.c new file mode 100644 index 00000000..bd4bdfe9 --- /dev/null +++ b/examples/cortex-a/armv8/spider/ethernet/eth_serdes.c @@ -0,0 +1,357 @@ +#include "tpl_os.h" +#include "eth_serdes.h" +#include "err_codes.h" +#include "utils.h" + +//#define ETH_SERDES_AN_ENABLED + +#define ETH_SERDES_CH_NUM 3 +#define ETH_SERDES_XPCS_CH0 0UL +#define ETH_SERDES_XPCS_CH1 1UL +#define ETH_SERDES_XPCS_CH2 2UL + +/* Maximum Ethernet Timeout Count */ +#define ETH_TIMEOUT_COUNT 63158UL + +/* Ethernet SERDES registers Base Address */ +#define ETH_SERDES_XPCS0_BASE 0xE6444000UL +#define ETH_SERDES_XPCS1_BASE 0xE6444400UL +#define ETH_SERDES_XPCS2_BASE 0xE6444800UL +/* Ehternet SERDES Bank Register Address */ +#define ETH_SERDES_XPCS0_BANK 0xE64443FCUL +#define ETH_SERDES_XPCS1_BANK 0xE64447FCUL +#define ETH_SERDES_XPCS2_BANK 0xE6444BFCUL + +uint32 eth_serdes_base_addr[ETH_SERDES_CH_NUM] = { + ETH_SERDES_XPCS0_BASE, + ETH_SERDES_XPCS1_BASE, + ETH_SERDES_XPCS2_BASE +}; + +uint32 eth_serdes_bank_addr[ETH_SERDES_CH_NUM] = { + ETH_SERDES_XPCS0_BANK, + ETH_SERDES_XPCS1_BANK, + ETH_SERDES_XPCS2_BANK +}; + +typedef enum { + ETH_MAC_LAYER_SPEED_10M = 0, + ETH_MAC_LAYER_SPEED_100M, + ETH_MAC_LAYER_SPEED_1G, + ETH_MAC_LAYER_SPEED_2500M, + ETH_MAC_LAYER_SPEED_10G +} eth_serdes_speed_t; + +#define ETH_SERDES_BPS ETH_MAC_LAYER_SPEED_1G + +#define ETH_SERDES_SEL_BANK(ch, value) \ + {*(volatile uint32*)eth_serdes_bank_addr[ch] = (uint32)value;} +#define ETH_SERDES_REG_WRITE(ch, offset, value) \ + {*(volatile uint32*)(eth_serdes_base_addr[ch] + (uint16)offset) = (uint32)value;} +#define ETH_SERDES_REG_READ(ch, offset) \ + (*(volatile uint32*)(eth_serdes_base_addr[ch] + (uint16)offset)) + +extern volatile VAR(uint32, OS_VAR) tpl_time_counter; + +void eth_disable_fuse_ovr(void) +{ + /* Disable Fuse_override_en */ + uint32 address; + volatile uint32 val; + + address = 0xE6446600; + val = *((volatile uint32*)address); + *((volatile uint32*)address) = 0x00000000U; + val = *((volatile uint32*)address); + (void) val; +} + +static int eth_serdes_wait_for_update(uint32 ch, uint16 offset, uint32 mask, + uint32 exp_val, uint32 timeout) +{ + uint32 start_time; + uint32 elapsed_time; + uint32 curr_time; + uint32 reg_val; + + start_time = tpl_time_counter; + + do { + curr_time = tpl_time_counter; + reg_val = ETH_SERDES_REG_READ(ch, offset); + elapsed_time = curr_time - start_time; + if ((reg_val & mask) == exp_val) { + return 0; + } + } while (elapsed_time < timeout); + + return ERR_TIMEOUT; +} + +static int eth_serdes_wait_reset(void) +{ + int ch, ret; + + for (ch = 0; ch < ETH_SERDES_CH_NUM; ch++) { + ETH_SERDES_SEL_BANK(ch, 0x0180U); + ret = eth_serdes_wait_for_update(ch, 0x026C, BIT(0), BIT(0), ETH_TIMEOUT_COUNT); + if (ret != 0) { + break; + } + } + return ret; +} + +static int eth_serdes_initialize_SRAM(void) +{ + int ch, ret; + + ret = eth_serdes_wait_reset(); + if (ret != 0) { + return ret; + } + + ETH_SERDES_SEL_BANK(ETH_SERDES_XPCS_CH0, 0x0180); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x026C, 0x3); + + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { + ETH_SERDES_SEL_BANK(ch, 0x0300U); + ret = eth_serdes_wait_for_update(ch, 0x0000U, BIT(15), 0UL, ETH_TIMEOUT_COUNT); + if (ret != 0) { + break; + } + } + + return ret; +} + +static void eth_serdes_set_SGMII_common_settings(void) +{ + /* Steps S.4.1 to S.4.5 */ + ETH_SERDES_SEL_BANK(ETH_SERDES_XPCS_CH0, 0x0180); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x0244, 0x97); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x01D0, 0x60); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x01D8, 0x2200); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x01D4, 0x0); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x01E0, 0x3D); +} + +static int eth_serdes_PHY_soft_reset(void) +{ + int ret; + + /* Step:5 */ + ETH_SERDES_SEL_BANK(ETH_SERDES_XPCS_CH0, 0x0380); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x0000, 0x8000); + + /* Step:6 */ + ret = eth_serdes_wait_reset(); + if (ret != 0) { + return ret; + } + + /* Step:7 */ + ETH_SERDES_SEL_BANK(ETH_SERDES_XPCS_CH0, 0x0180U); + ETH_SERDES_REG_WRITE(ETH_SERDES_XPCS_CH0, 0x026CU, 0x00000003UL); + + /* Step:8 */ + ETH_SERDES_SEL_BANK(ETH_SERDES_XPCS_CH0, 0x0380U); + ret = eth_serdes_wait_for_update(ETH_SERDES_XPCS_CH0, 0x0000U, BIT(15), 0UL, ETH_TIMEOUT_COUNT); + + return ret; +} + +static int eth_serdes_channel_SGMII_common_configuration(uint32 ch) +{ + int ret; + + /* Steps S/SA.9.1 to S/SA.9.14 */ + ETH_SERDES_SEL_BANK(ch, 0x0380); + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x2000); + ETH_SERDES_SEL_BANK(ch, 0x0180); + ETH_SERDES_REG_WRITE(ch, 0x01C0, 0x11); + ETH_SERDES_REG_WRITE(ch, 0x0248, 0x540); + ETH_SERDES_REG_WRITE(ch, 0x0258, 0x15); + ETH_SERDES_REG_WRITE(ch, 0x0144, 0x100); + ETH_SERDES_REG_WRITE(ch, 0x01A0, 0x0); + ETH_SERDES_REG_WRITE(ch, 0x00D0, 0x2); + ETH_SERDES_REG_WRITE(ch, 0x0150, 0x3); + ETH_SERDES_REG_WRITE(ch, 0x00C8, 0x100); + ETH_SERDES_REG_WRITE(ch, 0x0148, 0x100); + ETH_SERDES_REG_WRITE(ch, 0x0174, 0x0); + ETH_SERDES_REG_WRITE(ch, 0x0160, 0x7); + ETH_SERDES_REG_WRITE(ch, 0x01AC, 0x0); + ETH_SERDES_REG_WRITE(ch, 0x00C4, 0x310); + + /* Step: S/SA.9.15 */ + ETH_SERDES_REG_WRITE(ch, 0x00C8, 0x101); + + /* Step: S/SA.9.16 */ + ret = eth_serdes_wait_for_update(ch, 0x00C8, BIT(0), 0x0, ETH_TIMEOUT_COUNT); + if (ret != 0) { + return ret; + } + + /* Step: S/SA.9.17 */ + ETH_SERDES_REG_WRITE(ch, 0x0148, 0x101); + + /* Step: S/SA.9.18 */ + ret = eth_serdes_wait_for_update(ch, 0x0148, BIT(0), 0x0, ETH_TIMEOUT_COUNT); + if (ret != 0) { + return ret; + } + + /* Steps S/SA.9.19 to S/SA.9.24 */ + ETH_SERDES_REG_WRITE(ch, 0x00C4, 0x1310); + ETH_SERDES_REG_WRITE(ch, 0x00D8, 0x1800); + ETH_SERDES_REG_WRITE(ch, 0x00DC, 0x0); + + ETH_SERDES_SEL_BANK(ch, 0x0300); + ETH_SERDES_REG_WRITE(ch, 0x001C, 0x1); + ETH_SERDES_SEL_BANK(ch, 0x0380); + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x2100); + + ret = eth_serdes_wait_for_update(ch, 0x0000, BIT(8), 0x0, ETH_TIMEOUT_COUNT); + + return ret; +} + +#if defined(ETH_SERDES_AN_ENABLED) +static void eth_serdes_channel_SGMII_enable_AN(uint32 ch, eth_serdes_speed_t LenSpeed) +{ + /* Step: SA.9.25 */ + ETH_SERDES_SEL_BANK(ch, 0x1F00); + if (ETH_MAC_LAYER_SPEED_1G == ch) { + /* select when 1Gbps */ + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x140); + } else { + /* select when 100Mbps */ + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x2100); + } + + /* Steps SA.9.26 to SA.9.28 */ + ETH_SERDES_SEL_BANK(ch, 0x1F80); + ETH_SERDES_REG_WRITE(ch, 0x0004, 0x005); + ETH_SERDES_REG_WRITE(ch, 0x0028, 0x7A1); + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x208); +} +#endif + +#if defined(ETH_SERDES_AN_ENABLED) +static int eth_serdes_channel_set_bps_SGMII_ANON(uint32 ch, eth_serdes_speed_t LenSpeed) +{ + int ret; + + /* Step: SA.10.1 */ + ETH_SERDES_SEL_BANK(ch, 0x1F00); + + /* Mode Selection Method is provisional */ + if (ETH_MAC_LAYER_SPEED_1G == LenSpeed) { + /* select 1Gbps */ + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x1140); + } else { + /* select 100Mbps */ + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x3100); + } + + /* Step: SA.10.2 */ + ETH_SERDES_SEL_BANK(ch, 0x1F80); + ret = eth_serdes_wait_for_update(ch, 0x0008, BIT(0), BIT(0), ETH_TIMEOUT_COUNT); + if (ret != 0) { + return ret; + } + + ETH_SERDES_REG_WRITE(ch, 0x0008, 0x0); + + return ret; +} +#endif + +static void eth_serdes_channel_set_bps_SGMII_ANOFF(uint32 ch, eth_serdes_speed_t LenSpeed) +{ + /* Step:S.10.1 */ + ETH_SERDES_SEL_BANK(ch, 0x1F00); + + /* Mode Selection Method is provisional */ + if (ETH_MAC_LAYER_SPEED_1G == LenSpeed) { + /* select 1Gbps */ + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x140); + } else { + /* select 100Mbps */ + ETH_SERDES_REG_WRITE(ch, 0x0000, 0x2100); + } +} + +/* Following User's Manual at section 100.6.3 */ +int eth_serdes_initialize(void) +{ + int ret, ch; + + /* Step 1: Initialize SRAM */ + ret = eth_serdes_initialize_SRAM(); + if (ret != 0) { + return ret; + } + + /* Step 2 */ + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { + ETH_SERDES_SEL_BANK(ch, 0x0380); + ETH_SERDES_REG_WRITE(ch, 0x03D4, 0x443); + } + + /* Step 3 */ + eth_serdes_set_SGMII_common_settings(); + + /* Step 4 */ + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { + ETH_SERDES_SEL_BANK(ch, 0x0380); + ETH_SERDES_REG_WRITE(ch, 0X03D0, 0x1); + } + + /* Steps 5 to 8 */ + ret = eth_serdes_PHY_soft_reset(); + if (ret != 0) { + return ret; + } + + /* Step 9 */ + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { + /* Steps S/SA.9.1 to S/SA.9.24 */ + ret = eth_serdes_channel_SGMII_common_configuration(ch); + if (ret != 0) { + return ret; + } +#if defined(ETH_SERDES_AN_ENABLED) + /* Steps SA.9.25 to SA.9.28 */ + eth_serdes_channel_SGMII_enable_AN(ch, ETH_SERDES_BPS); +#endif + } + + /* Step 10: */ + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { +#if defined(ETH_SERDES_AN_ENABLED) + /* Steps SA.10.1 to SA.10.3 */ + ret = eth_serdes_channel_set_bps_SGMII_ANON(ch, ETH_SERDES_BPS); + if (ret != 0) { + return ret; + } +#else + /* Step: S.10.1 */ + eth_serdes_channel_set_bps_SGMII_ANOFF(ch, ETH_SERDES_BPS); +#endif + } + + /* Step 11 */ + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { + ETH_SERDES_SEL_BANK(ch, 0x0380); + ETH_SERDES_REG_WRITE(ch, 0x03C0, 0x0); + } + + /* Step 12 */ + for (ch = ETH_SERDES_XPCS_CH0; ch < ETH_SERDES_CH_NUM; ch++) { + ETH_SERDES_SEL_BANK(ch, 0x0380); + ETH_SERDES_REG_WRITE(ch, 0x03D0, 0x0); + } + + return 0; +} diff --git a/examples/cortex-a/armv8/spider/ethernet/eth_serdes.h b/examples/cortex-a/armv8/spider/ethernet/eth_serdes.h new file mode 100644 index 00000000..e75a0878 --- /dev/null +++ b/examples/cortex-a/armv8/spider/ethernet/eth_serdes.h @@ -0,0 +1,7 @@ +#ifndef _ETH_SERDES_H_ +#define _ETH_SERDES_H_ + +void eth_disable_fuse_ovr(void); +int eth_serdes_initialize(void); + +#endif /* _ETH_SERDES_H_ */ \ No newline at end of file diff --git a/examples/cortex-a/armv8/spider/ethernet/main.c b/examples/cortex-a/armv8/spider/ethernet/main.c new file mode 100644 index 00000000..e7325327 --- /dev/null +++ b/examples/cortex-a/armv8/spider/ethernet/main.c @@ -0,0 +1,137 @@ +#include "tpl_os.h" +#include "utils.h" +#include "eth_serdes.h" +#include "rswitch.h" + +#define debug_msg(x) do { (void)x; } while(0) + +#define APP_Task_sample_init_START_SEC_CODE +#include "tpl_memmap.h" + +extern volatile VAR(uint32, OS_VAR) tpl_time_counter; + +// Is this the right section for the main function?? +FUNC(int, OS_APPL_CODE) main(void) +{ + StartOS(OSDEFAULTAPPMODE); + return 0; +} + +TASK(sample_init) { + int ret; + + mcu_init(); + port_init(); + // Interrupt initializazion done by Trampoline + eth_disable_fuse_ovr(); + + ret = eth_serdes_initialize(); + if (ret != 0) { + debug_msg("Error in serdes initialization\n"); + goto exit; + } + + rswitch_init(); + + +exit: + TerminateTask(); +} + +#define APP_Task_sample_init_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_gwca1_rx_tx_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(gwca1_rx_tx_int) +{ + //CallTerminateISR2(); +} + +FUNC(void, OS_CODE) GWCA1_RX_TX_INT_ClearFlag(void) +{ + +} + +#define APP_ISR_gwca1_rx_tx_int_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_gwca1_rx_ts_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(gwca1_rx_ts_int) +{ + //CallTerminateISR2(); +} + +FUNC(void, OS_CODE) GWCA1_RX_TS_INT_ClearFlag(void) +{ + +} + +#define APP_ISR_gwca1_rx_ts_int_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_coma_err_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(coma_err_int) +{ + //CallTerminateISR2(); +} + +FUNC(void, OS_CODE) COMA_ERR_INT_ClearFlag(void) +{ + +} + +#define APP_ISR_coma_err_int_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_gwca1_err_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(gwca1_err_int) +{ + //CallTerminateISR2(); +} + +FUNC(void, OS_CODE) GWCA1_ERR_INT_ClearFlag(void) +{ + +} + +#define APP_ISR_gwca1_err_int_STOP_SEC_CODE +#include "tpl_memmap.h" + +/*****************************************************************************/ +/*****************************************************************************/ + +#define APP_ISR_etha0_err_int_START_SEC_CODE +#include "tpl_memmap.h" + +ISR(etha0_err_int) +{ + //CallTerminateISR2(); +} + +FUNC(void, OS_CODE) ETHA0_ERR_INT_ClearFlag(void) +{ + +} + +#define APP_ISR_etha0_err_int_STOP_SEC_CODE +#include "tpl_memmap.h" \ No newline at end of file diff --git a/examples/cortex-a/armv8/spider/ethernet/rswitch.c b/examples/cortex-a/armv8/spider/ethernet/rswitch.c new file mode 100644 index 00000000..6627a82f --- /dev/null +++ b/examples/cortex-a/armv8/spider/ethernet/rswitch.c @@ -0,0 +1,29 @@ +#include "tpl_os.h" +#include "rswitch.h" + +#define RSWITCH_BASE 0xE6880000 + +#define RSWITCH_FWD_ADDR (RSWITCH_BASE + 0x00000000) +#define RSWITCH_FAB_ADDR (RSWITCH_BASE + 0x00008000) +#define RSWITCH_COMA_ADDR (RSWITCH_BASE + 0x00009000) +#define RSWITCH_ETHA0_ADDR (RSWITCH_BASE + 0x0000a000) +#define RSWITCH_ETHA1_ADDR (RSWITCH_BASE + 0x0000c000) +#define RSWITCH_ETHA2_ADDR (RSWITCH_BASE + 0x0000e000) +#define RSWITCH_GWCA0_ADDR (RSWITCH_BASE + 0x00010000) +#define RSWITCH_GWCA1_ADDR (RSWITCH_BASE + 0x00012000) +#define RSWITCH_GPTP_ADDR (RSWITCH_BASE + 0x00018000) + +static inline uint32 reg_read32(void *addr) +{ + return *((volatile uint32*)addr); +} + +static inline void reg_write32(uint32 data, void *addr) +{ + *((volatile uint32*)addr) = data; +} + +int rswitch_init(void) +{ + return 0; +} \ No newline at end of file diff --git a/examples/cortex-a/armv8/spider/ethernet/rswitch.h b/examples/cortex-a/armv8/spider/ethernet/rswitch.h new file mode 100644 index 00000000..4bee5aae --- /dev/null +++ b/examples/cortex-a/armv8/spider/ethernet/rswitch.h @@ -0,0 +1,6 @@ +#ifndef _ETH_H_ +#define _ETH_H_ + +int rswitch_init(void); + +#endif /* _ETH_H_ */ \ No newline at end of file diff --git a/examples/cortex-a/armv8/spider/ethernet/utils.c b/examples/cortex-a/armv8/spider/ethernet/utils.c new file mode 100644 index 00000000..9a9c1bb5 --- /dev/null +++ b/examples/cortex-a/armv8/spider/ethernet/utils.c @@ -0,0 +1,104 @@ +#include "tpl_os.h" +#include "utils.h" +#include "pfcmap.h" +#include "device_cfg.h" + +#define ETH_CPUCLK_MHZ 1066UL +#define ETH_WAIT_NS(t) { volatile uint32 cnt; \ + for ( cnt = 0;cnt < ((((uint32)ETH_CPUCLK_MHZ * ((uint32)t)) / (uint32)1000) + (uint32)1);cnt++ ); } + +/* Module Standby, Software reset */ +#define MSTPCR_ETH_1 (*((volatile uint32 *)0xE6152D3CUL)) /* MSTPCR15 Register */ +#define MSTPSR_ETH_1 (*((volatile uint32 *)0xE6152E3CUL)) /* MSTPSR15 Register */ +#define MSTP_BIT_ETHIP (uint32)(1 << 5) +#define MSTP_BIT_ETHPHY (uint32)(1 << 6) + +/* CPG */ +#define CPG_CPGWPR (*((volatile uint32 *)0xE6150000UL)) /* CPGWPR Register used to remove MSTPCR write protection */ +#define CKCR_ETH_1 (*((volatile uint32 *)0xE61508E8UL)) /* RSW2CKCR Register */ +#define CKCR_BIT_ETHIP (uint32)(1 << 8) + +#define SRCR_ETH_1 (*((volatile uint32 *)0xE6152C3CUL)) /* SRCR15 Register */ +#define SRSTCLR_ETH_1 (*((volatile uint32 *)0xE6152CBCUL)) /* SRSTCLCR15 Register */ +#define SRCR_BIT_ETHIP (uint32)(1 << 5) +#define SRCR_BIT_ETHPHY (uint32)(1 << 6) + +void mcu_init(void) +{ + volatile uint32 regval = 0x0UL; + + /* Supply RSW2�� clock by writing 0 to CKCR */ + regval = CKCR_ETH_1; /* RSW2CKCR */ + if (regval & CKCR_BIT_ETHIP) /* 1: Stops the clock */ + { + regval &= ~CKCR_BIT_ETHIP; + CKCR_ETH_1 = regval; /* 0: Supplies the clock */ + while (CKCR_ETH_1 & CKCR_BIT_ETHIP); /* Wait for the register value to change */ + } + + /* Supply RSW2 and ETHPHY clock by writing 0 to MSTPSR */ + regval = MSTPSR_ETH_1; + if (regval & (MSTP_BIT_ETHIP | MSTP_BIT_ETHPHY)) /* If either one is 1(=Stops the clock), execute the process */ + { + regval &= ~(MSTP_BIT_ETHIP | MSTP_BIT_ETHPHY); + CPG_CPGWPR = ~regval; /* Release MSTPCR write protection by writing the inverse of the value to CPGWPR */ + MSTPCR_ETH_1 = regval; /* 0: Supplies the clock */ + while (MSTPSR_ETH_1 & (MSTP_BIT_ETHIP | MSTP_BIT_ETHPHY)); /* Wait for the register value to change */ + } + + /* Reset RSW2 and ETHPHY by writing 1 to SRCR */ + CPG_CPGWPR = ~(SRCR_BIT_ETHIP | SRCR_BIT_ETHPHY); /* Release SRCR write protection by writing the inverse of the value to CPGWR */ + SRCR_ETH_1 = (uint32)(SRCR_BIT_ETHIP | SRCR_BIT_ETHPHY); /* SRCR does not require read-modify write */ + ETH_WAIT_NS(20*1000); + + /* Release the reset RSW2 and ETHPHY by writing 1 to SRSTCLR */ + CPG_CPGWPR = ~(SRCR_BIT_ETHIP | SRCR_BIT_ETHPHY); /* Release SRSTCLR write protection by writing the inverse of the value to CPGWR */ + SRSTCLR_ETH_1 = (uint32)(SRCR_BIT_ETHIP | SRCR_BIT_ETHPHY); /* SRSTCLR does not require read-modify write */ + ETH_WAIT_NS(40*1000); +} + +void port_init(void) +{ + uint32 dataL; + + /*------- + * GPSR3[18:0] = 18'b1111111111111111111 + * = TSNx_AVTP_CAPTURE, TSNx_AVTP_MATCH, TSNx_AVTP_PPS, TSN0_MAGIC, TSNx_PHY_INT, TSNx_LINK, TSNx_MDC, TSNx_MDIO */ + dataL = *((volatile uint32 *)(PFC_GPSR_GPn_DM0(3))); + dataL &= ~(0x0007FFFFUL); + dataL |= (0x0007FFFFUL); + *((volatile uint32 *)(PFC_PMMR(PFC_GPn_BASE(3)))) = ~dataL; + *((volatile uint32 *)(PFC_GPSR_GPn_DM0(3))) = dataL; + + /*------- + * DRV0CTRL4 [31:28] AVB0_TXC + * [27:24] AVB0_TX_CTL + * DRV1CTRL4 [15:12] AVB0_TD3 + * [11:8] AVB0_TD2 + * [7:4] AVB0_TD1 + * [3:0] AVB0_TD0 */ + dataL = *((volatile uint32 *)PFC_DRVCTRLm_GPn_DM0(0,3)); + dataL &= ~0x77777777UL; + dataL |= 0x33333333UL; + *((volatile uint32 *)(PFC_PMMR(PFC_GPn_BASE(3)))) = ~dataL; + *((volatile uint32 *)(PFC_DRVCTRLm_GPn_DM0(0,3))) = dataL; + + dataL = *((volatile uint32 *)PFC_DRVCTRLm_GPn_DM0(1,3)); + dataL &= ~0x77777777UL; + dataL |= 0x33333333UL; + *((volatile uint32 *)(PFC_PMMR(PFC_GPn_BASE(3)))) = ~dataL; + *((volatile uint32 *)(PFC_DRVCTRLm_GPn_DM0(1,3))) = dataL; + + dataL = *((volatile uint32 *)PFC_DRVCTRLm_GPn_DM0(2,3)); + dataL &= ~0x00000777UL; + dataL |= 0x00000333UL; + *((volatile uint32 *)(PFC_PMMR(PFC_GPn_BASE(3)))) = ~dataL; + *((volatile uint32 *)(PFC_DRVCTRLm_GPn_DM0(2,3))) = dataL; + + /* Ether TSN IO voltage level = 1.8V + * POC3 bit[18:0] = 0 = IO voltage level = 1.8V */ + dataL = *((volatile uint32 *)PFC_POC_GPn_DM0(3)); + dataL &= ~(0x0007FFFFUL); + *((volatile uint32 *)(PFC_PMMR(PFC_GPn_BASE(3)))) = ~dataL; + *((volatile uint32 *)(PFC_POC_GPn_DM0(3))) = dataL; +} diff --git a/examples/cortex-a/armv8/spider/ethernet/utils.h b/examples/cortex-a/armv8/spider/ethernet/utils.h new file mode 100644 index 00000000..db0aa20d --- /dev/null +++ b/examples/cortex-a/armv8/spider/ethernet/utils.h @@ -0,0 +1,9 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#define BIT(x) (1UL << x) + +void mcu_init(void); +void port_init(void); + +#endif /* _UTILS_H_ */ \ No newline at end of file -- 2.25.1