modules: microchip: mpfs: Adding Polarfire SoC mpfs hal
Origin https://github.com/polarfire-soc/platform Signed-off-by: Conor Paxton <conor.paxton@microchip.com>
This commit is contained in:
parent
870d05e6a6
commit
3ac6315ede
|
@ -0,0 +1,16 @@
|
|||
#
|
||||
# Copyright (c) 2021, Microchip Technology Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
zephyr_include_directories(.)
|
||||
zephyr_include_directories(hal)
|
||||
zephyr_include_directories(mpfs_hal)
|
||||
zephyr_include_directories(boards/icicle-kit-es)
|
||||
zephyr_include_directories(boards/icicle-kit-es/platform_config)
|
||||
zephyr_include_directories(mpfs_hal/common)
|
||||
zephyr_include_directories(mpfs_hal/common/nwc)
|
||||
add_subdirectory(drivers/mss/mss_gpio)
|
||||
add_subdirectory(mpfs_hal/common)
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,197 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_clk_ddr_pll.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_CLK_DDR_PLL_H_
|
||||
#define HW_CLK_DDR_PLL_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_DDR_SOFT_RESET)
|
||||
/*This is a compulsory register for all SCB slaves and must be at the same
|
||||
offset in all slaves to facilitate global soft reset of all SCB registers with
|
||||
a single broadcast write from the SCB master. */
|
||||
#define LIBERO_SETTING_DDR_SOFT_RESET 0x00000000UL
|
||||
/* NV_MAP [0:1] RST */
|
||||
/* V_MAP [1:1] RST */
|
||||
/* PERIPH [8:1] RST */
|
||||
/* BLOCKID [16:16] ID */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_PLL_CTRL)
|
||||
/*PLL control register */
|
||||
#define LIBERO_SETTING_DDR_PLL_CTRL 0x0100003FUL
|
||||
/* REG_POWERDOWN_B [0:1] RW value= 0x1 */
|
||||
/* REG_RFDIV_EN [1:1] RW value= 0x1 */
|
||||
/* REG_DIVQ0_EN [2:1] RW value= 0x1 */
|
||||
/* REG_DIVQ1_EN [3:1] RW value= 0x1 */
|
||||
/* REG_DIVQ2_EN [4:1] RW value= 0x1 */
|
||||
/* REG_DIVQ3_EN [5:1] RW value= 0x1 */
|
||||
/* REG_RFCLK_SEL [6:1] RW value= 0x0 */
|
||||
/* RESETONLOCK [7:1] RW value= 0x0 */
|
||||
/* BYPCK_SEL [8:4] RW value= 0x0 */
|
||||
/* REG_BYPASS_GO_B [12:1] RW value= 0x0 */
|
||||
/* RESERVE10 [13:3] RSVD */
|
||||
/* REG_BYPASSPRE [16:4] RW value= 0x0 */
|
||||
/* REG_BYPASSPOST [20:4] RW value= 0x0 */
|
||||
/* LP_REQUIRES_LOCK [24:1] RW value= 0x1 */
|
||||
/* LOCK [25:1] RO */
|
||||
/* LOCK_INT_EN [26:1] RW value= 0x0 */
|
||||
/* UNLOCK_INT_EN [27:1] RW value= 0x0 */
|
||||
/* LOCK_INT [28:1] SW1C */
|
||||
/* UNLOCK_INT [29:1] SW1C */
|
||||
/* RESERVE11 [30:1] RSVD */
|
||||
/* LOCK_B [31:1] RO */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_PLL_REF_FB)
|
||||
/*PLL reference and feedback registers */
|
||||
#define LIBERO_SETTING_DDR_PLL_REF_FB 0x00000500UL
|
||||
/* FSE_B [0:1] RW value= 0x0 */
|
||||
/* FBCK_SEL [1:2] RW value= 0x0 */
|
||||
/* FOUTFB_SELMUX_EN [3:1] RW value= 0x0 */
|
||||
/* RESERVE12 [4:4] RSVD */
|
||||
/* RFDIV [8:6] RW value= 0x5 */
|
||||
/* RESERVE13 [14:2] RSVD */
|
||||
/* RESERVE14 [16:12] RSVD */
|
||||
/* RESERVE15 [28:4] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_PLL_FRACN)
|
||||
/*PLL fractional register */
|
||||
#define LIBERO_SETTING_DDR_PLL_FRACN 0x00000000UL
|
||||
/* FRACN_EN [0:1] RW value= 0x0 */
|
||||
/* FRACN_DAC_EN [1:1] RW value= 0x0 */
|
||||
/* RESERVE16 [2:6] RSVD */
|
||||
/* RESERVE17 [8:24] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_PLL_DIV_0_1)
|
||||
/*PLL 0/1 division registers */
|
||||
#define LIBERO_SETTING_DDR_PLL_DIV_0_1 0x02000100UL
|
||||
/* VCO0PH_SEL [0:3] RO */
|
||||
/* DIV0_START [3:3] RW value= 0x0 */
|
||||
/* RESERVE18 [6:2] RSVD */
|
||||
/* POST0DIV [8:7] RW value= 0x1 */
|
||||
/* RESERVE19 [15:1] RSVD */
|
||||
/* VCO1PH_SEL [16:3] RO */
|
||||
/* DIV1_START [19:3] RW value= 0x0 */
|
||||
/* RESERVE20 [22:2] RSVD */
|
||||
/* POST1DIV [24:7] RW value= 0x2 */
|
||||
/* RESERVE21 [31:1] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_PLL_DIV_2_3)
|
||||
/*PLL 2/3 division registers */
|
||||
#define LIBERO_SETTING_DDR_PLL_DIV_2_3 0x01000100UL
|
||||
/* VCO2PH_SEL [0:3] RO */
|
||||
/* DIV2_START [3:3] RW value= 0x0 */
|
||||
/* RESERVE22 [6:2] RSVD */
|
||||
/* POST2DIV [8:7] RW value= 0x1 */
|
||||
/* RESERVE23 [15:1] RSVD */
|
||||
/* VCO3PH_SEL [16:3] RO */
|
||||
/* DIV3_START [19:3] RW value= 0x0 */
|
||||
/* RESERVE24 [22:2] RSVD */
|
||||
/* POST3DIV [24:7] RW value= 0x1 */
|
||||
/* CKPOST3_SEL [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_PLL_CTRL2)
|
||||
/*PLL control register */
|
||||
#define LIBERO_SETTING_DDR_PLL_CTRL2 0x00001020UL
|
||||
/* BWI [0:2] RW value= 0x0 */
|
||||
/* BWP [2:2] RW value= 0x0 */
|
||||
/* IREF_EN [4:1] RW value= 0x0 */
|
||||
/* IREF_TOGGLE [5:1] RW value= 0x1 */
|
||||
/* RESERVE25 [6:3] RSVD */
|
||||
/* LOCKCNT [9:4] RW value= 0x8 */
|
||||
/* RESERVE26 [13:4] RSVD */
|
||||
/* ATEST_EN [17:1] RW value= 0x0 */
|
||||
/* ATEST_SEL [18:3] RW value= 0x0 */
|
||||
/* RESERVE27 [21:11] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_PLL_CAL)
|
||||
/*PLL calibration register */
|
||||
#define LIBERO_SETTING_DDR_PLL_CAL 0x00000D06UL
|
||||
/* DSKEWCALCNT [0:3] RW value= 0x6 */
|
||||
/* DSKEWCAL_EN [3:1] RW value= 0x0 */
|
||||
/* DSKEWCALBYP [4:1] RW value= 0x0 */
|
||||
/* RESERVE28 [5:3] RSVD */
|
||||
/* DSKEWCALIN [8:7] RW value= 0xd */
|
||||
/* RESERVE29 [15:1] RSVD */
|
||||
/* DSKEWCALOUT [16:7] RO */
|
||||
/* RESERVE30 [23:9] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_PLL_PHADJ)
|
||||
/*PLL phase registers */
|
||||
#define LIBERO_SETTING_DDR_PLL_PHADJ 0x00005003UL
|
||||
/* PLL_REG_SYNCREFDIV_EN [0:1] RW value= 0x1 */
|
||||
/* PLL_REG_ENABLE_SYNCREFDIV [1:1] RW value= 0x1 */
|
||||
/* REG_OUT0_PHSINIT [2:3] RW value= 0x0 */
|
||||
/* REG_OUT1_PHSINIT [5:3] RW value= 0x0 */
|
||||
/* REG_OUT2_PHSINIT [8:3] RW value= 0x0 */
|
||||
/* REG_OUT3_PHSINIT [11:3] RW value= 0x2 */
|
||||
/* REG_LOADPHS_B [14:1] RW value= 0x1 */
|
||||
/* RESERVE31 [15:17] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_SSCG_REG_0)
|
||||
/*SSCG registers 0 */
|
||||
#define LIBERO_SETTING_DDR_SSCG_REG_0 0x00000000UL
|
||||
/* DIVVAL [0:6] RW value= 0x0 */
|
||||
/* FRACIN [6:24] RW value= 0x0 */
|
||||
/* RESERVE00 [30:2] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_SSCG_REG_1)
|
||||
/*SSCG registers 1 */
|
||||
#define LIBERO_SETTING_DDR_SSCG_REG_1 0x00000000UL
|
||||
/* DOWNSPREAD [0:1] RW value= 0x0 */
|
||||
/* SSMD [1:5] RW value= 0x0 */
|
||||
/* FRACMOD [6:24] RO */
|
||||
/* RESERVE01 [30:2] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_SSCG_REG_2)
|
||||
/*SSCG registers 2 */
|
||||
#define LIBERO_SETTING_DDR_SSCG_REG_2 0x00000080UL
|
||||
/* INTIN [0:12] RW value= 0x80 */
|
||||
/* INTMOD [12:12] RO */
|
||||
/* RESERVE02 [24:8] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_SSCG_REG_3)
|
||||
/*SSCG registers 3 */
|
||||
#define LIBERO_SETTING_DDR_SSCG_REG_3 0x00000001UL
|
||||
/* SSE_B [0:1] RW value= 0x1 */
|
||||
/* SEL_EXTWAVE [1:2] RW value= 0x0 */
|
||||
/* EXT_MAXADDR [3:8] RW value= 0x0 */
|
||||
/* TBLADDR [11:8] RO */
|
||||
/* RANDOM_FILTER [19:1] RW value= 0x0 */
|
||||
/* RANDOM_SEL [20:2] RW value= 0x0 */
|
||||
/* RESERVE03 [22:1] RSVD */
|
||||
/* RESERVE04 [23:9] RSVD */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_CLK_DDR_PLL_H_ */
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_clk_mss_cfm.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_CLK_MSS_CFM_H_
|
||||
#define HW_CLK_MSS_CFM_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_MSS_BCLKMUX)
|
||||
/*Input mux selections */
|
||||
#define LIBERO_SETTING_MSS_BCLKMUX 0x00000208UL
|
||||
/* BCLK0_SEL [0:5] RW value= 0x8 */
|
||||
/* BCLK1_SEL [5:5] RW value= 0x10 */
|
||||
/* BCLK2_SEL [10:5] RW value= 0x0 */
|
||||
/* BCLK3_SEL [15:5] RW value= 0x0 */
|
||||
/* BCLK4_SEL [20:5] RW value= 0x0 */
|
||||
/* BCLK5_SEL [25:5] RW value= 0x0 */
|
||||
/* RESERVED [30:2] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_PLL_CKMUX)
|
||||
/*Input mux selections */
|
||||
#define LIBERO_SETTING_MSS_PLL_CKMUX 0x00000155UL
|
||||
/* CLK_IN_MAC_TSU_SEL [0:2] RW value= 0x1 */
|
||||
/* PLL0_RFCLK0_SEL [2:2] RW value= 0x1 */
|
||||
/* PLL0_RFCLK1_SEL [4:2] RW value= 0x1 */
|
||||
/* PLL1_RFCLK0_SEL [6:2] RW value= 0x1 */
|
||||
/* PLL1_RFCLK1_SEL [8:2] RW value= 0x1 */
|
||||
/* PLL1_FDR_SEL [10:5] RW value= 0x0 */
|
||||
/* RESERVED [15:17] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_MSSCLKMUX)
|
||||
/*MSS Clock mux selections */
|
||||
#define LIBERO_SETTING_MSS_MSSCLKMUX 0x00000003UL
|
||||
/* MSSCLK_MUX_SEL [0:2] RW value= 0x3 */
|
||||
/* MSSCLK_MUX_MD [2:2] RW value= 0x0 */
|
||||
/* CLK_STANDBY_SEL [4:1] RW value= 0x0 */
|
||||
/* RESERVED [5:27] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_SPARE0)
|
||||
/*spare logic */
|
||||
#define LIBERO_SETTING_MSS_SPARE0 0x00000000UL
|
||||
/* SPARE0 [0:32] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_FMETER_ADDR)
|
||||
/*Frequency_meter_address_selections */
|
||||
#define LIBERO_SETTING_MSS_FMETER_ADDR 0x00000000UL
|
||||
/* ADDR10 [0:2] RSVD */
|
||||
/* ADDR [2:4] RW value= 0x0 */
|
||||
/* RESERVE18 [6:26] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_FMETER_DATAW)
|
||||
/*Frequency_meter_data_write */
|
||||
#define LIBERO_SETTING_MSS_FMETER_DATAW 0x00000000UL
|
||||
/* DATA [0:24] RW value= 0x0 */
|
||||
/* STROBE [24:1] W1P */
|
||||
/* RESERVE19 [25:7] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_FMETER_DATAR)
|
||||
/*Frequency_meter_data_read */
|
||||
#define LIBERO_SETTING_MSS_FMETER_DATAR 0x00000000UL
|
||||
/* DATA [0:24] RO */
|
||||
/* RESERVE20 [24:8] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_IMIRROR_TRIM)
|
||||
/*Imirror TRIM Bits */
|
||||
#define LIBERO_SETTING_MSS_IMIRROR_TRIM 0x00000000UL
|
||||
/* BG_CODE [0:3] RW value= 0x0 */
|
||||
/* CC_CODE [3:8] RW value= 0x0 */
|
||||
/* RESERVE21 [11:21] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_TEST_CTRL)
|
||||
/*Test MUX Controls */
|
||||
#define LIBERO_SETTING_MSS_TEST_CTRL 0x00000000UL
|
||||
/* OSC_ENABLE [0:4] RW value= 0x0 */
|
||||
/* ATEST_EN [4:1] RW value= 0x0 */
|
||||
/* ATEST_SEL [5:5] RW value= 0x0 */
|
||||
/* DTEST_EN [10:1] RW value= 0x0 */
|
||||
/* DTEST_SEL [11:5] RW value= 0x0 */
|
||||
/* RESERVE22 [16:16] RSVD */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_CLK_MSS_CFM_H_ */
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_clk_mss_pll.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_CLK_MSS_PLL_H_
|
||||
#define HW_CLK_MSS_PLL_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_MSS_PLL_CTRL)
|
||||
/*PLL control register */
|
||||
#define LIBERO_SETTING_MSS_PLL_CTRL 0x01000037UL
|
||||
/* REG_POWERDOWN_B [0:1] RW value= 0x1 */
|
||||
/* REG_RFDIV_EN [1:1] RW value= 0x1 */
|
||||
/* REG_DIVQ0_EN [2:1] RW value= 0x1 */
|
||||
/* REG_DIVQ1_EN [3:1] RW value= 0x0 */
|
||||
/* REG_DIVQ2_EN [4:1] RW value= 0x1 */
|
||||
/* REG_DIVQ3_EN [5:1] RW value= 0x1 */
|
||||
/* REG_RFCLK_SEL [6:1] RW value= 0x0 */
|
||||
/* RESETONLOCK [7:1] RW value= 0x0 */
|
||||
/* BYPCK_SEL [8:4] RW value= 0x0 */
|
||||
/* REG_BYPASS_GO_B [12:1] RW value= 0x0 */
|
||||
/* RESERVE10 [13:3] RSVD */
|
||||
/* REG_BYPASSPRE [16:4] RW value= 0x0 */
|
||||
/* REG_BYPASSPOST [20:4] RW value= 0x0 */
|
||||
/* LP_REQUIRES_LOCK [24:1] RW value= 0x1 */
|
||||
/* LOCK [25:1] RO */
|
||||
/* LOCK_INT_EN [26:1] RW value= 0x0 */
|
||||
/* UNLOCK_INT_EN [27:1] RW value= 0x0 */
|
||||
/* LOCK_INT [28:1] SW1C */
|
||||
/* UNLOCK_INT [29:1] SW1C */
|
||||
/* RESERVE11 [30:1] RSVD */
|
||||
/* LOCK_B [31:1] RO */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_PLL_REF_FB)
|
||||
/*PLL reference and feedback registers */
|
||||
#define LIBERO_SETTING_MSS_PLL_REF_FB 0x00000500UL
|
||||
/* FSE_B [0:1] RW value= 0x0 */
|
||||
/* FBCK_SEL [1:2] RW value= 0x0 */
|
||||
/* FOUTFB_SELMUX_EN [3:1] RW value= 0x0 */
|
||||
/* RESERVE12 [4:4] RSVD */
|
||||
/* RFDIV [8:6] RW value= 0x5 */
|
||||
/* RESERVE13 [14:2] RSVD */
|
||||
/* RESERVE14 [16:12] RSVD */
|
||||
/* RESERVE15 [28:4] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_PLL_FRACN)
|
||||
/*PLL fractional register */
|
||||
#define LIBERO_SETTING_MSS_PLL_FRACN 0x00000000UL
|
||||
/* FRACN_EN [0:1] RW value= 0x0 */
|
||||
/* FRACN_DAC_EN [1:1] RW value= 0x0 */
|
||||
/* RESERVE16 [2:6] RSVD */
|
||||
/* RESERVE17 [8:24] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_PLL_DIV_0_1)
|
||||
/*PLL 0/1 division registers */
|
||||
#define LIBERO_SETTING_MSS_PLL_DIV_0_1 0x01000200UL
|
||||
/* VCO0PH_SEL [0:3] RO */
|
||||
/* DIV0_START [3:3] RW value= 0x0 */
|
||||
/* RESERVE18 [6:2] RSVD */
|
||||
/* POST0DIV [8:7] RW value= 0x2 */
|
||||
/* RESERVE19 [15:1] RSVD */
|
||||
/* VCO1PH_SEL [16:3] RO */
|
||||
/* DIV1_START [19:3] RW value= 0x0 */
|
||||
/* RESERVE20 [22:2] RSVD */
|
||||
/* POST1DIV [24:7] RW value= 0x1 */
|
||||
/* RESERVE21 [31:1] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_PLL_DIV_2_3)
|
||||
/*PLL 2/3 division registers */
|
||||
#define LIBERO_SETTING_MSS_PLL_DIV_2_3 0x0F000600UL
|
||||
/* VCO2PH_SEL [0:3] RO */
|
||||
/* DIV2_START [3:3] RW value= 0x0 */
|
||||
/* RESERVE22 [6:2] RSVD */
|
||||
/* POST2DIV [8:7] RW value= 0x6 */
|
||||
/* RESERVE23 [15:1] RSVD */
|
||||
/* VCO3PH_SEL [16:3] RO */
|
||||
/* DIV3_START [19:3] RW value= 0x0 */
|
||||
/* RESERVE24 [22:2] RSVD */
|
||||
/* POST3DIV [24:7] RW value= 0xF */
|
||||
/* CKPOST3_SEL [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_PLL_CTRL2)
|
||||
/*PLL control register */
|
||||
#define LIBERO_SETTING_MSS_PLL_CTRL2 0x00001020UL
|
||||
/* BWI [0:2] RW value= 0x0 */
|
||||
/* BWP [2:2] RW value= 0x0 */
|
||||
/* IREF_EN [4:1] RW value= 0x0 */
|
||||
/* IREF_TOGGLE [5:1] RW value= 0x1 */
|
||||
/* RESERVE25 [6:3] RSVD */
|
||||
/* LOCKCNT [9:4] RW value= 0x8 */
|
||||
/* RESERVE26 [13:4] RSVD */
|
||||
/* ATEST_EN [17:1] RW value= 0x0 */
|
||||
/* ATEST_SEL [18:3] RW value= 0x0 */
|
||||
/* RESERVE27 [21:11] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_PLL_CAL)
|
||||
/*PLL calibration register */
|
||||
#define LIBERO_SETTING_MSS_PLL_CAL 0x00000D06UL
|
||||
/* DSKEWCALCNT [0:3] RW value= 0x6 */
|
||||
/* DSKEWCAL_EN [3:1] RW value= 0x0 */
|
||||
/* DSKEWCALBYP [4:1] RW value= 0x0 */
|
||||
/* RESERVE28 [5:3] RSVD */
|
||||
/* DSKEWCALIN [8:7] RW value= 0xd */
|
||||
/* RESERVE29 [15:1] RSVD */
|
||||
/* DSKEWCALOUT [16:7] RO */
|
||||
/* RESERVE30 [23:9] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_PLL_PHADJ)
|
||||
/*PLL phase registers */
|
||||
#define LIBERO_SETTING_MSS_PLL_PHADJ 0x00004003UL
|
||||
/* PLL_REG_SYNCREFDIV_EN [0:1] RW value= 0x1 */
|
||||
/* PLL_REG_ENABLE_SYNCREFDIV [1:1] RW value= 0x1 */
|
||||
/* REG_OUT0_PHSINIT [2:3] RW value= 0x0 */
|
||||
/* REG_OUT1_PHSINIT [5:3] RW value= 0x0 */
|
||||
/* REG_OUT2_PHSINIT [8:3] RW value= 0x0 */
|
||||
/* REG_OUT3_PHSINIT [11:3] RW value= 0x8 */
|
||||
/* REG_LOADPHS_B [14:1] RW value= 0x0 */
|
||||
/* RESERVE31 [15:17] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_SSCG_REG_0)
|
||||
/*SSCG registers 0 */
|
||||
#define LIBERO_SETTING_MSS_SSCG_REG_0 0x00000000UL
|
||||
/* DIVVAL [0:6] RW value= 0x0 */
|
||||
/* FRACIN [6:24] RW value= 0x0 */
|
||||
/* RESERVE00 [30:2] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_SSCG_REG_1)
|
||||
/*SSCG registers 1 */
|
||||
#define LIBERO_SETTING_MSS_SSCG_REG_1 0x00000000UL
|
||||
/* DOWNSPREAD [0:1] RW value= 0x0 */
|
||||
/* SSMD [1:5] RW value= 0x0 */
|
||||
/* FRACMOD [6:24] RO */
|
||||
/* RESERVE01 [30:2] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_SSCG_REG_2)
|
||||
/*SSCG registers 2 */
|
||||
#define LIBERO_SETTING_MSS_SSCG_REG_2 0x000000C0UL
|
||||
/* INTIN [0:12] RW value= 0xC0 */
|
||||
/* INTMOD [12:12] RO */
|
||||
/* RESERVE02 [24:8] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_SSCG_REG_3)
|
||||
/*SSCG registers 3 */
|
||||
#define LIBERO_SETTING_MSS_SSCG_REG_3 0x00000001UL
|
||||
/* SSE_B [0:1] RW value= 0x1 */
|
||||
/* SEL_EXTWAVE [1:2] RW value= 0x0 */
|
||||
/* EXT_MAXADDR [3:8] RW value= 0x0 */
|
||||
/* TBLADDR [11:8] RO */
|
||||
/* RANDOM_FILTER [19:1] RW value= 0x0 */
|
||||
/* RANDOM_SEL [20:2] RW value= 0x0 */
|
||||
/* RESERVE03 [22:1] RSVD */
|
||||
/* RESERVE04 [23:9] RSVD */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_CLK_MSS_PLL_H_ */
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_clk_sgmii_cfm.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_CLK_SGMII_CFM_H_
|
||||
#define HW_CLK_SGMII_CFM_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_SGMII_REFCLKMUX)
|
||||
/*Input mux selections */
|
||||
#define LIBERO_SETTING_SGMII_REFCLKMUX 0x00000005UL
|
||||
/* PLL0_RFCLK0_SEL [0:2] RW value= 0x1 */
|
||||
/* PLL0_RFCLK1_SEL [2:2] RW value= 0x1 */
|
||||
/* RESERVED [4:28] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_SGMII_CLKMUX)
|
||||
/*sgmii clk mux */
|
||||
#define LIBERO_SETTING_SGMII_SGMII_CLKMUX 0x00000005UL
|
||||
/* SGMII_CLKMUX [0:32] RW value= 0x5 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_SPARE0)
|
||||
/*spare logic */
|
||||
#define LIBERO_SETTING_SGMII_SPARE0 0x00000000UL
|
||||
/* RESERVED [0:32] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_CLK_XCVR)
|
||||
/*Clock_Receiver */
|
||||
#define LIBERO_SETTING_SGMII_CLK_XCVR 0x00002C30UL
|
||||
/* EN_UDRIVE_P [0:1] RW value= 0x0 */
|
||||
/* EN_INS_HYST_P [1:1] RW value= 0x0 */
|
||||
/* EN_TERM_P [2:2] RW value= 0x0 */
|
||||
/* EN_RXMODE_P [4:2] RW value= 0x3 */
|
||||
/* EN_UDRIVE_N [6:1] RW value= 0x0 */
|
||||
/* EN_INS_HYST_N [7:1] RW value= 0x0 */
|
||||
/* EN_TERM_N [8:2] RW value= 0x0 */
|
||||
/* EN_RXMODE_N [10:2] RW value= 0x3 */
|
||||
/* CLKBUF_EN_PULLUP [12:1] RW value= 0x0 */
|
||||
/* EN_RDIFF [13:1] RW value= 0x1 */
|
||||
/* RESERVED [14:18] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_TEST_CTRL)
|
||||
/*Test MUX Controls */
|
||||
#define LIBERO_SETTING_SGMII_TEST_CTRL 0x00000000UL
|
||||
/* OSC_ENABLE [0:4] RW value= 0x0 */
|
||||
/* ATEST_EN [4:1] RW value= 0x0 */
|
||||
/* ATEST_SEL [5:5] RW value= 0x0 */
|
||||
/* DTEST_EN [10:1] RW value= 0x0 */
|
||||
/* DTEST_SEL [11:5] RW value= 0x0 */
|
||||
/* RESERVE22 [16:16] RSVD */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_CLK_SGMII_CFM_H_ */
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_clk_sgmii_pll.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_CLK_SGMII_PLL_H_
|
||||
#define HW_CLK_SGMII_PLL_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_SGMII_SOFT_RESET)
|
||||
/*This is a compulsory register for all SCB slaves and must be at the same
|
||||
offset in all slaves to facilitate global soft reset of all SCB registers with
|
||||
a single broadcast write from the SCB master. */
|
||||
#define LIBERO_SETTING_SGMII_SOFT_RESET 0x00000000UL
|
||||
/* NV_MAP [0:1] RST */
|
||||
/* V_MAP [1:1] RST */
|
||||
/* PERIPH [8:1] RST */
|
||||
/* BLOCKID [16:16] ID */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_PLL_CTRL)
|
||||
/*PLL control register */
|
||||
#define LIBERO_SETTING_SGMII_PLL_CTRL 0x0100003FUL
|
||||
/* REG_POWERDOWN_B [0:1] RW value= 0x1 */
|
||||
/* REG_RFDIV_EN [1:1] RW value= 0x1 */
|
||||
/* REG_DIVQ0_EN [2:1] RW value= 0x1 */
|
||||
/* REG_DIVQ1_EN [3:1] RW value= 0x1 */
|
||||
/* REG_DIVQ2_EN [4:1] RW value= 0x1 */
|
||||
/* REG_DIVQ3_EN [5:1] RW value= 0x1 */
|
||||
/* REG_RFCLK_SEL [6:1] RW value= 0x0 */
|
||||
/* RESETONLOCK [7:1] RW value= 0x0 */
|
||||
/* BYPCK_SEL [8:4] RW value= 0x0 */
|
||||
/* REG_BYPASS_GO_B [12:1] RW value= 0x0 */
|
||||
/* RESERVE10 [13:3] RSVD */
|
||||
/* REG_BYPASSPRE [16:4] RW value= 0x0 */
|
||||
/* REG_BYPASSPOST [20:4] RW value= 0x0 */
|
||||
/* LP_REQUIRES_LOCK [24:1] RW value= 0x1 */
|
||||
/* LOCK [25:1] RO */
|
||||
/* LOCK_INT_EN [26:1] RW value= 0x0 */
|
||||
/* UNLOCK_INT_EN [27:1] RW value= 0x0 */
|
||||
/* LOCK_INT [28:1] SW1C */
|
||||
/* UNLOCK_INT [29:1] SW1C */
|
||||
/* RESERVE11 [30:1] RSVD */
|
||||
/* LOCK_B [31:1] RO */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_PLL_REF_FB)
|
||||
/*PLL reference and feedback registers */
|
||||
#define LIBERO_SETTING_SGMII_PLL_REF_FB 0x00000100UL
|
||||
/* FSE_B [0:1] RW value= 0x0 */
|
||||
/* FBCK_SEL [1:2] RW value= 0x0 */
|
||||
/* FOUTFB_SELMUX_EN [3:1] RW value= 0x0 */
|
||||
/* RESERVE12 [4:4] RSVD */
|
||||
/* RFDIV [8:6] RW value= 0x1 */
|
||||
/* RESERVE13 [14:2] RSVD */
|
||||
/* RESERVE14 [16:12] RSVD */
|
||||
/* RESERVE15 [28:4] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_PLL_FRACN)
|
||||
/*PLL fractional register */
|
||||
#define LIBERO_SETTING_SGMII_PLL_FRACN 0x00000000UL
|
||||
/* FRACN_EN [0:1] RW value= 0x0 */
|
||||
/* FRACN_DAC_EN [1:1] RW value= 0x0 */
|
||||
/* RESERVE16 [2:6] RSVD */
|
||||
/* RESERVE17 [8:24] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_PLL_DIV_0_1)
|
||||
/*PLL 0/1 division registers */
|
||||
#define LIBERO_SETTING_SGMII_PLL_DIV_0_1 0x01000100UL
|
||||
/* VCO0PH_SEL [0:3] RO */
|
||||
/* DIV0_START [3:3] RW value= 0x0 */
|
||||
/* RESERVE18 [6:2] RSVD */
|
||||
/* POST0DIV [8:7] RW value= 0x1 */
|
||||
/* RESERVE19 [15:1] RSVD */
|
||||
/* VCO1PH_SEL [16:3] RO */
|
||||
/* DIV1_START [19:3] RW value= 0x0 */
|
||||
/* RESERVE20 [22:2] RSVD */
|
||||
/* POST1DIV [24:7] RW value= 0x1 */
|
||||
/* RESERVE21 [31:1] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_PLL_DIV_2_3)
|
||||
/*PLL 2/3 division registers */
|
||||
#define LIBERO_SETTING_SGMII_PLL_DIV_2_3 0x01000100UL
|
||||
/* VCO2PH_SEL [0:3] RO */
|
||||
/* DIV2_START [3:3] RW value= 0x0 */
|
||||
/* RESERVE22 [6:2] RSVD */
|
||||
/* POST2DIV [8:7] RW value= 0x1 */
|
||||
/* RESERVE23 [15:1] RSVD */
|
||||
/* VCO3PH_SEL [16:3] RO */
|
||||
/* DIV3_START [19:3] RW value= 0x0 */
|
||||
/* RESERVE24 [22:2] RSVD */
|
||||
/* POST3DIV [24:7] RW value= 0x1 */
|
||||
/* CKPOST3_SEL [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_PLL_CTRL2)
|
||||
/*PLL control register */
|
||||
#define LIBERO_SETTING_SGMII_PLL_CTRL2 0x00001020UL
|
||||
/* BWI [0:2] RW value= 0x0 */
|
||||
/* BWP [2:2] RW value= 0x0 */
|
||||
/* IREF_EN [4:1] RW value= 0x0 */
|
||||
/* IREF_TOGGLE [5:1] RW value= 0x1 */
|
||||
/* RESERVE25 [6:3] RSVD */
|
||||
/* LOCKCNT [9:4] RW value= 0x8 */
|
||||
/* RESERVE26 [13:4] RSVD */
|
||||
/* ATEST_EN [17:1] RW value= 0x0 */
|
||||
/* ATEST_SEL [18:3] RW value= 0x0 */
|
||||
/* RESERVE27 [21:11] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_PLL_CAL)
|
||||
/*PLL calibration register */
|
||||
#define LIBERO_SETTING_SGMII_PLL_CAL 0x00000D06UL
|
||||
/* DSKEWCALCNT [0:3] RW value= 0x6 */
|
||||
/* DSKEWCAL_EN [3:1] RW value= 0x0 */
|
||||
/* DSKEWCALBYP [4:1] RW value= 0x0 */
|
||||
/* RESERVE28 [5:3] RSVD */
|
||||
/* DSKEWCALIN [8:7] RW value= 0xd */
|
||||
/* RESERVE29 [15:1] RSVD */
|
||||
/* DSKEWCALOUT [16:7] RO */
|
||||
/* RESERVE30 [23:9] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_PLL_PHADJ)
|
||||
/*PLL phase registers */
|
||||
#define LIBERO_SETTING_SGMII_PLL_PHADJ 0x00007443UL
|
||||
/* PLL_REG_SYNCREFDIV_EN [0:1] RW value= 0x1 */
|
||||
/* PLL_REG_ENABLE_SYNCREFDIV [1:1] RW value= 0x1 */
|
||||
/* REG_OUT0_PHSINIT [2:3] RW value= 0x0 */
|
||||
/* REG_OUT1_PHSINIT [5:3] RW value= 0x2 */
|
||||
/* REG_OUT2_PHSINIT [8:3] RW value= 0x4 */
|
||||
/* REG_OUT3_PHSINIT [11:3] RW value= 0x6 */
|
||||
/* REG_LOADPHS_B [14:1] RW value= 0x1 */
|
||||
/* RESERVE31 [15:17] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_SSCG_REG_0)
|
||||
/*SSCG registers 0 */
|
||||
#define LIBERO_SETTING_SGMII_SSCG_REG_0 0x00000000UL
|
||||
/* DIVVAL [0:6] RW value= 0x0 */
|
||||
/* FRACIN [6:24] RW value= 0x0 */
|
||||
/* RESERVE00 [30:2] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_SSCG_REG_1)
|
||||
/*SSCG registers 1 */
|
||||
#define LIBERO_SETTING_SGMII_SSCG_REG_1 0x00000000UL
|
||||
/* DOWNSPREAD [0:1] RW value= 0x0 */
|
||||
/* SSMD [1:5] RW value= 0x0 */
|
||||
/* FRACMOD [6:24] RO */
|
||||
/* RESERVE01 [30:2] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_SSCG_REG_2)
|
||||
/*SSCG registers 2 */
|
||||
#define LIBERO_SETTING_SGMII_SSCG_REG_2 0x00000014UL
|
||||
/* INTIN [0:12] RW value= 0x14 */
|
||||
/* INTMOD [12:12] RO */
|
||||
/* RESERVE02 [24:8] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_SSCG_REG_3)
|
||||
/*SSCG registers 3 */
|
||||
#define LIBERO_SETTING_SGMII_SSCG_REG_3 0x00000001UL
|
||||
/* SSE_B [0:1] RW value= 0x1 */
|
||||
/* SEL_EXTWAVE [1:2] RW value= 0x0 */
|
||||
/* EXT_MAXADDR [3:8] RW value= 0x0 */
|
||||
/* TBLADDR [11:8] RO */
|
||||
/* RANDOM_FILTER [19:1] RW value= 0x0 */
|
||||
/* RANDOM_SEL [20:2] RW value= 0x0 */
|
||||
/* RESERVE03 [22:1] RSVD */
|
||||
/* RESERVE04 [23:9] RSVD */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_CLK_SGMII_PLL_H_ */
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_clk_sysreg.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_CLK_SYSREG_H_
|
||||
#define HW_CLK_SYSREG_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_MSS_CLOCK_CONFIG_CR)
|
||||
/*Master clock config (00=/1 01=/2 10=/4 11=/8 ) */
|
||||
#define LIBERO_SETTING_MSS_CLOCK_CONFIG_CR 0x00000024UL
|
||||
/* DIVIDER_CPU [0:2] RW value= 0x0 */
|
||||
/* DIVIDER_AXI [2:2] RW value= 0x1 */
|
||||
/* DIVIDER_APB_AHB [4:2] RW value= 0x2 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_RTC_CLOCK_CR)
|
||||
/*RTC clock divider */
|
||||
#define LIBERO_SETTING_MSS_RTC_CLOCK_CR 0x0000007DUL
|
||||
/* PERIOD [0:12] RW value= 0x7D */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_ENVM_CR)
|
||||
/*ENVM AHB Controller setup - - Clock period = (Value+1) * (1000/AHBFREQMHZ)
|
||||
e.g. 7 will generate a 40ns period 25MHz clock if the AHB clock is 200MHz */
|
||||
#define LIBERO_SETTING_MSS_ENVM_CR 0x40050006UL
|
||||
/* CLOCK_PERIOD [0:6] RW value= 0x6 */
|
||||
/* CLOCK_CONTINUOUS [8:1] RW value= 0x0 */
|
||||
/* CLOCK_SUPPRESS [9:1] RW value= 0x0 */
|
||||
/* READAHEAD [16:1] RW value= 0x1 */
|
||||
/* SLOWREAD [17:1] RW value= 0x0 */
|
||||
/* INTERRUPT_ENABLE [18:1] RW value= 0x1 */
|
||||
/* TIMER [24:8] RW value= 0x40 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_CLK_SYSREG_H_ */
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_mss_clks.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_MSS_CLKS_H_
|
||||
#define HW_MSS_CLKS_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_MSS_EXT_SGMII_REF_CLK)
|
||||
/*Ref Clock rate in MHz */
|
||||
#define LIBERO_SETTING_MSS_EXT_SGMII_REF_CLK 125000000
|
||||
/* MSS_EXT_SGMII_REF_CLK [0:32] RW value= 125000000 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_COREPLEX_CPU_CLK)
|
||||
/*CPU Clock rate in MHz */
|
||||
#define LIBERO_SETTING_MSS_COREPLEX_CPU_CLK 600000000
|
||||
/* MSS_COREPLEX_CPU_CLK [0:32] RW value= 600000000 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_SYSTEM_CLK)
|
||||
/*System Clock rate in MHz static power. */
|
||||
#define LIBERO_SETTING_MSS_SYSTEM_CLK 600000000
|
||||
/* MSS_SYSTEM_CLK [0:32] RW value= 600000000 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_RTC_TOGGLE_CLK)
|
||||
/*RTC toggle Clock rate in MHz static power. */
|
||||
#define LIBERO_SETTING_MSS_RTC_TOGGLE_CLK 1000000
|
||||
/* MSS_RTC_TOGGLE_CLK [0:32] RW value= 1000000 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_AXI_CLK)
|
||||
/*AXI Clock rate in MHz static power. */
|
||||
#define LIBERO_SETTING_MSS_AXI_CLK 300000000
|
||||
/* MSS_AXI_CLK [0:32] RW value= 300000000 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSS_APB_AHB_CLK)
|
||||
/*AXI Clock rate in MHz static power. */
|
||||
#define LIBERO_SETTING_MSS_APB_AHB_CLK 150000000
|
||||
/* MSS_APB_AHB_CLK [0:32] RW value= 150000000 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_MSS_CLKS_H_ */
|
||||
|
|
@ -0,0 +1,512 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_ddr_io_bank.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_DDR_IO_BANK_H_
|
||||
#define HW_DDR_IO_BANK_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_DPC_BITS)
|
||||
/*DPC Bits Register */
|
||||
#define LIBERO_SETTING_DPC_BITS 0x0004C422UL
|
||||
/* DPC_VS [0:4] RW value= 0x2 */
|
||||
/* DPC_VRGEN_H [4:6] RW value= 0x2 */
|
||||
/* DPC_VRGEN_EN_H [10:1] RW value= 0x1 */
|
||||
/* DPC_MOVE_EN_H [11:1] RW value= 0x0 */
|
||||
/* DPC_VRGEN_V [12:6] RW value= 0xC */
|
||||
/* DPC_VRGEN_EN_V [18:1] RW value= 0x1 */
|
||||
/* DPC_MOVE_EN_V [19:1] RW value= 0x0 */
|
||||
/* RESERVE01 [20:12] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_ODT_DQ)
|
||||
/*Need to be set by software in all modes but OFF mode. Decoding options should
|
||||
follow ODT_STR table, depends on drive STR setting */
|
||||
#define LIBERO_SETTING_RPC_ODT_DQ 0x00000006UL
|
||||
/* RPC_ODT_DQ [0:32] RW value= 0x6 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_ODT_DQS)
|
||||
/*Need to be set by software in all modes but OFF mode. Decoding options should
|
||||
follow ODT_STR table, depends on drive STR setting */
|
||||
#define LIBERO_SETTING_RPC_ODT_DQS 0x00000006UL
|
||||
/* RPC_ODT_DQS [0:32] RW value= 0x6 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_ODT_ADDCMD)
|
||||
/*Need to be set by software in all modes but OFF mode. Decoding options should
|
||||
follow ODT_STR table, depends on drive STR setting */
|
||||
#define LIBERO_SETTING_RPC_ODT_ADDCMD 0x00000002UL
|
||||
/* RPC_ODT_ADDCMD [0:32] RW value= 0x2 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_ODT_CLK)
|
||||
/*Need to be set by software in all modes but OFF mode. Decoding options should
|
||||
follow ODT_STR table, depends on drive STR setting */
|
||||
#define LIBERO_SETTING_RPC_ODT_CLK 0x00000002UL
|
||||
/* RPC_ODT_CLK [0:32] RW value= 0x2 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_ODT_STATIC_DQ)
|
||||
/*0x2000 73A8 (rpc10_ODT) */
|
||||
#define LIBERO_SETTING_RPC_ODT_STATIC_DQ 0x00000005UL
|
||||
/* RPC_ODT_STATIC_DQ [0:32] RW value= 0x5 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_ODT_STATIC_DQS)
|
||||
/*0x2000 73AC (rpc11_ODT) */
|
||||
#define LIBERO_SETTING_RPC_ODT_STATIC_DQS 0x00000005UL
|
||||
/* RPC_ODT_STATIC_DQS [0:32] RW value= 0x5 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_ODT_STATIC_ADDCMD)
|
||||
/*0x2000 739C (rpc7_ODT) */
|
||||
#define LIBERO_SETTING_RPC_ODT_STATIC_ADDCMD 0x00000007UL
|
||||
/* RPC_ODT_STATIC_ADDCMD [0:32] RW value= 0x7 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_ODT_STATIC_CLKP)
|
||||
/*0x2000 73A4 (rpc9_ODT) */
|
||||
#define LIBERO_SETTING_RPC_ODT_STATIC_CLKP 0x00000007UL
|
||||
/* RPC_ODT_STATIC_CLKP [0:32] RW value= 0x7 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_ODT_STATIC_CLKN)
|
||||
/*0x2000 73A0 (rpc8_ODT) */
|
||||
#define LIBERO_SETTING_RPC_ODT_STATIC_CLKN 0x00000007UL
|
||||
/* RPC_ODT_STATIC_CLKN [0:32] RW value= 0x7 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_IBUFMD_ADDCMD)
|
||||
/*0x2000 757C (rpc95) */
|
||||
#define LIBERO_SETTING_RPC_IBUFMD_ADDCMD 0x00000003UL
|
||||
/* RPC_IBUFMD_ADDCMD [0:32] RW value= 0x3 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_IBUFMD_CLK)
|
||||
/*0x2000 7580 (rpc96) */
|
||||
#define LIBERO_SETTING_RPC_IBUFMD_CLK 0x00000004UL
|
||||
/* RPC_IBUFMD_CLK [0:32] RW value= 0x4 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_IBUFMD_DQ)
|
||||
/*0x2000 7584 (rpc97) */
|
||||
#define LIBERO_SETTING_RPC_IBUFMD_DQ 0x00000003UL
|
||||
/* RPC_IBUFMD_DQ [0:32] RW value= 0x3 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_IBUFMD_DQS)
|
||||
/*0x2000 7588 (rpc98) */
|
||||
#define LIBERO_SETTING_RPC_IBUFMD_DQS 0x00000004UL
|
||||
/* RPC_IBUFMD_DQS [0:32] RW value= 0x4 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_SPARE0_DQ)
|
||||
/*bits 15:14 connect to pc_ibufmx DQ/DQS/DM bits 13:12 connect to pc_ibufmx
|
||||
CA/CK Check at ioa pc bit */
|
||||
#define LIBERO_SETTING_RPC_SPARE0_DQ 0x00008000UL
|
||||
/* RPC_SPARE0_DQ [0:32] RW value= 0x8000 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_EN_ADDCMD0_OVRT9)
|
||||
/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
|
||||
to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC_EN_ADDCMD0_OVRT9 0x00000F00UL
|
||||
/* MSS_DDR_CK0 [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_CK_N0 [1:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A0 [2:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A1 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A2 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A3 [5:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A4 [6:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A5 [7:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A6 [8:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A7 [9:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A8 [10:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A9 [11:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_EN_ADDCMD1_OVRT10)
|
||||
/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
|
||||
to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC_EN_ADDCMD1_OVRT10 0x00000FFFUL
|
||||
/* MSS_DDR_CK1 [0:1] RW value= 0x1 */
|
||||
/* MSS_DDR_CK_N1 [1:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A10 [2:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A11 [3:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A12 [4:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A13 [5:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A14 [6:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A15 [7:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A16 [8:1] RW value= 0x1 */
|
||||
/* MSS_DDR3_WE_N [9:1] RW value= 0x1 */
|
||||
/* MSS_DDR_BA0 [10:1] RW value= 0x1 */
|
||||
/* MSS_DDR_BA1 [11:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_EN_ADDCMD2_OVRT11)
|
||||
/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
|
||||
to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC_EN_ADDCMD2_OVRT11 0x00000FE6UL
|
||||
/* MSS_DDR_RAM_RST_N [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_BG0 [1:1] RW value= 0x1 */
|
||||
/* MSS_DDR_BG1 [2:1] RW value= 0x1 */
|
||||
/* MSS_DDR_CS0 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_CKE0 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_ODT0 [5:1] RW value= 0x1 */
|
||||
/* MSS_DDR_CS1 [6:1] RW value= 0x1 */
|
||||
/* MSS_DDR_CKE1 [7:1] RW value= 0x1 */
|
||||
/* MSS_DDR_ODT1 [8:1] RW value= 0x1 */
|
||||
/* MSS_DDR_ACT_N [9:1] RW value= 0x1 */
|
||||
/* MSS_DDR_PARITY [10:1] RW value= 0x1 */
|
||||
/* MSS_DDR_ALERT_N [11:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_EN_DATA0_OVRT12)
|
||||
/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
|
||||
to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC_EN_DATA0_OVRT12 0x00000000UL
|
||||
/* MSS_DDR_DQ0 [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ1 [1:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ2 [2:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ3 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_P0 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_N0 [5:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ4 [6:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ5 [7:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ6 [8:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ7 [9:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DM0 [10:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_EN_DATA1_OVRT13)
|
||||
/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
|
||||
to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC_EN_DATA1_OVRT13 0x00000000UL
|
||||
/* MSS_DDR_DQ8 [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ9 [1:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ10 [2:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ11 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_P1 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_N1 [5:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ12 [6:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ13 [7:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ14 [8:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ15 [9:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DM1 [10:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_EN_DATA2_OVRT14)
|
||||
/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
|
||||
to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC_EN_DATA2_OVRT14 0x00000000UL
|
||||
/* MSS_DDR_DQ16 [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ17 [1:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ18 [2:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ19 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_P2 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_N2 [5:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ20 [6:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ21 [7:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ22 [8:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ23 [9:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DM2 [10:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_EN_DATA3_OVRT15)
|
||||
/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
|
||||
to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC_EN_DATA3_OVRT15 0x00000000UL
|
||||
/* MSS_DDR_DQ24 [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ25 [1:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ26 [2:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ27 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_P3 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_N3 [5:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ28 [6:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ29 [7:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ30 [8:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ31 [9:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DM3 [10:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC_EN_ECC_OVRT16)
|
||||
/*Overrides the I/O, used to disable specific DDR I/0. Each bit corresponding
|
||||
to an IO in corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC_EN_ECC_OVRT16 0x0000007FUL
|
||||
/* MSS_DDR_DQ32 [0:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ33 [1:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ34 [2:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ35 [3:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQS_P4 [4:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQS_N4 [5:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DM4 [6:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC235_WPD_ADD_CMD0)
|
||||
/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC235_WPD_ADD_CMD0 0x00000000UL
|
||||
/* MSS_DDR_CK0 [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_CK_N0 [1:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A0 [2:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A1 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A2 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A3 [5:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A4 [6:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A5 [7:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A6 [8:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A7 [9:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A8 [10:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A9 [11:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC236_WPD_ADD_CMD1)
|
||||
/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC236_WPD_ADD_CMD1 0x00000000UL
|
||||
/* MSS_DDR_CK1 [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_CK_N1 [1:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A10 [2:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A11 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A12 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A13 [5:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A14 [6:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A15 [7:1] RW value= 0x0 */
|
||||
/* MSS_DDR_A16 [8:1] RW value= 0x0 */
|
||||
/* MSS_DDR3_WE_N [9:1] RW value= 0x0 */
|
||||
/* MSS_DDR_BA0 [10:1] RW value= 0x0 */
|
||||
/* MSS_DDR_BA1 [11:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC237_WPD_ADD_CMD2)
|
||||
/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. Note: For LPDDR4 need
|
||||
to over-ride MSS_DDR_ODT0 and MSS_DDR_ODT1 and eanble PU i.e. (set OVR_EN ==1 ,
|
||||
wpu == 0 , wpd == 1 ) */
|
||||
#define LIBERO_SETTING_RPC237_WPD_ADD_CMD2 0x00000120UL
|
||||
/* MSS_DDR_RAM_RST_N [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_BG0 [1:1] RW value= 0x0 */
|
||||
/* MSS_DDR_BG1 [2:1] RW value= 0x0 */
|
||||
/* MSS_DDR_CS0 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_CKE0 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_ODT0 [5:1] RW value= 0x1 */
|
||||
/* MSS_DDR_CS1 [6:1] RW value= 0x0 */
|
||||
/* MSS_DDR_CKE1 [7:1] RW value= 0x0 */
|
||||
/* MSS_DDR_ODT1 [8:1] RW value= 0x1 */
|
||||
/* MSS_DDR_ACT_N [9:1] RW value= 0x0 */
|
||||
/* MSS_DDR_PARITY [10:1] RW value= 0x0 */
|
||||
/* MSS_DDR_ALERT_N [11:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC238_WPD_DATA0)
|
||||
/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC238_WPD_DATA0 0x00000000UL
|
||||
/* MSS_DDR_DQ0 [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ1 [1:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ2 [2:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ3 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_P0 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_N0 [5:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ4 [6:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ5 [7:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ6 [8:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ7 [9:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DM0 [10:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC239_WPD_DATA1)
|
||||
/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC239_WPD_DATA1 0x00000000UL
|
||||
/* MSS_DDR_DQ8 [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ9 [1:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ10 [2:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ11 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_P1 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_N1 [5:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ12 [6:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ13 [7:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ14 [8:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ15 [9:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DM1 [10:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC240_WPD_DATA2)
|
||||
/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC240_WPD_DATA2 0x00000000UL
|
||||
/* MSS_DDR_DQ16 [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ17 [1:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ18 [2:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ19 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_P2 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_N2 [5:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ20 [6:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ21 [7:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ22 [8:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ23 [9:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DM2 [10:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC241_WPD_DATA3)
|
||||
/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC241_WPD_DATA3 0x00000000UL
|
||||
/* MSS_DDR_DQ24 [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ25 [1:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ26 [2:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ27 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_P3 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_N3 [5:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ28 [6:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ29 [7:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ30 [8:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ31 [9:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DM3 [10:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC242_WPD_ECC)
|
||||
/*Sets pull-downs when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC242_WPD_ECC 0x00000000UL
|
||||
/* MSS_DDR_DQ32 [0:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ33 [1:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ34 [2:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQ35 [3:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_P4 [4:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DQS_N4 [5:1] RW value= 0x0 */
|
||||
/* MSS_DDR_DM4 [6:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC243_WPU_ADD_CMD0)
|
||||
/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC243_WPU_ADD_CMD0 0x00000FFFUL
|
||||
/* MSS_DDR_CK0 [0:1] RW value= 0x1 */
|
||||
/* MSS_DDR_CK_N0 [1:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A0 [2:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A1 [3:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A2 [4:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A3 [5:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A4 [6:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A5 [7:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A6 [8:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A7 [9:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A8 [10:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A9 [11:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC244_WPU_ADD_CMD1)
|
||||
/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC244_WPU_ADD_CMD1 0x00000FFFUL
|
||||
/* MSS_DDR_CK1 [0:1] RW value= 0x1 */
|
||||
/* MSS_DDR_CK_N1 [1:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A10 [2:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A11 [3:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A12 [4:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A13 [5:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A14 [6:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A15 [7:1] RW value= 0x1 */
|
||||
/* MSS_DDR_A16 [8:1] RW value= 0x1 */
|
||||
/* MSS_DDR3_WE_N [9:1] RW value= 0x1 */
|
||||
/* MSS_DDR_BA0 [10:1] RW value= 0x1 */
|
||||
/* MSS_DDR_BA1 [11:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC245_WPU_ADD_CMD2)
|
||||
/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC245_WPU_ADD_CMD2 0x00000EDFUL
|
||||
/* MSS_DDR_RAM_RST_N [0:1] RW value= 0x1 */
|
||||
/* MSS_DDR_BG0 [1:1] RW value= 0x1 */
|
||||
/* MSS_DDR_BG1 [2:1] RW value= 0x1 */
|
||||
/* MSS_DDR_CS0 [3:1] RW value= 0x1 */
|
||||
/* MSS_DDR_CKE0 [4:1] RW value= 0x1 */
|
||||
/* MSS_DDR_ODT0 [5:1] RW value= 0x0 */
|
||||
/* MSS_DDR_CS1 [6:1] RW value= 0x1 */
|
||||
/* MSS_DDR_CKE1 [7:1] RW value= 0x1 */
|
||||
/* MSS_DDR_ODT1 [8:1] RW value= 0x0 */
|
||||
/* MSS_DDR_ACT_N [9:1] RW value= 0x1 */
|
||||
/* MSS_DDR_PARITY [10:1] RW value= 0x1 */
|
||||
/* MSS_DDR_ALERT_N [11:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC246_WPU_DATA0)
|
||||
/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC246_WPU_DATA0 0x000007FFUL
|
||||
/* MSS_DDR_DQ0 [0:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ1 [1:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ2 [2:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ3 [3:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQS_P0 [4:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQS_N0 [5:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ4 [6:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ5 [7:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ6 [8:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ7 [9:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DM0 [10:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC247_WPU_DATA1)
|
||||
/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC247_WPU_DATA1 0x000007FFUL
|
||||
/* MSS_DDR_DQ8 [0:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ9 [1:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ10 [2:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ11 [3:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQS_P1 [4:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQS_N1 [5:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ12 [6:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ13 [7:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ14 [8:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ15 [9:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DM1 [10:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC248_WPU_DATA2)
|
||||
/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC248_WPU_DATA2 0x000007FFUL
|
||||
/* MSS_DDR_DQ16 [0:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ17 [1:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ18 [2:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ19 [3:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQS_P2 [4:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQS_N2 [5:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ20 [6:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ21 [7:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ22 [8:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ23 [9:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DM2 [10:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC249_WPU_DATA3)
|
||||
/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC249_WPU_DATA3 0x000007FFUL
|
||||
/* MSS_DDR_DQ24 [0:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ25 [1:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ26 [2:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ27 [3:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQS_P3 [4:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQS_N3 [5:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ28 [6:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ29 [7:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ30 [8:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ31 [9:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DM3 [10:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RPC250_WPU_ECC)
|
||||
/*Sets pull-ups when override enabled. Each bit corresponding to an IO in
|
||||
corresponding IOG lane, starting from p_pair0 to n_pair5. */
|
||||
#define LIBERO_SETTING_RPC250_WPU_ECC 0x0000007FUL
|
||||
/* MSS_DDR_DQ32 [0:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ33 [1:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ34 [2:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQ35 [3:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQS_P4 [4:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DQS_N4 [5:1] RW value= 0x1 */
|
||||
/* MSS_DDR_DM4 [6:1] RW value= 0x1 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_DDR_IO_BANK_H_ */
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_ddr_mode.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_DDR_MODE_H_
|
||||
#define HW_DDR_MODE_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_DDRPHY_MODE)
|
||||
/*DDRPHY MODE (binary)- 000 ddr3, 001 ddr33L, 010 ddr4, 011 LPDDR3, 100 LPDDR4,
|
||||
111 OFF_MODE */
|
||||
#define LIBERO_SETTING_DDRPHY_MODE 0x00014B24UL
|
||||
/* DDRMODE [0:3] RW value= 0x4 */
|
||||
/* ECC [3:1] RW value= 0x0 */
|
||||
/* CRC [4:1] RW value= 0x0 */
|
||||
/* BUS_WIDTH [5:3] RW value= 0x1 */
|
||||
/* DMI_DBI [8:1] RW value= 0x1 */
|
||||
/* DQ_DRIVE [9:2] RW value= 0x1 */
|
||||
/* DQS_DRIVE [11:2] RW value= 0x1 */
|
||||
/* ADD_CMD_DRIVE [13:2] RW value= 0x2 */
|
||||
/* CLOCK_OUT_DRIVE [15:2] RW value= 0x2 */
|
||||
/* DQ_TERMINATION [17:2] RW value= 0x0 */
|
||||
/* DQS_TERMINATION [19:2] RW value= 0x0 */
|
||||
/* ADD_CMD_INPUT_PIN_TERMINATION [21:2] RW value= 0x0 */
|
||||
/* PRESET_ODT_CLK [23:2] RW value= 0x0 */
|
||||
/* POWER_DOWN [25:1] RW value= 0x0 */
|
||||
/* RANK [26:1] RW value= 0x0 */
|
||||
/* RESERVED [27:5] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DATA_LANES_USED)
|
||||
/*number of lanes used for data- does not include ECC, infer from mode register
|
||||
*/
|
||||
#define LIBERO_SETTING_DATA_LANES_USED 0x00000004UL
|
||||
/* DATA_LANES [0:3] RW value= 0x4 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_DDR_MODE_H_ */
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_ddr_off_mode.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_DDR_OFF_MODE_H_
|
||||
#define HW_DDR_OFF_MODE_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_DDRPHY_MODE_OFF)
|
||||
/*DDRPHY MODE Register, ddr off */
|
||||
#define LIBERO_SETTING_DDRPHY_MODE_OFF 0x00000000UL
|
||||
/* DDRMODE [0:3] RW value= 0x0 */
|
||||
/* ECC [3:1] RW value= 0x0 */
|
||||
/* CRC [4:1] RW value= 0x0 */
|
||||
/* BUS_WIDTH [5:3] RW value= 0x0 */
|
||||
/* DMI_DBI [8:1] RW value= 0x0 */
|
||||
/* DQ_DRIVE [9:2] RW value= 0x0 */
|
||||
/* DQS_DRIVE [11:2] RW value= 0x0 */
|
||||
/* ADD_CMD_DRIVE [13:2] RW value= 0x0 */
|
||||
/* CLOCK_OUT_DRIVE [15:2] RW value= 0x0 */
|
||||
/* DQ_TERMINATION [17:2] RW value= 0x0 */
|
||||
/* DQS_TERMINATION [19:2] RW value= 0x0 */
|
||||
/* ADD_CMD_INPUT_PIN_TERMINATION [21:2] RW value= 0x0 */
|
||||
/* PRESET_ODT_CLK [23:2] RW value= 0x0 */
|
||||
/* POWER_DOWN [25:1] RW value= 0x0 */
|
||||
/* RANK [26:1] RW value= 0x0 */
|
||||
/* RESERVED [27:5] RSVD */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DPC_BITS_OFF_MODE)
|
||||
/*DPC Bits Register off mode */
|
||||
#define LIBERO_SETTING_DPC_BITS_OFF_MODE 0x00000000UL
|
||||
/* DPC_VS [0:4] RW value= 0x0 */
|
||||
/* DPC_VRGEN_H [4:6] RW value= 0x0 */
|
||||
/* DPC_VRGEN_EN_H [10:1] RW value= 0x0 */
|
||||
/* DPC_MOVE_EN_H [11:1] RW value= 0x0 */
|
||||
/* DPC_VRGEN_V [12:6] RW value= 0x0 */
|
||||
/* DPC_VRGEN_EN_V [18:1] RW value= 0x0 */
|
||||
/* DPC_MOVE_EN_V [19:1] RW value= 0x0 */
|
||||
/* RESERVE01 [20:12] RSVD */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_DDR_OFF_MODE_H_ */
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_ddr_options.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_DDR_OPTIONS_H_
|
||||
#define HW_DDR_OPTIONS_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_CA_BUS_RX_OFF_POST_TRAINING)
|
||||
/*Tip config: Referenced receivers in the CA bus are turned on for CA training.
|
||||
These burn static power.(0x01 => turn off ; 0x00 => no action ) */
|
||||
#define LIBERO_SETTING_CA_BUS_RX_OFF_POST_TRAINING 0x00000001UL
|
||||
/* CA_BUS_RX_OFF_POST_TRAINING [0:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_USER_INPUT_PHY_RANKS_TO_TRAIN)
|
||||
/*Tip config: 1 => 1 rank, 3 => 2 ranks */
|
||||
#define LIBERO_SETTING_USER_INPUT_PHY_RANKS_TO_TRAIN 0x00000001UL
|
||||
/* USER_INPUT_PHY_RANKS_TO_TRAIN [0:2] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_TRAINING_SKIP_SETTING)
|
||||
/*Tip config: Pick what trainings we want performed by the TIP, default is 0x1F
|
||||
*/
|
||||
#define LIBERO_SETTING_TRAINING_SKIP_SETTING 0x00000002UL
|
||||
/* SKIP_BCLKSCLK_TIP_TRAINING [0:1] RW value= 0x0 */
|
||||
/* SKIP_ADDCMD_TIP_TRAINING [1:1] RW value= 0x1 */
|
||||
/* SKIP_WRLVL_TIP_TRAINING [2:1] RW value= 0x0 */
|
||||
/* SKIP_RDGATE_TIP_TRAINING [3:1] RW value= 0x0 */
|
||||
/* SKIP_DQ_DQS_OPT_TIP_TRAINING [4:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_TIP_CFG_PARAMS)
|
||||
/*Tip config: default: 0x2,0x4,0x0,0x1F,0x1F */
|
||||
#define LIBERO_SETTING_TIP_CFG_PARAMS 0x07CFE02AUL
|
||||
/* ADDCMD_OFFSET [0:3] RW value= 0x2 */
|
||||
/* BCKLSCLK_OFFSET [3:3] RW value= 0x5 */
|
||||
/* WRCALIB_WRITE_COUNT [6:7] RW value= 0x0 */
|
||||
/* READ_GATE_MIN_READS [13:8] RW value= 0x7F */
|
||||
/* ADDRCMD_WAIT_COUNT [22:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_TIP_CONFIG_PARAMS_BCLK_VCOPHS_OFFSET)
|
||||
/*in simulation we need to set this to 2, for hardware it will be dependent on
|
||||
the trace lengths */
|
||||
#define LIBERO_SETTING_TIP_CONFIG_PARAMS_BCLK_VCOPHS_OFFSET 0x00000002UL
|
||||
/* TIP_CONFIG_PARAMS_BCLK_VCOPHS [0:32] RW value= 0x02 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_DDR_OPTIONS_H_ */
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_ddr_segs.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_DDR_SEGS_H_
|
||||
#define HW_DDR_SEGS_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_SEG0_0)
|
||||
/*Cached access at 0x00_8000_0000 (-0x80+0x00) */
|
||||
#define LIBERO_SETTING_SEG0_0 0x80007F80UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x7F80 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG0_1)
|
||||
/*Cached access at 0x10_0000_000 */
|
||||
#define LIBERO_SETTING_SEG0_1 0x80007030UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x7030 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG0_2)
|
||||
/*not used */
|
||||
#define LIBERO_SETTING_SEG0_2 0x00000000UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x0 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG0_3)
|
||||
/*not used */
|
||||
#define LIBERO_SETTING_SEG0_3 0x00000000UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x0 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG0_4)
|
||||
/*not used */
|
||||
#define LIBERO_SETTING_SEG0_4 0x00000000UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x0 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG0_5)
|
||||
/*not used */
|
||||
#define LIBERO_SETTING_SEG0_5 0x00000000UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x0 */
|
||||
/* RESERVED [15:6] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG0_6)
|
||||
/*not used */
|
||||
#define LIBERO_SETTING_SEG0_6 0x00000000UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x0 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG0_7)
|
||||
/*not used */
|
||||
#define LIBERO_SETTING_SEG0_7 0x00000000UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x0 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG1_0)
|
||||
/*not used */
|
||||
#define LIBERO_SETTING_SEG1_0 0x00000000UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x0 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG1_1)
|
||||
/*not used */
|
||||
#define LIBERO_SETTING_SEG1_1 0x00000000UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x0 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG1_2)
|
||||
/*Non-Cached access at 0x00_c000_0000 */
|
||||
#define LIBERO_SETTING_SEG1_2 0x80007FB0UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x7FB0 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG1_3)
|
||||
/*Non-Cached access at 0x14_0000_0000 */
|
||||
#define LIBERO_SETTING_SEG1_3 0x80000000UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x0 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG1_4)
|
||||
/*Non-Cached WCB access at 0x00_d000_0000 */
|
||||
#define LIBERO_SETTING_SEG1_4 0x80007FA0UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x7FA0 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG1_5)
|
||||
/*Non-Cached WCB 0x18_0000_0000 */
|
||||
#define LIBERO_SETTING_SEG1_5 0x80000000UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x0 */
|
||||
/* RESERVED [15:6] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG1_6)
|
||||
/*Trace - Trace not in use here so can be left as 0 */
|
||||
#define LIBERO_SETTING_SEG1_6 0x00000000UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x0 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SEG1_7)
|
||||
/*not used */
|
||||
#define LIBERO_SETTING_SEG1_7 0x00000000UL
|
||||
/* ADDRESS_OFFSET [0:15] RW value= 0x0 */
|
||||
/* RESERVED [15:16] RW value= 0x0 */
|
||||
/* LOCKED [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_DDR_SEGS_H_ */
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,91 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file fpga_design_config.h
|
||||
* @author Embedded Software
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FPGA_DESIGN_CONFIG_H_
|
||||
#define FPGA_DESIGN_CONFIG_H_
|
||||
|
||||
#define LIBERO_SETTING_MSS_CONFIGURATOR_VERSION "2021.1"
|
||||
#define LIBERO_SETTING_DESIGN_NAME "ICICLE_MSS"
|
||||
#define LIBERO_SETTING_MPFS_PART "MPFS250T_ES"
|
||||
#define LIBERO_SETTING_GENERATION_DATE "07-06-2021_20:54:25"
|
||||
#define LIBERO_SETTING_XML_VERSION "0.5.3"
|
||||
#define LIBERO_SETTING_XML_VERSION_MAJOR 0
|
||||
#define LIBERO_SETTING_XML_VERSION_MINOR 5
|
||||
#define LIBERO_SETTING_XML_VERSION_PATCH 3
|
||||
#define LIBERO_SETTING_HEADER_GENERATOR_VERSION "0.6.3"
|
||||
#define LIBERO_SETTING_HEADER_GENERATOR_VERSION_MAJOR 0
|
||||
#define LIBERO_SETTING_HEADER_GENERATOR_VERSION_MINOR 6
|
||||
#define LIBERO_SETTING_HEADER_GENERATOR_VERSION_PATCH 3
|
||||
|
||||
#include "memory_map/hw_memory.h"
|
||||
#include "memory_map/hw_apb_split.h"
|
||||
#include "memory_map/hw_cache.h"
|
||||
#include "memory_map/hw_pmp_hart0.h"
|
||||
#include "memory_map/hw_pmp_hart1.h"
|
||||
#include "memory_map/hw_pmp_hart2.h"
|
||||
#include "memory_map/hw_pmp_hart3.h"
|
||||
#include "memory_map/hw_pmp_hart4.h"
|
||||
#include "memory_map/hw_mpu_fic0.h"
|
||||
#include "memory_map/hw_mpu_fic1.h"
|
||||
#include "memory_map/hw_mpu_fic2.h"
|
||||
#include "memory_map/hw_mpu_crypto.h"
|
||||
#include "memory_map/hw_mpu_gem0.h"
|
||||
#include "memory_map/hw_mpu_gem1.h"
|
||||
#include "memory_map/hw_mpu_usb.h"
|
||||
#include "memory_map/hw_mpu_mmc.h"
|
||||
#include "memory_map/hw_mpu_scb.h"
|
||||
#include "memory_map/hw_mpu_trace.h"
|
||||
#include "io/hw_mssio_mux.h"
|
||||
#include "io/hw_hsio_mux.h"
|
||||
#include "sgmii/hw_sgmii_tip.h"
|
||||
#include "ddr/hw_ddr_options.h"
|
||||
#include "ddr/hw_ddr_io_bank.h"
|
||||
#include "ddr/hw_ddr_mode.h"
|
||||
#include "ddr/hw_ddr_off_mode.h"
|
||||
#include "ddr/hw_ddr_segs.h"
|
||||
#include "ddr/hw_ddrc.h"
|
||||
#include "clocks/hw_mss_clks.h"
|
||||
#include "clocks/hw_clk_sysreg.h"
|
||||
#include "clocks/hw_clk_mss_pll.h"
|
||||
#include "clocks/hw_clk_sgmii_pll.h"
|
||||
#include "clocks/hw_clk_ddr_pll.h"
|
||||
#include "clocks/hw_clk_mss_cfm.h"
|
||||
#include "clocks/hw_clk_sgmii_cfm.h"
|
||||
#include "general/hw_gen_peripherals.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* No content in this file, used for referencing header */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef FPGA_DESIGN_CONFIG_H_ */
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_gen_peripherals.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_GEN_PERIPHERALS_H_
|
||||
#define HW_GEN_PERIPHERALS_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_GPIO_CR)
|
||||
/*GPIO Blocks reset control- (soft_reset options chossen in Libero confgurator)
|
||||
*/
|
||||
#define LIBERO_SETTING_GPIO_CR 0x000F0703UL
|
||||
/* GPIO0_SOFT_RESET_SELECT [0:2] RW value= 0x3 */
|
||||
/* GPIO0_DEFAULT [4:2] RW value= 0x0 */
|
||||
/* GPIO1_SOFT_RESET_SELECT [8:3] RW value= 0x7 */
|
||||
/* GPIO1_DEFAULT [12:3] RW value= 0x0 */
|
||||
/* GPIO2_SOFT_RESET_SELECT [16:4] RW value= 0xF */
|
||||
/* GPIO2_DEFAULT [20:4] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_CRYPTO_CR_INFO)
|
||||
/*Information on how Crypto setup on this MPFS */
|
||||
#define LIBERO_SETTING_CRYPTO_CR_INFO 0x00000000UL
|
||||
/* MSS_MODE [0:2] RO */
|
||||
/* RESERVED [2:1] RO */
|
||||
/* STREAM_ENABLE [3:1] RO */
|
||||
/* RESERVED1 [4:28] RO */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_GEN_PERIPHERALS_H_ */
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_hsio_mux.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_HSIO_MUX_H_
|
||||
#define HW_HSIO_MUX_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_TRIM_OPTIONS)
|
||||
/*User trim options- set option to 1 to use */
|
||||
#define LIBERO_SETTING_TRIM_OPTIONS 0x00000000UL
|
||||
/* TRIM_DDR_OPTION [0:1] */
|
||||
/* TRIM_SGMII_OPTION [1:1] */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_IOC_REG0)
|
||||
/*Manual trim values */
|
||||
#define LIBERO_SETTING_DDR_IOC_REG0 0x00000000UL
|
||||
/* BANK_PCODE [0:6] RW value= 0x0 */
|
||||
/* BANK_NCODE [6:6] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SGMII_IOC_REG0)
|
||||
/*Manual trim values */
|
||||
#define LIBERO_SETTING_SGMII_IOC_REG0 0x00000000UL
|
||||
/* BANK_PCODE [0:6] RW value= 0x0 */
|
||||
/* BANK_NCODE [6:6] RW value= 0x0 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_HSIO_MUX_H_ */
|
||||
|
|
@ -0,0 +1,340 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_mssio_mux.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_MSSIO_MUX_H_
|
||||
#define HW_MSSIO_MUX_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_IOMUX0_CR)
|
||||
/*Selects whether the peripheral is connected to the Fabric or IOMUX structure.
|
||||
*/
|
||||
#define LIBERO_SETTING_IOMUX0_CR 0x00000F9DUL
|
||||
/* SPI0_FABRIC [0:1] RW value= 0x1 */
|
||||
/* SPI1_FABRIC [1:1] RW value= 0x0 */
|
||||
/* I2C0_FABRIC [2:1] RW value= 0x1 */
|
||||
/* I2C1_FABRIC [3:1] RW value= 0x1 */
|
||||
/* CAN0_FABRIC [4:1] RW value= 0x1 */
|
||||
/* CAN1_FABRIC [5:1] RW value= 0x0 */
|
||||
/* QSPI_FABRIC [6:1] RW value= 0x0 */
|
||||
/* MMUART0_FABRIC [7:1] RW value= 0x1 */
|
||||
/* MMUART1_FABRIC [8:1] RW value= 0x1 */
|
||||
/* MMUART2_FABRIC [9:1] RW value= 0x1 */
|
||||
/* MMUART3_FABRIC [10:1] RW value= 0x1 */
|
||||
/* MMUART4_FABRIC [11:1] RW value= 0x1 */
|
||||
/* MDIO0_FABRIC [12:1] RW value= 0x0 */
|
||||
/* MDIO1_FABRIC [13:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_IOMUX1_CR)
|
||||
/*Configures the IO Mux structure for each IO pad. 0 implies SD/SDIO, 1 implies
|
||||
EMMC, 2 implies QSPI, 3 implies SPI,4 implies USB,5 implies MMUART,6 implies
|
||||
I2C,7 implies CAN,8 implies MDIO,9 implies Miscellaneous,0xA implies Reserved
|
||||
(Equivalent to Tristate),0xB implies GPIO ,0xC implies Fabric-test,0xD implies
|
||||
Logic 0,0xE implies Logic 1, 0xF implies Tristate */
|
||||
#define LIBERO_SETTING_IOMUX1_CR 0x11111111UL
|
||||
/* PAD0 [0:4] RW value= 0x1 */
|
||||
/* PAD1 [4:4] RW value= 0x1 */
|
||||
/* PAD2 [8:4] RW value= 0x1 */
|
||||
/* PAD3 [12:4] RW value= 0x1 */
|
||||
/* PAD4 [16:4] RW value= 0x1 */
|
||||
/* PAD5 [20:4] RW value= 0x1 */
|
||||
/* PAD6 [24:4] RW value= 0x1 */
|
||||
/* PAD7 [28:4] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_IOMUX2_CR)
|
||||
/*Configures the IO Mux structure for each IO pad. 0 implies SD/SDIO, 1 implies
|
||||
EMMC, 2 implies QSPI, 3 implies SPI,4 implies USB,5 implies MMUART,6 implies
|
||||
I2C,7 implies CAN,8 implies MDIO,9 implies Miscellaneous,0xA implies Reserved
|
||||
(Equivalent to Tristate),0xB implies GPIO ,0xC implies Fabric-test,0xD implies
|
||||
Logic 0,0xE implies Logic 1, 0xF implies Tristate */
|
||||
#define LIBERO_SETTING_IOMUX2_CR 0x00FF1111UL
|
||||
/* PAD8 [0:4] RW value= 0x1 */
|
||||
/* PAD9 [4:4] RW value= 0x1 */
|
||||
/* PAD10 [8:4] RW value= 0x1 */
|
||||
/* PAD11 [12:4] RW value= 0x1 */
|
||||
/* PAD12 [16:4] RW value= 0xF */
|
||||
/* PAD13 [20:4] RW value= 0xF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_IOMUX3_CR)
|
||||
/*Configures the IO Mux structure for each IO pad. 0 implies SD/SDIO, 1 implies
|
||||
EMMC, 2 implies QSPI, 3 implies SPI,4 implies USB,5 implies MMUART,6 implies
|
||||
I2C,7 implies CAN,8 implies MDIO,9 implies Miscellaneous,0xA implies Reserved
|
||||
(Equivalent to Tristate),0xB implies GPIO ,0xC implies Fabric-test,0xD implies
|
||||
Logic 0,0xE implies Logic 1, 0xF implies Tristate */
|
||||
#define LIBERO_SETTING_IOMUX3_CR 0x44444444UL
|
||||
/* PAD14 [0:4] RW value= 0x4 */
|
||||
/* PAD15 [4:4] RW value= 0x4 */
|
||||
/* PAD16 [8:4] RW value= 0x4 */
|
||||
/* PAD17 [12:4] RW value= 0x4 */
|
||||
/* PAD18 [16:4] RW value= 0x4 */
|
||||
/* PAD19 [20:4] RW value= 0x4 */
|
||||
/* PAD20 [24:4] RW value= 0x4 */
|
||||
/* PAD21 [28:4] RW value= 0x4 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_IOMUX4_CR)
|
||||
/*Configures the IO Mux structure for each IO pad. 0 implies SD/SDIO, 1 implies
|
||||
EMMC, 2 implies QSPI, 3 implies SPI,4 implies USB,5 implies MMUART,6 implies
|
||||
I2C,7 implies CAN,8 implies MDIO,9 implies Miscellaneous,0xA implies Reserved
|
||||
(Equivalent to Tristate),0xB implies GPIO ,0xC implies Fabric-test,0xD implies
|
||||
Logic 0,0xE implies Logic 1, 0xF implies Tristate */
|
||||
#define LIBERO_SETTING_IOMUX4_CR 0x88CC4444UL
|
||||
/* PAD22 [0:4] RW value= 0x4 */
|
||||
/* PAD23 [4:4] RW value= 0x4 */
|
||||
/* PAD24 [8:4] RW value= 0x4 */
|
||||
/* PAD25 [12:4] RW value= 0x4 */
|
||||
/* PAD26 [16:4] RW value= 0xC */
|
||||
/* PAD27 [20:4] RW value= 0xC */
|
||||
/* PAD28 [24:4] RW value= 0x8 */
|
||||
/* PAD29 [28:4] RW value= 0x8 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_IOMUX5_CR)
|
||||
/*Configures the IO Mux structure for each IO pad. 0 implies SD/SDIO, 1 implies
|
||||
EMMC, 2 implies QSPI, 3 implies SPI,4 implies USB,5 implies MMUART,6 implies
|
||||
I2C,7 implies CAN,8 implies MDIO,9 implies Miscellaneous,0xA implies Reserved
|
||||
(Equivalent to Tristate),0xB implies GPIO ,0xC implies Fabric-test,0xD implies
|
||||
Logic 0,0xE implies Logic 1, 0xF implies Tristate */
|
||||
#define LIBERO_SETTING_IOMUX5_CR 0xF7772222UL
|
||||
/* PAD30 [0:4] RW value= 0x2 */
|
||||
/* PAD31 [4:4] RW value= 0x2 */
|
||||
/* PAD32 [8:4] RW value= 0x2 */
|
||||
/* PAD33 [12:4] RW value= 0x2 */
|
||||
/* PAD34 [16:4] RW value= 0x7 */
|
||||
/* PAD35 [20:4] RW value= 0x7 */
|
||||
/* PAD36 [24:4] RW value= 0x7 */
|
||||
/* PAD37 [28:4] RW value= 0xF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_IOMUX6_CR)
|
||||
/*Sets whether the MMC/SD Voltage select lines are inverted on entry to the
|
||||
IOMUX structure */
|
||||
#define LIBERO_SETTING_IOMUX6_CR 0x00000000UL
|
||||
/* VLT_SEL [0:1] RW value= 0x0 */
|
||||
/* VLT_EN [1:1] RW value= 0x0 */
|
||||
/* VLT_CMD_DIR [2:1] RW value= 0x0 */
|
||||
/* VLT_DIR_0 [3:1] RW value= 0x0 */
|
||||
/* VLT_DIR_1_3 [4:1] RW value= 0x0 */
|
||||
/* SD_LED [5:1] RW value= 0x0 */
|
||||
/* SD_VOLT_0 [6:1] RW value= 0x0 */
|
||||
/* SD_VOLT_1 [7:1] RW value= 0x0 */
|
||||
/* SD_VOLT_2 [8:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK4_CFG_CR)
|
||||
/*Configures the MSSIO block using SCB write */
|
||||
#define LIBERO_SETTING_MSSIO_BANK4_CFG_CR 0x00040A0DUL
|
||||
/* BANK_PCODE [0:6] RW value= 0xD */
|
||||
/* RESERVED0 [6:2] RW value= 0x00 */
|
||||
/* BANK_NCODE [8:6] RW value= 0xA */
|
||||
/* RESERVED1 [14:2] RW value= 0x0 */
|
||||
/* VS [16:4] RW value= 0x4 */
|
||||
/* RESERVED2 [20:12] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_0_1_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_0_1_CR 0x09280928UL
|
||||
/* IO_CFG_0 [0:16] RW value= 0x0928 */
|
||||
/* IO_CFG_1 [16:16] RW value= 0x0928 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_2_3_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_2_3_CR 0x09280928UL
|
||||
/* IO_CFG_2 [0:16] RW value= 0x0928 */
|
||||
/* IO_CFG_3 [16:16] RW value= 0x0928 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_4_5_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_4_5_CR 0x09280928UL
|
||||
/* IO_CFG_4 [0:16] RW value= 0x0928 */
|
||||
/* IO_CFG_5 [16:16] RW value= 0x0928 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_6_7_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_6_7_CR 0x09280928UL
|
||||
/* IO_CFG_6 [0:16] RW value= 0x0928 */
|
||||
/* IO_CFG_7 [16:16] RW value= 0x0928 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_8_9_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_8_9_CR 0x09280928UL
|
||||
/* IO_CFG_8 [0:16] RW value= 0x0928 */
|
||||
/* IO_CFG_9 [16:16] RW value= 0x0928 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_10_11_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_10_11_CR 0x09280928UL
|
||||
/* IO_CFG_10 [0:16] RW value= 0x0928 */
|
||||
/* IO_CFG_11 [16:16] RW value= 0x0928 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK4_IO_CFG_12_13_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK4_IO_CFG_12_13_CR 0x09280928UL
|
||||
/* IO_CFG_12 [0:16] RW value= 0x0928 */
|
||||
/* IO_CFG_13 [16:16] RW value= 0x0928 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK2_CFG_CR)
|
||||
/*Configures the MSSIO block using SCB write */
|
||||
#define LIBERO_SETTING_MSSIO_BANK2_CFG_CR 0x00080907UL
|
||||
/* BANK_PCODE [0:6] RW value= 0x7 */
|
||||
/* RESERVED0 [6:2] RW value= 0x00 */
|
||||
/* BANK_NCODE [8:6] RW value= 0x9 */
|
||||
/* RESERVED1 [14:2] RW value= 0x0 */
|
||||
/* VS [16:4] RW value= 0x8 */
|
||||
/* RESERVED2 [20:12] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_0_1_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_0_1_CR 0x08290829UL
|
||||
/* IO_CFG_0 [0:16] RW value= 0x0829 */
|
||||
/* IO_CFG_1 [16:16] RW value= 0x0829 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_2_3_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_2_3_CR 0x08290829UL
|
||||
/* IO_CFG_2 [0:16] RW value= 0x0829 */
|
||||
/* IO_CFG_3 [16:16] RW value= 0x0829 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_4_5_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_4_5_CR 0x08290829UL
|
||||
/* IO_CFG_4 [0:16] RW value= 0x0829 */
|
||||
/* IO_CFG_5 [16:16] RW value= 0x0829 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_6_7_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_6_7_CR 0x08290829UL
|
||||
/* IO_CFG_6 [0:16] RW value= 0x0829 */
|
||||
/* IO_CFG_7 [16:16] RW value= 0x0829 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_8_9_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_8_9_CR 0x08290829UL
|
||||
/* IO_CFG_8 [0:16] RW value= 0x0829 */
|
||||
/* IO_CFG_9 [16:16] RW value= 0x0829 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_10_11_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_10_11_CR 0x08290829UL
|
||||
/* IO_CFG_10 [0:16] RW value= 0x0829 */
|
||||
/* IO_CFG_11 [16:16] RW value= 0x0829 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_12_13_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_12_13_CR 0x08290829UL
|
||||
/* IO_CFG_12 [0:16] RW value= 0x0829 */
|
||||
/* IO_CFG_13 [16:16] RW value= 0x0829 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_14_15_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_14_15_CR 0x08290829UL
|
||||
/* IO_CFG_14 [0:16] RW value= 0x0829 */
|
||||
/* IO_CFG_15 [16:16] RW value= 0x0829 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_16_17_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_16_17_CR 0x08290829UL
|
||||
/* IO_CFG_16 [0:16] RW value= 0x0829 */
|
||||
/* IO_CFG_17 [16:16] RW value= 0x0829 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_18_19_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_18_19_CR 0x08290829UL
|
||||
/* IO_CFG_18 [0:16] RW value= 0x0829 */
|
||||
/* IO_CFG_19 [16:16] RW value= 0x0829 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_20_21_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_20_21_CR 0x08290829UL
|
||||
/* IO_CFG_20 [0:16] RW value= 0x0829 */
|
||||
/* IO_CFG_21 [16:16] RW value= 0x0829 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_BANK2_IO_CFG_22_23_CR)
|
||||
/*IO electrical configuration for MSSIO pad */
|
||||
#define LIBERO_SETTING_MSSIO_BANK2_IO_CFG_22_23_CR 0x08290829UL
|
||||
/* IO_CFG_22 [0:16] RW value= 0x0829 */
|
||||
/* IO_CFG_23 [16:16] RW value= 0x0829 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_VB2_CFG)
|
||||
/*default dpc values for MSSIO bank 2 */
|
||||
#define LIBERO_SETTING_MSSIO_VB2_CFG 0x00000828UL
|
||||
/* DPC_IO_CFG_IBUFMD_0 [0:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_IBUFMD_1 [1:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_IBUFMD_2 [2:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_DRV_0 [3:1] RW value= 0x1 */
|
||||
/* DPC_IO_CFG_DRV_1 [4:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_DRV_2 [5:1] RW value= 0x1 */
|
||||
/* DPC_IO_CFG_DRV_3 [6:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_CLAMP [7:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_ENHYST [8:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_LOCKDN_EN [9:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_WPD [10:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_WPU [11:1] RW value= 0x1 */
|
||||
/* DPC_IO_CFG_ATP_EN [12:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_LP_PERSIST_EN [13:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_LP_BYPASS_EN [14:1] RW value= 0x0 */
|
||||
/* RESERVED [15:17] R */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_VB4_CFG)
|
||||
/*default dpc values for MSSIO bank 4 */
|
||||
#define LIBERO_SETTING_MSSIO_VB4_CFG 0x00000828UL
|
||||
/* DPC_IO_CFG_IBUFMD_0 [0:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_IBUFMD_1 [1:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_IBUFMD_2 [2:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_DRV_0 [3:1] RW value= 0x1 */
|
||||
/* DPC_IO_CFG_DRV_1 [4:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_DRV_2 [5:1] RW value= 0x1 */
|
||||
/* DPC_IO_CFG_DRV_3 [6:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_CLAMP [7:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_ENHYST [8:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_LOCKDN_EN [9:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_WPD [10:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_WPU [11:1] RW value= 0x1 */
|
||||
/* DPC_IO_CFG_ATP_EN [12:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_LP_PERSIST_EN [13:1] RW value= 0x0 */
|
||||
/* DPC_IO_CFG_LP_BYPASS_EN [14:1] RW value= 0x0 */
|
||||
/* RESERVED [15:17] R */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS)
|
||||
/*Indicates if eMMC is configured for use (bit 0 == 1), If SD is configued for
|
||||
use (bit 1 == 1). Bit 2 indicates which one should be used by default on MSS
|
||||
embedded software startup ( bit2 == 0, implies default is eMMC, bit2 == 1,
|
||||
implies default is SD). The eMMC configuration is always defined in xml tag
|
||||
(io_mux, the SD configuration is always defined in xml tag (io_mux_alt). All
|
||||
other elements in the (o_mux) and (io_mux_alt) not releating to eMMC/SD
|
||||
differences should be the same values. */
|
||||
#define LIBERO_SETTING_MSSIO_CONFIGURATION_OPTIONS 0x00000000UL
|
||||
/* EMMC_CONFIGURED [0:1] RW value= 0x0 */
|
||||
/* SD_CONFIGURED [1:1] RW value= 0x0 */
|
||||
/* DEFAULT_ON_START [2:1] RW value= 0x0 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_MSSIO_MUX_H_ */
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_apb_split.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_APB_SPLIT_H_
|
||||
#define HW_APB_SPLIT_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_APB_SPLIT_VERSION)
|
||||
/*This version incrments when change to format of this file */
|
||||
#define LIBERO_SETTING_APB_SPLIT_VERSION 0x00000001UL
|
||||
/* VERSION [0:32] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MEM_CONFIGS_ENABLED)
|
||||
/*Enabled in configurator when bit set to 1 */
|
||||
#define LIBERO_SETTING_MEM_CONFIGS_ENABLED 0x00000003UL
|
||||
/* PMP [0:0] RW value= 0x1 */
|
||||
/* MPU [1:0] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_APBBUS_CR)
|
||||
/*AMP Mode peripheral mapping register. When the register bit is '0' the
|
||||
peripheral is mapped into the 0x2000000 address range using AXI bus 5 from the
|
||||
Coreplex. When the register bit is '1' the peripheral is mapped into the
|
||||
0x28000000 address range using AXI bus 6 from the Coreplex. */
|
||||
#define LIBERO_SETTING_APBBUS_CR 0x0012A818UL
|
||||
/* MMUART0 [0:1] RW value= 0x0 */
|
||||
/* MMUART1 [1:1] RW value= 0x0 */
|
||||
/* MMUART2 [2:1] RW value= 0x0 */
|
||||
/* MMUART3 [3:1] RW value= 0x1 */
|
||||
/* MMUART4 [4:1] RW value= 0x1 */
|
||||
/* WDOG0 [5:1] RW value= 0x0 */
|
||||
/* WDOG1 [6:1] RW value= 0x0 */
|
||||
/* WDOG2 [7:1] RW value= 0x0 */
|
||||
/* WDOG3 [8:1] RW value= 0x0 */
|
||||
/* WDOG4 [9:1] RW value= 0x0 */
|
||||
/* SPI0 [10:1] RW value= 0x0 */
|
||||
/* SPI1 [11:1] RW value= 0x1 */
|
||||
/* I2C0 [12:1] RW value= 0x0 */
|
||||
/* I2C1 [13:1] RW value= 0x1 */
|
||||
/* CAN0 [14:1] RW value= 0x0 */
|
||||
/* CAN1 [15:1] RW value= 0x1 */
|
||||
/* GEM0 [16:1] RW value= 0x0 */
|
||||
/* GEM1 [17:1] RW value= 0x1 */
|
||||
/* TIMER [18:1] RW value= 0x0 */
|
||||
/* GPIO0 [19:1] RW value= 0x0 */
|
||||
/* GPIO1 [20:1] RW value= 0x1 */
|
||||
/* GPIO2 [21:1] RW value= 0x0 */
|
||||
/* RTC [22:1] RW value= 0x0 */
|
||||
/* H2FINT [23:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_CONTEXT_A_EN)
|
||||
/*AMP context A. When the register bit is '0' the peripheral is not allowed
|
||||
access from context A. */
|
||||
#define LIBERO_SETTING_CONTEXT_A_EN 0x4F695406UL
|
||||
/* MMUART0 [0:1] RW value= 0x0 */
|
||||
/* MMUART1 [1:1] RW value= 0x1 */
|
||||
/* MMUART2 [2:1] RW value= 0x1 */
|
||||
/* MMUART3 [3:1] RW value= 0x0 */
|
||||
/* MMUART4 [4:1] RW value= 0x0 */
|
||||
/* WDOG0 [5:1] RW value= 0x0 */
|
||||
/* WDOG1 [6:1] RW value= 0x0 */
|
||||
/* WDOG2 [7:1] RW value= 0x0 */
|
||||
/* WDOG3 [8:1] RW value= 0x0 */
|
||||
/* WDOG4 [9:1] RW value= 0x0 */
|
||||
/* SPI0 [10:1] RW value= 0x1 */
|
||||
/* SPI1 [11:1] RW value= 0x0 */
|
||||
/* I2C0 [12:1] RW value= 0x1 */
|
||||
/* I2C1 [13:1] RW value= 0x0 */
|
||||
/* CAN0 [14:1] RW value= 0x1 */
|
||||
/* CAN1 [15:1] RW value= 0x0 */
|
||||
/* GEM0 [16:1] RW value= 0x1 */
|
||||
/* GEM1 [17:1] RW value= 0x0 */
|
||||
/* TIMER [18:1] RW value= 0x0 */
|
||||
/* GPIO0 [19:1] RW value= 0x1 */
|
||||
/* GPIO1 [20:1] RW value= 0x0 */
|
||||
/* GPIO2 [21:1] RW value= 0x1 */
|
||||
/* RTC [22:1] RW value= 0x1 */
|
||||
/* H2FINT [23:1] RW value= 0x0 */
|
||||
/* CRYPTO [24:1] RW value= 0x1 */
|
||||
/* USB [25:1] RW value= 0x1 */
|
||||
/* QSPIXIP [26:1] RW value= 0x1 */
|
||||
/* ATHENA [27:1] RW value= 0x1 */
|
||||
/* TRACE [28:1] RW value= 0x0 */
|
||||
/* MAILBOX_SC [29:1] RW value= 0x0 */
|
||||
/* EMMC [30:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_CONTEXT_B_EN)
|
||||
/*AMP context B. When the register bit is '0' the peripheral is not allowed
|
||||
access from context B. */
|
||||
#define LIBERO_SETTING_CONTEXT_B_EN 0x0012A818UL
|
||||
/* MMUART0 [0:1] RW value= 0x0 */
|
||||
/* MMUART1 [1:1] RW value= 0x0 */
|
||||
/* MMUART2 [2:1] RW value= 0x0 */
|
||||
/* MMUART3 [3:1] RW value= 0x1 */
|
||||
/* MMUART4 [4:1] RW value= 0x1 */
|
||||
/* WDOG0 [5:1] RW value= 0x0 */
|
||||
/* WDOG1 [6:1] RW value= 0x0 */
|
||||
/* WDOG2 [7:1] RW value= 0x0 */
|
||||
/* WDOG3 [8:1] RW value= 0x0 */
|
||||
/* WDOG4 [9:1] RW value= 0x0 */
|
||||
/* SPI0 [10:1] RW value= 0x0 */
|
||||
/* SPI1 [11:1] RW value= 0x1 */
|
||||
/* I2C0 [12:1] RW value= 0x0 */
|
||||
/* I2C1 [13:1] RW value= 0x1 */
|
||||
/* CAN0 [14:1] RW value= 0x0 */
|
||||
/* CAN1 [15:1] RW value= 0x1 */
|
||||
/* GEM0 [16:1] RW value= 0x0 */
|
||||
/* GEM1 [17:1] RW value= 0x1 */
|
||||
/* TIMER [18:1] RW value= 0x0 */
|
||||
/* GPIO0 [19:1] RW value= 0x0 */
|
||||
/* GPIO1 [20:1] RW value= 0x1 */
|
||||
/* GPIO2 [21:1] RW value= 0x0 */
|
||||
/* RTC [22:1] RW value= 0x0 */
|
||||
/* H2FINT [23:1] RW value= 0x0 */
|
||||
/* CRYPTO [24:1] RW value= 0x0 */
|
||||
/* USB [25:1] RW value= 0x0 */
|
||||
/* QSPIXIP [26:1] RW value= 0x0 */
|
||||
/* ATHENA [27:1] RW value= 0x0 */
|
||||
/* TRACE [28:1] RW value= 0x0 */
|
||||
/* MAILBOX_SC [29:1] RW value= 0x0 */
|
||||
/* EMMC [30:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_CONTEXT_A_HART_EN)
|
||||
/*When the register bit is '0' hart is not associated with context A. */
|
||||
#define LIBERO_SETTING_CONTEXT_A_HART_EN 0x00000006UL
|
||||
/* HART0 [0:1] RW value= 0x0 */
|
||||
/* HART1 [1:1] RW value= 0x1 */
|
||||
/* HART2 [2:1] RW value= 0x1 */
|
||||
/* HART3 [3:1] RW value= 0x0 */
|
||||
/* HART4 [4:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_CONTEXT_B_HART_EN)
|
||||
/*When the register bit is '0' hart is not associated with context B. */
|
||||
#define LIBERO_SETTING_CONTEXT_B_HART_EN 0x00000018UL
|
||||
/* HART0 [0:1] RW value= 0x0 */
|
||||
/* HART1 [1:1] RW value= 0x0 */
|
||||
/* HART2 [2:1] RW value= 0x0 */
|
||||
/* HART3 [3:1] RW value= 0x1 */
|
||||
/* HART4 [4:1] RW value= 0x1 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_APB_SPLIT_H_ */
|
||||
|
|
@ -0,0 +1,436 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_cache.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_CACHE_H_
|
||||
#define HW_CACHE_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_WAY_ENABLE)
|
||||
/*Way indexes less than or equal to this register value may be used by the
|
||||
cache. E.g. set to 0x7, will allocate 8 cache ways, 0-7 to cache, and leave
|
||||
8-15 as LIM. Note 1: Way 0 is always allocated as cache. Note 2: each way is
|
||||
128KB. */
|
||||
#define LIBERO_SETTING_WAY_ENABLE 0x0000000BUL
|
||||
/* WAY_ENABLE [0:8] RW value= 0xB */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_DMA)
|
||||
/*Way mask register master DMA. Set field to zero to disable way from this
|
||||
master. The available cache ways are 0 to number set in WAY_ENABLE register. If
|
||||
using scratch pad memory, the ways you want reserved for scrathpad are not
|
||||
available for selection, you must set to 0. e.g. If three ways reserved for
|
||||
scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
|
||||
masters, so they can not evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_DMA 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_0)
|
||||
/*Way mask register master DMA. Set field to zero to disable way from this
|
||||
master. The available cache ways are 0 to number set in WAY_ENABLE register. If
|
||||
using scratch pad memory, the ways you want reserved for scrathpad are not
|
||||
available for selection, you must set to 0. e.g. If three ways reserved for
|
||||
scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
|
||||
masters, so they can not evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_0 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_1)
|
||||
/*Way mask register master DMA. Set field to zero to disable way from this
|
||||
master. The available cache ways are 0 to number set in WAY_ENABLE register. If
|
||||
using scratch pad memory, the ways you want reserved for scrathpad are not
|
||||
available for selection, you must set to 0. e.g. If three ways reserved for
|
||||
scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
|
||||
masters, so they can not evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_1 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_2)
|
||||
/*Way mask registerAXI slave port 2. Set field to zero to disable way from this
|
||||
master. The available cache ways are 0 to number set in WAY_ENABLE register. If
|
||||
using scratch pad memory, the ways you want reserved for scrathpad are not
|
||||
available for selection, you must set to 0. e.g. If three ways reserved for
|
||||
scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for all
|
||||
masters, so they can not evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_2 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_AXI4_PORT_3)
|
||||
/*Way mask register AXI slave port 3. Set field to 1 to disable way from this
|
||||
master. Set field to zero to disable way from this master. The available cache
|
||||
ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
|
||||
the ways you want reserved for scrathpad are not available for selection, you
|
||||
must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
|
||||
WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
|
||||
evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_AXI4_PORT_3 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_E51_DCACHE)
|
||||
/*Way mask register E51 data cache (hart0). Set field to zero to disable way
|
||||
from this master. The available cache ways are 0 to number set in WAY_ENABLE
|
||||
register. If using scratch pad memory, the ways you want reserved for scrathpad
|
||||
are not available for selection, you must set to 0. e.g. If three ways reserved
|
||||
for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
|
||||
all masters, so they can not evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_E51_DCACHE 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_E51_ICACHE)
|
||||
/*Way mask registerE52 instruction cache (hart0). Set field to zero to disable
|
||||
way from this master. The available cache ways are 0 to number set in
|
||||
WAY_ENABLE register. If using scratch pad memory, the ways you want reserved
|
||||
for scrathpad are not available for selection, you must set to 0. e.g. If three
|
||||
ways reserved for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set
|
||||
to zero for all masters, so they can not evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_E51_ICACHE 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_U54_1_DCACHE)
|
||||
/*Way mask register data cache (hart1). Set field to zero to disable way from
|
||||
this master. The available cache ways are 0 to number set in WAY_ENABLE
|
||||
register. If using scratch pad memory, the ways you want reserved for scrathpad
|
||||
are not available for selection, you must set to 0. e.g. If three ways reserved
|
||||
for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
|
||||
all masters, so they can not evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_U54_1_DCACHE 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_U54_1_ICACHE)
|
||||
/*Way mask register instruction cache (hart1). Set field to zero to disable way
|
||||
from this master. The available cache ways are 0 to number set in WAY_ENABLE
|
||||
register. If using scratch pad memory, the ways you want reserved for scrathpad
|
||||
are not available for selection, you must set to 0. e.g. If three ways reserved
|
||||
for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
|
||||
all masters, so they can not evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_U54_1_ICACHE 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_U54_2_DCACHE)
|
||||
/*Way mask register data cache (hart2). Set field to 1 to disable way from this
|
||||
master. Set field to zero to disable way from this master. The available cache
|
||||
ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
|
||||
the ways you want reserved for scrathpad are not available for selection, you
|
||||
must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
|
||||
WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
|
||||
evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_U54_2_DCACHE 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_U54_2_ICACHE)
|
||||
/*Way mask register instruction cache (hart2). Set field to zero to disable way
|
||||
from this master. The available cache ways are 0 to number set in WAY_ENABLE
|
||||
register. If using scratch pad memory, the ways you want reserved for scrathpad
|
||||
are not available for selection, you must set to 0. e.g. If three ways reserved
|
||||
for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
|
||||
all masters, so they can not evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_U54_2_ICACHE 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_U54_3_DCACHE)
|
||||
/*Way mask register data cache (hart3). Set field to 1 to disable way from this
|
||||
master.Set field to zero to disable way from this master. The available cache
|
||||
ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
|
||||
the ways you want reserved for scrathpad are not available for selection, you
|
||||
must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
|
||||
WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
|
||||
evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_U54_3_DCACHE 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_U54_3_ICACHE)
|
||||
/*Way mask register instruction cache(hart3). Set field to zero to disable way
|
||||
from this master. The available cache ways are 0 to number set in WAY_ENABLE
|
||||
register. If using scratch pad memory, the ways you want reserved for scrathpad
|
||||
are not available for selection, you must set to 0. e.g. If three ways reserved
|
||||
for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
|
||||
all masters, so they can not evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_U54_3_ICACHE 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_U54_4_DCACHE)
|
||||
/*Way mask register data cache (hart4). Set field to 1 to disable way from this
|
||||
master. Set field to zero to disable way from this master. The available cache
|
||||
ways are 0 to number set in WAY_ENABLE register. If using scratch pad memory,
|
||||
the ways you want reserved for scrathpad are not available for selection, you
|
||||
must set to 0. e.g. If three ways reserved for scratchpad, WAY_MASK_0,
|
||||
WAY_MASK_1 and WAY_MASK_2 will be set to zero for all masters, so they can not
|
||||
evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_U54_4_DCACHE 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_WAY_MASK_U54_4_ICACHE)
|
||||
/*Way mask register instruction cache (hart4). Set field to zero to disable way
|
||||
from this master. The available cache ways are 0 to number set in WAY_ENABLE
|
||||
register. If using scratch pad memory, the ways you want reserved for scrathpad
|
||||
are not available for selection, you must set to 0. e.g. If three ways reserved
|
||||
for scratchpad, WAY_MASK_0, WAY_MASK_1 and WAY_MASK_2 will be set to zero for
|
||||
all masters, so they can not evict the way. */
|
||||
#define LIBERO_SETTING_WAY_MASK_U54_4_ICACHE 0x0000F0FFUL
|
||||
/* WAY_MASK_0 [0:1] RW value= 0x1 */
|
||||
/* WAY_MASK_1 [1:1] RW value= 0x1 */
|
||||
/* WAY_MASK_2 [2:1] RW value= 0x1 */
|
||||
/* WAY_MASK_3 [3:1] RW value= 0x1 */
|
||||
/* WAY_MASK_4 [4:1] RW value= 0x1 */
|
||||
/* WAY_MASK_5 [5:1] RW value= 0x1 */
|
||||
/* WAY_MASK_6 [6:1] RW value= 0x1 */
|
||||
/* WAY_MASK_7 [7:1] RW value= 0x1 */
|
||||
/* WAY_MASK_8 [8:1] RW value= 0x0 */
|
||||
/* WAY_MASK_9 [9:1] RW value= 0x0 */
|
||||
/* WAY_MASK_10 [10:1] RW value= 0x0 */
|
||||
/* WAY_MASK_11 [11:1] RW value= 0x0 */
|
||||
/* WAY_MASK_12 [12:1] RW value= 0x1 */
|
||||
/* WAY_MASK_13 [13:1] RW value= 0x1 */
|
||||
/* WAY_MASK_14 [14:1] RW value= 0x1 */
|
||||
/* WAY_MASK_15 [15:1] RW value= 0x1 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS)
|
||||
/*Number of ways reserved for scratchpad. Note 1: This is not a register Note
|
||||
2: each way is 128KB. Note 3: Embedded software expects cache ways allocated
|
||||
for scratchpad start at way 0, and work up. */
|
||||
#define LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS 0x00000004UL
|
||||
/* NUM_OF_WAYS [0:8] RW value= 0x4 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_CACHE_H_ */
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_memory.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_MEMORY_H_
|
||||
#define HW_MEMORY_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_RESET_VECTOR_HART0)
|
||||
/*Reset vector hart0 */
|
||||
#define LIBERO_SETTING_RESET_VECTOR_HART0 0x20220000
|
||||
#define LIBERO_SETTING_RESET_VECTOR_HART0_SIZE 0x4 /* Length of memory block*/
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RESET_VECTOR_HART1)
|
||||
/*Reset vector hart1 */
|
||||
#define LIBERO_SETTING_RESET_VECTOR_HART1 0x20220000
|
||||
#define LIBERO_SETTING_RESET_VECTOR_HART1_SIZE 0x4 /* Length of memory block*/
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RESET_VECTOR_HART2)
|
||||
/*Reset vector hart2 */
|
||||
#define LIBERO_SETTING_RESET_VECTOR_HART2 0x20220000
|
||||
#define LIBERO_SETTING_RESET_VECTOR_HART2_SIZE 0x4 /* Length of memory block*/
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RESET_VECTOR_HART3)
|
||||
/*Reset vector hart3 */
|
||||
#define LIBERO_SETTING_RESET_VECTOR_HART3 0x20220000
|
||||
#define LIBERO_SETTING_RESET_VECTOR_HART3_SIZE 0x4 /* Length of memory block*/
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RESET_VECTOR_HART4)
|
||||
/*Reset vector hart4 */
|
||||
#define LIBERO_SETTING_RESET_VECTOR_HART4 0x20220000
|
||||
#define LIBERO_SETTING_RESET_VECTOR_HART4_SIZE 0x4 /* Length of memory block*/
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_32_CACHE)
|
||||
/*example instance of memory */
|
||||
#define LIBERO_SETTING_DDR_32_CACHE 0x80000000
|
||||
#define LIBERO_SETTING_DDR_32_CACHE_SIZE 0x100000 /* Length of memory block*/
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_32_NON_CACHE)
|
||||
/*example instance */
|
||||
#define LIBERO_SETTING_DDR_32_NON_CACHE 0xC0000000
|
||||
#define LIBERO_SETTING_DDR_32_NON_CACHE_SIZE 0x100000 /* Length of memory block*/
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_64_CACHE)
|
||||
/*64 bit address */
|
||||
#define LIBERO_SETTING_DDR_64_CACHE 0x1000000000
|
||||
#define LIBERO_SETTING_DDR_64_CACHE_SIZE 0x100000 /* Length of memory block*/
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_64_NON_CACHE)
|
||||
/*64 bit address */
|
||||
#define LIBERO_SETTING_DDR_64_NON_CACHE 0x1400000000
|
||||
#define LIBERO_SETTING_DDR_64_NON_CACHE_SIZE 0x100000 /* Length of memory block*/
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_32_WCB)
|
||||
/*example instance */
|
||||
#define LIBERO_SETTING_DDR_32_WCB 0xD0000000
|
||||
#define LIBERO_SETTING_DDR_32_WCB_SIZE 0x100000 /* Length of memory block*/
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DDR_64_WCB)
|
||||
/*64 bit address */
|
||||
#define LIBERO_SETTING_DDR_64_WCB 0x1800000000
|
||||
#define LIBERO_SETTING_DDR_64_WCB_SIZE 0x100000 /* Length of memory block*/
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RESERVED_SNVM)
|
||||
/*Offset and size of reserved sNVM. (Not available to MSS) */
|
||||
#define LIBERO_SETTING_RESERVED_SNVM 0x00000000
|
||||
#define LIBERO_SETTING_RESERVED_SNVM_SIZE 0x00000000 /* Length of memory block*/
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RESERVED_ENVM)
|
||||
/*Offset and size of reserved eNVM (Not available to MSS) */
|
||||
#define LIBERO_SETTING_RESERVED_ENVM 0x00000000
|
||||
#define LIBERO_SETTING_RESERVED_ENVM_SIZE 0x00000000 /* Length of memory block*/
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_MEMORY_H_ */
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_mpu_crypto.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_MPU_CRYPTO_H_
|
||||
#define HW_MPU_CRYPTO_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_CRYPTO_MPU_CFG_PMP0)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_CRYPTO_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_CRYPTO_MPU_CFG_PMP1)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_CRYPTO_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_CRYPTO_MPU_CFG_PMP2)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_CRYPTO_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_CRYPTO_MPU_CFG_PMP3)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_CRYPTO_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_MPU_CRYPTO_H_ */
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_mpu_fic0.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_MPU_FIC0_H_
|
||||
#define HW_MPU_FIC0_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP0)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP1)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP2)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP3)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP4)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP4 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP5)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP5 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP6)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP6 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP7)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP7 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP8)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP8 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP9)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP9 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP10)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP10 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP11)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP11 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP12)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP12 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP13)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP13 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP14)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP14 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC0_MPU_CFG_PMP15)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC0_MPU_CFG_PMP15 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_MPU_FIC0_H_ */
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_mpu_fic1.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_MPU_FIC1_H_
|
||||
#define HW_MPU_FIC1_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP0)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP1)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP2)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP3)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP4)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP4 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP5)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP5 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP6)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP6 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP7)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP7 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP8)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP8 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP9)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP9 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP10)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP10 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP11)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP11 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP12)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP12 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP13)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP13 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP14)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP14 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC1_MPU_CFG_PMP15)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC1_MPU_CFG_PMP15 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_MPU_FIC1_H_ */
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_mpu_fic2.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_MPU_FIC2_H_
|
||||
#define HW_MPU_FIC2_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP0)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC2_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP1)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC2_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP2)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC2_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP3)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC2_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP4)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC2_MPU_CFG_PMP4 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP5)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC2_MPU_CFG_PMP5 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP6)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC2_MPU_CFG_PMP6 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_FIC2_MPU_CFG_PMP7)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_FIC2_MPU_CFG_PMP7 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_MPU_FIC2_H_ */
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_mpu_gem0.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_MPU_GEM0_H_
|
||||
#define HW_MPU_GEM0_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP0)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM0_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP1)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM0_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP2)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM0_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP3)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM0_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP4)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM0_MPU_CFG_PMP4 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP5)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM0_MPU_CFG_PMP5 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP6)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM0_MPU_CFG_PMP6 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM0_MPU_CFG_PMP7)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM0_MPU_CFG_PMP7 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_MPU_GEM0_H_ */
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_mpu_gem1.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_MPU_GEM1_H_
|
||||
#define HW_MPU_GEM1_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP0)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM1_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP1)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM1_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP2)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM1_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP3)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM1_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP4)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM1_MPU_CFG_PMP4 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP5)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM1_MPU_CFG_PMP5 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP6)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM1_MPU_CFG_PMP6 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_GEM1_MPU_CFG_PMP7)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_GEM1_MPU_CFG_PMP7 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_MPU_GEM1_H_ */
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_mpu_mmc.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_MPU_MMC_H_
|
||||
#define HW_MPU_MMC_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_MMC_MPU_CFG_PMP0)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_MMC_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MMC_MPU_CFG_PMP1)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_MMC_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MMC_MPU_CFG_PMP2)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_MMC_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_MMC_MPU_CFG_PMP3)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_MMC_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_MPU_MMC_H_ */
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_mpu_scb.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_MPU_SCB_H_
|
||||
#define HW_MPU_SCB_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP0)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_SCB_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP1)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_SCB_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP2)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_SCB_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP3)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_SCB_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP4)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_SCB_MPU_CFG_PMP4 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP5)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_SCB_MPU_CFG_PMP5 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP6)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_SCB_MPU_CFG_PMP6 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SCB_MPU_CFG_PMP7)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_SCB_MPU_CFG_PMP7 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_MPU_SCB_H_ */
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_mpu_trace.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_MPU_TRACE_H_
|
||||
#define HW_MPU_TRACE_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_TRACE_MPU_CFG_PMP0)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_TRACE_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_TRACE_MPU_CFG_PMP1)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_TRACE_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_MPU_TRACE_H_ */
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_mpu_usb.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_MPU_USB_H_
|
||||
#define HW_MPU_USB_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_USB_MPU_CFG_PMP0)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_USB_MPU_CFG_PMP0 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_USB_MPU_CFG_PMP1)
|
||||
/*mpu setup register, 64 bits */
|
||||
#define LIBERO_SETTING_USB_MPU_CFG_PMP1 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_USB_MPU_CFG_PMP2)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_USB_MPU_CFG_PMP2 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_USB_MPU_CFG_PMP3)
|
||||
/*pmp setup register, 64 bits */
|
||||
#define LIBERO_SETTING_USB_MPU_CFG_PMP3 0x1F00000FFFFFFFFFULL
|
||||
/* PMP [0:38] RW value= 0xFFFFFFFFF */
|
||||
/* RESERVED [38:18] RW value= 0x0 */
|
||||
/* MODE [56:8] RW value= 0x1F */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_MPU_USB_H_ */
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_pmp_hart0.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_PMP_HART0_H_
|
||||
#define HW_PMP_HART0_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPCFG0)
|
||||
/*PMP configuration for 8 adress regions, bit 0 read, bit 1 write, bit 2
|
||||
execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPCFG0 0x0000000000000000ULL
|
||||
/* PMP0CFG [0:8] RW value= 0x00 */
|
||||
/* PMP1CFG [8:8] RW value= 0x0 */
|
||||
/* PMP2CFG [16:8] RW value= 0x00 */
|
||||
/* PMP3CFG [24:8] RW value= 0x00 */
|
||||
/* PMP4CFG [32:8] RW value= 0x00 */
|
||||
/* PMP5CFG [40:8] RW value= 0x00 */
|
||||
/* PMP6CFG [48:8] RW value= 0x00 */
|
||||
/* PMP7CFG [56:8] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPCFG2)
|
||||
/*PMP configuration for 8 address regions, bit 0 read, bit 1 write, bit 2
|
||||
execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPCFG2 0x0000000000000000ULL
|
||||
/* PMP8CFG [0:8] RW value= 0x00 */
|
||||
/* PMP9CFG [8:8] RW value= 0x00 */
|
||||
/* PMP10CFG [16:8] RW value= 0x00 */
|
||||
/* PMP11CFG [24:8] RW value= 0x00 */
|
||||
/* PMP12CFG [32:8] RW value= 0x00 */
|
||||
/* PMP13CFG [40:8] RW value= 0x00 */
|
||||
/* PMP14CFG [48:8] RW value= 0x00 */
|
||||
/* PMP15CFG [56:8] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR0)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR0 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR0 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR1)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR1 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR1 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR2)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR2 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR2 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR3)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR3 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR3 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR4)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR4 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR4 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR5)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR5 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR5 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR6)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR6 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR6 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR7)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR7 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR7 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR8)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR8 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR8 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR9)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR9 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR9 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR10)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR10 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR10 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR11)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR11 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR11 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR12)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR12 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR12 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR13)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR13 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR13 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR14)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR14 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR14 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART0_CSR_PMPADDR15)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART0_CSR_PMPADDR15 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR15 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_PMP_HART0_H_ */
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_pmp_hart1.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_PMP_HART1_H_
|
||||
#define HW_PMP_HART1_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPCFG0)
|
||||
/*PMP configuration for 8 adress regions, bit 0 read, bit 1 write, bit 2
|
||||
execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPCFG0 0x9B9B9B9B00000000ULL
|
||||
/* PMP0CFG [0:8] RW value= 0x00 */
|
||||
/* PMP1CFG [8:8] RW value= 0x00 */
|
||||
/* PMP2CFG [16:8] RW value= 0x00 */
|
||||
/* PMP3CFG [24:8] RW value= 0x00 */
|
||||
/* PMP4CFG [32:8] RW value= 0x9B */
|
||||
/* PMP5CFG [40:8] RW value= 0x9B */
|
||||
/* PMP6CFG [48:8] RW value= 0x9B */
|
||||
/* PMP7CFG [56:8] RW value= 0x9B */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPCFG2)
|
||||
/*PMP configuration for 8 address regions, bit 0 read, bit 1 write, bit 2
|
||||
execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPCFG2 0x00989B9B9F9B9B9BULL
|
||||
/* PMP8CFG [0:8] RW value= 0x9B */
|
||||
/* PMP9CFG [8:8] RW value= 0x9B */
|
||||
/* PMP10CFG [16:8] RW value= 0x9B */
|
||||
/* PMP11CFG [24:8] RW value= 0x9F */
|
||||
/* PMP12CFG [32:8] RW value= 0x9B */
|
||||
/* PMP13CFG [40:8] RW value= 0x9B */
|
||||
/* PMP14CFG [48:8] RW value= 0x98 */
|
||||
/* PMP15CFG [56:8] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR0)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR0 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR0 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR1)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR1 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR1 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR2)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR2 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR2 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR3)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR3 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR3 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR4)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR4 0x0000000008047FFFULL
|
||||
/* CSR_PMPADDR4 [0:64] RW value= 0x8047FFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR5)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR5 0x000000000307FFFFULL
|
||||
/* CSR_PMPADDR5 [0:64] RW value= 0x307FFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR6)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR6 0x00000000080009FFULL
|
||||
/* CSR_PMPADDR6 [0:64] RW value= 0x80009FF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR7)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR7 0x00000000080021FFULL
|
||||
/* CSR_PMPADDR7 [0:64] RW value= 0x80021FF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR8)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR8 0x00000000080805FFULL
|
||||
/* CSR_PMPADDR8 [0:64] RW value= 0x80805FF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR9)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR9 0x00000000085FFFFFULL
|
||||
/* CSR_PMPADDR9 [0:64] RW value= 0x85FFFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR10)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR10 0x0000000008803FFFULL
|
||||
/* CSR_PMPADDR10 [0:64] RW value= 0x8803FFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR11)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR11 0x000000002003FFFFULL
|
||||
/* CSR_PMPADDR11 [0:64] RW value= 0x2003FFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR12)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR12 0x00000000008041FFULL
|
||||
/* CSR_PMPADDR12 [0:64] RW value= 0x8041FF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR13)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR13 0x0000000000801FFFULL
|
||||
/* CSR_PMPADDR13 [0:64] RW value= 0x801FFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR14)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR14 0xFFFFFFFFFFFFFFFFULL
|
||||
/* CSR_PMPADDR14 [0:64] RW value= 0xFFFFFFFFFFFFFFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART1_CSR_PMPADDR15)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART1_CSR_PMPADDR15 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR15 [0:64] RW value= 0x0 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_PMP_HART1_H_ */
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_pmp_hart2.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_PMP_HART2_H_
|
||||
#define HW_PMP_HART2_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPCFG0)
|
||||
/*PMP configuration for 8 adress regions, bit 0 read, bit 1 write, bit 2
|
||||
execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPCFG0 0x9B9B9B9B00000000ULL
|
||||
/* PMP0CFG [0:8] RW value= 0x00 */
|
||||
/* PMP1CFG [8:8] RW value= 0x00 */
|
||||
/* PMP2CFG [16:8] RW value= 0x00 */
|
||||
/* PMP3CFG [24:8] RW value= 0x00 */
|
||||
/* PMP4CFG [32:8] RW value= 0x9B */
|
||||
/* PMP5CFG [40:8] RW value= 0x9B */
|
||||
/* PMP6CFG [48:8] RW value= 0x9B */
|
||||
/* PMP7CFG [56:8] RW value= 0x9B */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPCFG2)
|
||||
/*PMP configuration for 8 address regions, bit 0 read, bit 1 write, bit 2
|
||||
execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPCFG2 0x00989B9B9F9B9B9BULL
|
||||
/* PMP8CFG [0:8] RW value= 0x9B */
|
||||
/* PMP9CFG [8:8] RW value= 0x9B */
|
||||
/* PMP10CFG [16:8] RW value= 0x9B */
|
||||
/* PMP11CFG [24:8] RW value= 0x9F */
|
||||
/* PMP12CFG [32:8] RW value= 0x9B */
|
||||
/* PMP13CFG [40:8] RW value= 0x9B */
|
||||
/* PMP14CFG [48:8] RW value= 0x98 */
|
||||
/* PMP15CFG [56:8] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR0)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR0 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR0 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR1)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR1 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR1 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR2)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR2 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR2 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR3)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR3 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR3 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR4)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR4 0x0000000008047FFFULL
|
||||
/* CSR_PMPADDR4 [0:64] RW value= 0x8047FFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR5)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR5 0x000000000307FFFFULL
|
||||
/* CSR_PMPADDR5 [0:64] RW value= 0x307FFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR6)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR6 0x00000000080009FFULL
|
||||
/* CSR_PMPADDR6 [0:64] RW value= 0x80009FF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR7)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR7 0x00000000080021FFULL
|
||||
/* CSR_PMPADDR7 [0:64] RW value= 0x80021FF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR8)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR8 0x00000000080805FFULL
|
||||
/* CSR_PMPADDR8 [0:64] RW value= 0x80805FF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR9)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR9 0x00000000085FFFFFULL
|
||||
/* CSR_PMPADDR9 [0:64] RW value= 0x85FFFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR10)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR10 0x0000000008803FFFULL
|
||||
/* CSR_PMPADDR10 [0:64] RW value= 0x8803FFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR11)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR11 0x000000002003FFFFULL
|
||||
/* CSR_PMPADDR11 [0:64] RW value= 0x2003FFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR12)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR12 0x00000000008041FFULL
|
||||
/* CSR_PMPADDR12 [0:64] RW value= 0x8041FF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR13)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR13 0x0000000000801FFFULL
|
||||
/* CSR_PMPADDR13 [0:64] RW value= 0x801FFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR14)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR14 0xFFFFFFFFFFFFFFFFULL
|
||||
/* CSR_PMPADDR14 [0:64] RW value= 0xFFFFFFFFFFFFFFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART2_CSR_PMPADDR15)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART2_CSR_PMPADDR15 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR15 [0:64] RW value= 0x0 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_PMP_HART2_H_ */
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_pmp_hart3.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_PMP_HART3_H_
|
||||
#define HW_PMP_HART3_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPCFG0)
|
||||
/*PMP configuration for 8 adress regions, bit 0 read, bit 1 write, bit 2
|
||||
execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPCFG0 0x9F9B9B9B00000000ULL
|
||||
/* PMP0CFG [0:8] RW value= 0x00 */
|
||||
/* PMP1CFG [8:8] RW value= 0x00 */
|
||||
/* PMP2CFG [16:8] RW value= 0x00 */
|
||||
/* PMP3CFG [24:8] RW value= 0x00 */
|
||||
/* PMP4CFG [32:8] RW value= 0x9B */
|
||||
/* PMP5CFG [40:8] RW value= 0x9B */
|
||||
/* PMP6CFG [48:8] RW value= 0x9B */
|
||||
/* PMP7CFG [56:8] RW value= 0x9F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPCFG2)
|
||||
/*PMP configuration for 8 address regions, bit 0 read, bit 1 write, bit 2
|
||||
execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPCFG2 0x0000000000989B9BULL
|
||||
/* PMP8CFG [0:8] RW value= 0x9B */
|
||||
/* PMP9CFG [8:8] RW value= 0x9B */
|
||||
/* PMP10CFG [16:8] RW value= 0x98 */
|
||||
/* PMP11CFG [24:8] RW value= 0x0 */
|
||||
/* PMP12CFG [32:8] RW value= 0x0 */
|
||||
/* PMP13CFG [40:8] RW value= 0x0 */
|
||||
/* PMP14CFG [48:8] RW value= 0x0 */
|
||||
/* PMP15CFG [56:8] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR0)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR0 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR0 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR1)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR1 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR1 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR2)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR2 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR2 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR3)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR3 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR3 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR4)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR4 0x000000000A047FFFULL
|
||||
/* CSR_PMPADDR4 [0:64] RW value= 0xA047FFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR5)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR5 0x000000000307FFFFULL
|
||||
/* CSR_PMPADDR5 [0:64] RW value= 0x307FFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR6)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR6 0x00000000080009FFULL
|
||||
/* CSR_PMPADDR6 [0:64] RW value= 0x80009FF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR7)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR7 0x00000000200BFFFFULL
|
||||
/* CSR_PMPADDR7 [0:64] RW value= 0x200BFFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR8)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR8 0x00000000008041FFULL
|
||||
/* CSR_PMPADDR8 [0:64] RW value= 0x8041FF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR9)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR9 0x0000000000801FFFULL
|
||||
/* CSR_PMPADDR9 [0:64] RW value= 0x801FFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR10)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR10 0xFFFFFFFFFFFFFFFFULL
|
||||
/* CSR_PMPADDR10 [0:64] RW value= 0xFFFFFFFFFFFFFFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR11)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR11 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR11 [0:64] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR12)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR12 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR12 [0:64] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR13)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR13 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR13 [0:64] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR14)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR14 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR14 [0:64] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART3_CSR_PMPADDR15)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART3_CSR_PMPADDR15 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR15 [0:64] RW value= 0x0 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_PMP_HART3_H_ */
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_pmp_hart4.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_PMP_HART4_H_
|
||||
#define HW_PMP_HART4_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPCFG0)
|
||||
/*PMP configuration for 8 adress regions, bit 0 read, bit 1 write, bit 2
|
||||
execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPCFG0 0x9F9B9B9B00000000ULL
|
||||
/* PMP0CFG [0:8] RW value= 0x00 */
|
||||
/* PMP1CFG [8:8] RW value= 0x00 */
|
||||
/* PMP2CFG [16:8] RW value= 0x00 */
|
||||
/* PMP3CFG [24:8] RW value= 0x00 */
|
||||
/* PMP4CFG [32:8] RW value= 0x9B */
|
||||
/* PMP5CFG [40:8] RW value= 0x9B */
|
||||
/* PMP6CFG [48:8] RW value= 0x9B */
|
||||
/* PMP7CFG [56:8] RW value= 0x9F */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPCFG2)
|
||||
/*PMP configuration for 8 address regions, bit 0 read, bit 1 write, bit 2
|
||||
execute, bit 7 disable, bits 3,4 address format (0x18 => NAPOT) */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPCFG2 0x0000000000989B9BULL
|
||||
/* PMP8CFG [0:8] RW value= 0x9B */
|
||||
/* PMP9CFG [8:8] RW value= 0x9B */
|
||||
/* PMP10CFG [16:8] RW value= 0x98 */
|
||||
/* PMP11CFG [24:8] RW value= 0x0 */
|
||||
/* PMP12CFG [32:8] RW value= 0x0 */
|
||||
/* PMP13CFG [40:8] RW value= 0x0 */
|
||||
/* PMP14CFG [48:8] RW value= 0x0 */
|
||||
/* PMP15CFG [56:8] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR0)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR0 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR0 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR1)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR1 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR1 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR2)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR2 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR2 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR3)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR3 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR3 [0:64] RW value= 0x00 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR4)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR4 0x000000000A047FFFULL
|
||||
/* CSR_PMPADDR4 [0:64] RW value= 0xA047FFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR5)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR5 0x000000000307FFFFULL
|
||||
/* CSR_PMPADDR5 [0:64] RW value= 0x307FFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR6)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR6 0x00000000080009FFULL
|
||||
/* CSR_PMPADDR6 [0:64] RW value= 0x80009FF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR7)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR7 0x00000000200BFFFFULL
|
||||
/* CSR_PMPADDR7 [0:64] RW value= 0x200BFFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR8)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR8 0x00000000008041FFULL
|
||||
/* CSR_PMPADDR8 [0:64] RW value= 0x8041FF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR9)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR9 0x0000000000801FFFULL
|
||||
/* CSR_PMPADDR9 [0:64] RW value= 0x801FFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR10)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR10 0xFFFFFFFFFFFFFFFFULL
|
||||
/* CSR_PMPADDR10 [0:64] RW value= 0xFFFFFFFFFFFFFFFF */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR11)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR11 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR11 [0:64] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR12)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR12 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR12 [0:64] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR13)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR13 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR13 [0:64] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR14)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR14 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR14 [0:64] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_HART4_CSR_PMPADDR15)
|
||||
/*PMP ADRESS and size, format determined from bit 3 and 4 of configuration byte
|
||||
in CSR_PMPCFGx */
|
||||
#define LIBERO_SETTING_HART4_CSR_PMPADDR15 0x0000000000000000ULL
|
||||
/* CSR_PMPADDR15 [0:64] RW value= 0x0 */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_PMP_HART4_H_ */
|
||||
|
|
@ -0,0 +1,196 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* @file hw_sgmii_tip.h
|
||||
* @author Microchip-FPGA Embedded Systems Solutions
|
||||
*
|
||||
*
|
||||
* Note 1: This file should not be edited. If you need to modify a parameter
|
||||
* without going through regenerating using the MSS Configurator Libero flow
|
||||
* or editing the associated xml file
|
||||
* the following method is recommended:
|
||||
|
||||
* 1. edit the following file
|
||||
* boards/your_board/platform_config/mpfs_hal_config/mss_sw_config.h
|
||||
|
||||
* 2. define the value you want to override there.
|
||||
* (Note: There is a commented example in the platform directory)
|
||||
|
||||
* Note 2: The definition in mss_sw_config.h takes precedence, as
|
||||
* mss_sw_config.h is included prior to the generated header files located in
|
||||
* boards/your_board/fpga_design_config
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HW_SGMII_TIP_H_
|
||||
#define HW_SGMII_TIP_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined (LIBERO_SETTING_SGMII_MODE)
|
||||
/*SGMII mode control (SEU) */
|
||||
#define LIBERO_SETTING_SGMII_MODE 0x08C0E6FFUL
|
||||
/* REG_PLL_EN [0:1] RW value= 0x1 */
|
||||
/* REG_DLL_EN [1:1] RW value= 0x1 */
|
||||
/* REG_PVT_EN [2:1] RW value= 0x1 */
|
||||
/* REG_BC_VRGEN_EN [3:1] RW value= 0x1 */
|
||||
/* REG_TX0_EN [4:1] RW value= 0x1 */
|
||||
/* REG_RX0_EN [5:1] RW value= 0x1 */
|
||||
/* REG_TX1_EN [6:1] RW value= 0x1 */
|
||||
/* REG_RX1_EN [7:1] RW value= 0x1 */
|
||||
/* REG_DLL_LOCK_FLT [8:2] RW value= 0x2 */
|
||||
/* REG_DLL_ADJ_CODE [10:4] RW value= 0x9 */
|
||||
/* REG_CH0_CDR_RESET_B [14:1] RW value= 0x1 */
|
||||
/* REG_CH1_CDR_RESET_B [15:1] RW value= 0x1 */
|
||||
/* REG_BC_VRGEN [16:6] RW value= 0x00 */
|
||||
/* REG_CDR_MOVE_STEP [22:1] RW value= 0x1 */
|
||||
/* REG_REFCLK_EN_RDIFF [23:1] RW value= 0x1 */
|
||||
/* REG_BC_VS [24:4] RW value= 0x8 */
|
||||
/* REG_REFCLK_EN_UDRIVE_P [28:1] RW value= 0x0 */
|
||||
/* REG_REFCLK_EN_INS_HYST_P [29:1] RW value= 0x0 */
|
||||
/* REG_REFCLK_EN_UDRIVE_N [30:1] RW value= 0x0 */
|
||||
/* REG_REFCLK_EN_INS_HYST_N [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_PLL_CNTL)
|
||||
/*PLL control register (SEU) */
|
||||
#define LIBERO_SETTING_PLL_CNTL 0x80140101UL
|
||||
/* REG_PLL_POSTDIV [0:7] RW value= 0x1 */
|
||||
/* ARO_PLL0_LOCK [7:1] RO */
|
||||
/* REG_PLL_RFDIV [8:6] RW value= 0x1 */
|
||||
/* REG_PLL_REG_RFCLK_SEL [14:1] RW value= 0x0 */
|
||||
/* REG_PLL_LP_REQUIRES_LOCK [15:1] RW value= 0x0 */
|
||||
/* REG_PLL_INTIN [16:12] RW value= 0x14 */
|
||||
/* REG_PLL_BWI [28:2] RW value= 0x0 */
|
||||
/* REG_PLL_BWP [30:2] RW value= 0x2 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_CH0_CNTL)
|
||||
/*Channel0 control register */
|
||||
#define LIBERO_SETTING_CH0_CNTL 0x37F07770UL
|
||||
/* REG_TX0_WPU_P [0:1] RW value= 0x0 */
|
||||
/* REG_TX0_WPD_P [1:1] RW value= 0x0 */
|
||||
/* REG_TX0_SLEW_P [2:2] RW value= 0x0 */
|
||||
/* REG_TX0_DRV_P [4:4] RW value= 0x7 */
|
||||
/* REG_TX0_ODT_P [8:4] RW value= 0x7 */
|
||||
/* REG_TX0_ODT_STATIC_P [12:3] RW value= 0x7 */
|
||||
/* REG_RX0_TIM_LONG [15:1] RW value= 0x0 */
|
||||
/* REG_RX0_WPU_P [16:1] RW value= 0x0 */
|
||||
/* REG_RX0_WPD_P [17:1] RW value= 0x0 */
|
||||
/* REG_RX0_IBUFMD_P [18:3] RW value= 0x4 */
|
||||
/* REG_RX0_EYEWIDTH_P [21:3] RW value= 0x7 */
|
||||
/* REG_RX0_ODT_P [24:4] RW value= 0x7 */
|
||||
/* REG_RX0_ODT_STATIC_P [28:3] RW value= 0x3 */
|
||||
/* REG_RX0_EN_FLAG_N [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_CH1_CNTL)
|
||||
/*Channel1 control register */
|
||||
#define LIBERO_SETTING_CH1_CNTL 0x37F07770UL
|
||||
/* REG_TX1_WPU_P [0:1] RW value= 0x0 */
|
||||
/* REG_TX1_WPD_P [1:1] RW value= 0x0 */
|
||||
/* REG_TX1_SLEW_P [2:2] RW value= 0x0 */
|
||||
/* REG_TX1_DRV_P [4:4] RW value= 0x7 */
|
||||
/* REG_TX1_ODT_P [8:4] RW value= 0x7 */
|
||||
/* REG_TX1_ODT_STATIC_P [12:3] RW value= 0x7 */
|
||||
/* REG_RX1_TIM_LONG [15:1] RW value= 0x0 */
|
||||
/* REG_RX1_WPU_P [16:1] RW value= 0x0 */
|
||||
/* REG_RX1_WPD_P [17:1] RW value= 0x0 */
|
||||
/* REG_RX1_IBUFMD_P [18:3] RW value= 0x4 */
|
||||
/* REG_RX1_EYEWIDTH_P [21:3] RW value= 0x7 */
|
||||
/* REG_RX1_ODT_P [24:4] RW value= 0x7 */
|
||||
/* REG_RX1_ODT_STATIC_P [28:3] RW value= 0x3 */
|
||||
/* REG_RX1_EN_FLAG_N [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_RECAL_CNTL)
|
||||
/*Recalibration control register */
|
||||
#define LIBERO_SETTING_RECAL_CNTL 0x000020C8UL
|
||||
/* REG_RECAL_DIFF_RANGE [0:5] RW value= 0x8 */
|
||||
/* REG_RECAL_START_EN [5:1] RW value= 0x0 */
|
||||
/* REG_PVT_CALIB_START [6:1] RW value= 0x1 */
|
||||
/* REG_PVT_CALIB_LOCK [7:1] RW value= 0x1 */
|
||||
/* REG_RECAL_UPD [8:1] RW value= 0x0 */
|
||||
/* BC_VRGEN_DIRECTION [9:1] RW value= 0x0 */
|
||||
/* BC_VRGEN_LOAD [10:1] RW value= 0x0 */
|
||||
/* BC_VRGEN_MOVE [11:1] RW value= 0x0 */
|
||||
/* REG_PVT_REG_CALIB_CLKDIV [12:2] RW value= 0x2 */
|
||||
/* REG_PVT_REG_CALIB_DIFFR_VSEL [14:2] RW value= 0x0 */
|
||||
/* SRO_DLL_90_CODE [16:7] RO */
|
||||
/* SRO_DLL_LOCK [23:1] RO */
|
||||
/* SRO_DLL_ST_CODE [24:7] RO */
|
||||
/* SRO_RECAL_START [31:1] RO */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_CLK_CNTL)
|
||||
/*Clock input and routing control registers */
|
||||
#define LIBERO_SETTING_CLK_CNTL 0xF00050CCUL
|
||||
/* REG_REFCLK_EN_TERM_P [0:2] RW value= 0x0 */
|
||||
/* REG_REFCLK_EN_RXMODE_P [2:2] RW value= 0x3 */
|
||||
/* REG_REFCLK_EN_TERM_N [4:2] RW value= 0x0 */
|
||||
/* REG_REFCLK_EN_RXMODE_N [6:2] RW value= 0x3 */
|
||||
/* REG_REFCLK_CLKBUF_EN_PULLUP [8:1] RW value= 0x0 */
|
||||
/* REG_CLKMUX_FCLK_SEL [9:3] RW value= 0x0 */
|
||||
/* REG_CLKMUX_PLL0_RFCLK0_SEL [12:2] RW value= 0x1 */
|
||||
/* REG_CLKMUX_PLL0_RFCLK1_SEL [14:2] RW value= 0x1 */
|
||||
/* REG_CLKMUX_SPARE0 [16:16] RW value= 0xf000 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_DYN_CNTL)
|
||||
/*Dynamic control registers */
|
||||
#define LIBERO_SETTING_DYN_CNTL 0x00000000UL
|
||||
/* REG_PLL_DYNEN [0:1] RW value= 0x0 */
|
||||
/* REG_DLL_DYNEN [1:1] RW value= 0x0 */
|
||||
/* REG_PVT_DYNEN [2:1] RW value= 0x0 */
|
||||
/* REG_BC_DYNEN [3:1] RW value= 0x0 */
|
||||
/* REG_CLKMUX_DYNEN [4:1] RW value= 0x0 */
|
||||
/* REG_LANE0_DYNEN [5:1] RW value= 0x0 */
|
||||
/* REG_LANE1_DYNEN [6:1] RW value= 0x0 */
|
||||
/* BC_VRGEN_OOR [7:1] RO */
|
||||
/* REG_PLL_SOFT_RESET_PERIPH [8:1] RW value= 0x0 */
|
||||
/* REG_DLL_SOFT_RESET_PERIPH [9:1] RW value= 0x0 */
|
||||
/* REG_PVT_SOFT_RESET_PERIPH [10:1] RW value= 0x0 */
|
||||
/* REG_BC_SOFT_RESET_PERIPH [11:1] RW value= 0x0 */
|
||||
/* REG_CLKMUX_SOFT_RESET_PERIPH [12:1] RW value= 0x0 */
|
||||
/* REG_LANE0_SOFT_RESET_PERIPH [13:1] RW value= 0x0 */
|
||||
/* REG_LANE1_SOFT_RESET_PERIPH [14:1] RW value= 0x0 */
|
||||
/* PVT_CALIB_STATUS [15:1] RO */
|
||||
/* ARO_PLL0_VCO0PH_SEL [16:3] RO */
|
||||
/* ARO_PLL0_VCO1PH_SEL [19:3] RO */
|
||||
/* ARO_PLL0_VCO2PH_SEL [22:3] RO */
|
||||
/* ARO_PLL0_VCO3PH_SEL [25:3] RO */
|
||||
/* ARO_REF_DIFFR [28:4] RO */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_PVT_STAT)
|
||||
/*PVT calibrator status registers */
|
||||
#define LIBERO_SETTING_PVT_STAT 0x00000000UL
|
||||
/* ARO_REF_PCODE [0:6] RO */
|
||||
/* ARO_IOEN_BNK [6:1] RO */
|
||||
/* ARO_IOEN_BNK_B [7:1] RO */
|
||||
/* ARO_REF_NCODE [8:6] RO */
|
||||
/* ARO_CALIB_STATUS [14:1] RO */
|
||||
/* ARO_CALIB_STATUS_B [15:1] RO */
|
||||
/* ARO_PCODE [16:6] RO */
|
||||
/* ARO_CALIB_INTRPT [22:1] RO */
|
||||
/* PVT_CALIB_INTRPT [23:1] RO */
|
||||
/* ARO_NCODE [24:6] RO */
|
||||
/* PVT_CALIB_LOCK [30:1] RW value= 0x0 */
|
||||
/* PVT_CALIB_START [31:1] RW value= 0x0 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SPARE_CNTL)
|
||||
/*Spare control register */
|
||||
#define LIBERO_SETTING_SPARE_CNTL 0xFF000000UL
|
||||
/* REG_SPARE [0:32] RW value= 0xFF000000 */
|
||||
#endif
|
||||
#if !defined (LIBERO_SETTING_SPARE_STAT)
|
||||
/*Spare status register */
|
||||
#define LIBERO_SETTING_SPARE_STAT 0x00000000UL
|
||||
/* SRO_SPARE [0:32] RO */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* #ifdef HW_SGMII_TIP_H_ */
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
contains user configuration of the drivers.
|
||||
drivers config should follow the following format:
|
||||
platform/config/drivers/<same folder name as driver folder>/<driver name>_sw_cfg.h
|
||||
e.g
|
||||
platform/config/drivers/ddr/ddr_sw_cfg.h
|
|
@ -0,0 +1,235 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* MPFS HAL Embedded Software
|
||||
*
|
||||
*/
|
||||
/*******************************************************************************
|
||||
*
|
||||
* file name : mpfs-ddr-e51.ld
|
||||
* Use this linker script when the program is fully located in DDR. The
|
||||
* assumption is DDR has already been initialized by another program.
|
||||
* This linker script can be used with a debugger or when compiled and loaded
|
||||
* by a boot-loader.
|
||||
* Please see the project mpfs-hal-run-from-ddr-1 located in the Bare Metal
|
||||
* library under examples/mpfs-hal for an example of it use.
|
||||
* https://github.com/polarfire-soc/polarfire-soc-bare-metal-library
|
||||
*
|
||||
* You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
|
||||
* which can be found under the link below:
|
||||
* https://github.com/polarfire-soc/polarfire-soc-documentation
|
||||
*
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH( "riscv" )
|
||||
ENTRY(_start)
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-- MSS hart Reset vector
|
||||
|
||||
The MSS reset vector for each hart is stored securely in the MPFS.
|
||||
The most common usage will be where the reset vector for each hart will be set
|
||||
to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
|
||||
non-volatile storage. Normally this is where the initial boot-loader will
|
||||
reside. (Note: The first 256B page of envm is used for metadata associated with
|
||||
secure boot. When not using secure boot (mode 0,1), this area is still reserved
|
||||
by convention. It allows easier transition from non-secure to secure boot flow
|
||||
during the development process.
|
||||
When debugging a bare metal program that is run out of reset from envm, a linker
|
||||
script will be used whereby the program will run from LIM instead of envm.
|
||||
In this case, the reset vector in the linker script is normally set to the
|
||||
start of LIM, 0x0800_0000.
|
||||
This means you are not continually programming the envm each time you load a
|
||||
program and there is no limitation with break points when debugging.
|
||||
See the mpfs-lim.ld example linker script when runing from LIM.
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/* In this example, our reset vector is set to point to the */
|
||||
/* start at page 1 of the envm */
|
||||
envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
|
||||
dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
|
||||
e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
|
||||
u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
|
||||
u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
|
||||
u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
|
||||
u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
|
||||
l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
|
||||
scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
|
||||
/* This 1K of DTIM is used to run code when switching the envm clock */
|
||||
switch_code_dtim (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
|
||||
/* DDR sections example */
|
||||
ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
|
||||
ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
|
||||
ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
|
||||
ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
|
||||
ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
|
||||
ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
|
||||
}
|
||||
HEAP_SIZE = 0k; /* needs to be calculated for your application if using */
|
||||
|
||||
/*
|
||||
* Stack size for our single hart U54 application.
|
||||
*/
|
||||
STACK_SIZE_U54_APPLICATION = 8k;
|
||||
|
||||
/*
|
||||
* A small amount of unitialised memory used to store information
|
||||
* obtained from the boot-loader on start-up
|
||||
*/
|
||||
UNITITALISED_MEM = 16B;
|
||||
|
||||
/* reset address 0xC0000000 */
|
||||
SECTION_START_ADDRESS = 0x80000000;
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
/* text: test code section */
|
||||
. = SECTION_START_ADDRESS;
|
||||
.text : ALIGN(0x10)
|
||||
{
|
||||
__text_load = LOADADDR(.text);
|
||||
__text_start = .;
|
||||
*(.text.init)
|
||||
. = ALIGN(0x10);
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
*(.plt)
|
||||
. = ALIGN(0x10);
|
||||
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*crtend.o(.ctors))
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*crtend.o(.dtors))
|
||||
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
|
||||
*(.gcc_except_table)
|
||||
*(.eh_frame_hdr)
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
|
||||
*(.srodata*)
|
||||
|
||||
. = ALIGN(0x10);
|
||||
__text_end = .;
|
||||
} > ddr_cached_32bit
|
||||
|
||||
.l2_scratchpad : ALIGN(0x10)
|
||||
{
|
||||
__l2_scratchpad_load = LOADADDR(.l2_scratchpad);
|
||||
__l2_scratchpad_start = .;
|
||||
__l2_scratchpad_vma_start = .;
|
||||
*(.l2_scratchpad)
|
||||
. = ALIGN(0x10);
|
||||
__l2_scratchpad_end = .;
|
||||
__l2_scratchpad_vma_end = .;
|
||||
} >scratchpad AT> ddr_cached_32bit
|
||||
|
||||
/* short/global data section */
|
||||
.sdata : ALIGN(0x10)
|
||||
{
|
||||
__sdata_load = LOADADDR(.sdata);
|
||||
__sdata_start = .;
|
||||
/* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
|
||||
/* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
|
||||
__global_pointer$ = . + 0x800;
|
||||
*(.sdata .sdata.* .gnu.linkonce.s.*)
|
||||
. = ALIGN(0x10);
|
||||
__sdata_end = .;
|
||||
} > ddr_cached_32bit
|
||||
|
||||
/* data section */
|
||||
.data : ALIGN(0x10)
|
||||
{
|
||||
__data_load = LOADADDR(.data);
|
||||
__data_start = .;
|
||||
*(.got.plt) *(.got)
|
||||
*(.shdata)
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
. = ALIGN(0x10);
|
||||
__data_end = .;
|
||||
} > ddr_cached_32bit
|
||||
|
||||
/* sbss section */
|
||||
.sbss : ALIGN(0x10)
|
||||
{
|
||||
__sbss_start = .;
|
||||
*(.sbss .sbss.* .gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
. = ALIGN(0x10);
|
||||
__sbss_end = .;
|
||||
} > ddr_cached_32bit
|
||||
|
||||
/* sbss section */
|
||||
.bss : ALIGN(0x10)
|
||||
{
|
||||
__bss_start = .;
|
||||
*(.shbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(0x10);
|
||||
__bss_end = .;
|
||||
} > ddr_cached_32bit
|
||||
|
||||
/* End of uninitialized data segment */
|
||||
_end = .;
|
||||
|
||||
.heap : ALIGN(0x10)
|
||||
{
|
||||
__heap_start = .;
|
||||
. += HEAP_SIZE;
|
||||
__heap_end = .;
|
||||
. = ALIGN(0x10);
|
||||
_heap_end = __heap_end;
|
||||
} > ddr_cached_32bit
|
||||
|
||||
/* must be on 4k boundary- corresponds to page size */
|
||||
.stack : ALIGN(0x1000)
|
||||
{
|
||||
PROVIDE(__app_stack_bottom = .);
|
||||
. += STACK_SIZE_U54_APPLICATION;
|
||||
PROVIDE(__app_stack_top = .);
|
||||
} > ddr_cached_32bit
|
||||
|
||||
/*
|
||||
* used by a program loaded by a bootloader to store information passed
|
||||
* from boot-loader
|
||||
* a0 holds the hart ID
|
||||
* a1 hold pointer to device data, which includes pointer to shared memory
|
||||
* when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
|
||||
* mss_sw_config.h
|
||||
*/
|
||||
.no_init : ALIGN(0x10)
|
||||
{
|
||||
PROVIDE(__uninit_bottom$ = .);
|
||||
. += UNITITALISED_MEM;
|
||||
PROVIDE(__uninit_top_h$ = .);
|
||||
} > ddr_cached_32bit
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
contains user configuration of the platform
|
||||
e.g. division of memory between harts etc.
|
|
@ -0,0 +1,197 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* MPFS HAL Embedded Software
|
||||
*
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Platform definitions
|
||||
* Version based on requirements of MPFS MSS
|
||||
*
|
||||
*/
|
||||
/*========================================================================*//**
|
||||
@mainpage Sample file detailing how mss_sw_config.h should be constructed for
|
||||
the MPFS MSS
|
||||
|
||||
@section intro_sec Introduction
|
||||
The mss_sw_config.h has the default software configuration settings for the
|
||||
MPFS HAL and will be located at
|
||||
<Project-Name>/src/platform/platform_config_reference folder of the bare
|
||||
metal SoftConsole project. The platform_config_reference is provided as a
|
||||
default reference configuration.
|
||||
When you want to configure the MPFS HAL with required configuration for
|
||||
your project, the mss_sw_config.h must be edited and be placed in the
|
||||
following project directory:
|
||||
<Project-Name>/src/boards/<your-board>/platform_config/mpfs_hal_config/
|
||||
|
||||
@section
|
||||
|
||||
*//*==========================================================================*/
|
||||
|
||||
|
||||
#ifndef MSS_SW_CONFIG_H_
|
||||
#define MSS_SW_CONFIG_H_
|
||||
|
||||
/*
|
||||
* MPFS_HAL_FIRST_HART and MPFS_HAL_LAST_HART defines are used to specify which
|
||||
* harts to actually start. The value and the actual hart it represents are
|
||||
* listed below:
|
||||
* value hart
|
||||
* 0 E51
|
||||
* 1 U54_1
|
||||
* 2 U54_2
|
||||
* 3 U54_3
|
||||
* 4 U54_4
|
||||
* Set MPFS_HAL_FIRST_HART to a value greater than 0 if you do not want your
|
||||
* application to start and execute code on the harts represented by smaller
|
||||
* value numbers.
|
||||
* Set MPFS_HAL_LAST_HART to a value smaller than 4 if you do not wish to use
|
||||
* all U54_x harts.
|
||||
* Harts that are not started will remain in an infinite WFI loop unless used
|
||||
* through some other method.
|
||||
* The value of MPFS_HAL_FIRST_HART must always be less than MPFS_HAL_LAST_HART.
|
||||
* The value of MPFS_HAL_LAST_HART must never be greater than 4.
|
||||
* A typical use-case where you set MPFS_HAL_FIRST_HART = 1 and
|
||||
* MPFS_HAL_LAST_HART = 1 is when
|
||||
* your application is running on U54_1 and a bootloader running on E51 loads
|
||||
* your application to the target memory and kicks-off U54_1 to run it.
|
||||
*/
|
||||
#ifndef MPFS_HAL_FIRST_HART
|
||||
#define MPFS_HAL_FIRST_HART 1
|
||||
#endif
|
||||
|
||||
#ifndef MPFS_HAL_LAST_HART
|
||||
#define MPFS_HAL_LAST_HART 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IMAGE_LOADED_BY_BOOTLOADER
|
||||
* We set IMAGE_LOADED_BY_BOOTLOADER = 0 if the application image runs from
|
||||
* non-volatile memory after reset. (No previous stage bootloader is used.)
|
||||
* Set IMAGE_LOADED_BY_BOOTLOADER = 1 if the application image is loaded by a
|
||||
* previous stage bootloader.
|
||||
*
|
||||
* MPFS_HAL_HW_CONFIG is defined if we are a boot-loader. This is a
|
||||
* conditional compile switch is used to determine if MPFS HAL will perform the
|
||||
* hardware configurations or not.
|
||||
* Defined => This program acts as a First stage bootloader and performs
|
||||
* hardware configurations.
|
||||
* Not defined => This program assumes that the hardware configurations are
|
||||
* already performed (Typically by a previous boot stage)
|
||||
*
|
||||
* List of items initialised when MPFS_HAL_HW_CONFIG is enabled
|
||||
* - load virtual rom (see load_virtual_rom(void) in system_startup.c)
|
||||
* - l2 cache config
|
||||
* - Bus error unit config
|
||||
* - MPU config
|
||||
* - pmp config
|
||||
* - I/O, clock and clock mux's, DDR and SGMII
|
||||
* - will start other harts, see text describing MPFS_HAL_FIRST_HART,
|
||||
* MPFS_HAL_LAST_HART above
|
||||
*
|
||||
*/
|
||||
#define IMAGE_LOADED_BY_BOOTLOADER 1
|
||||
#if (IMAGE_LOADED_BY_BOOTLOADER == 0)
|
||||
#define MPFS_HAL_HW_CONFIG
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* If you are using common memory for sharing across harts,
|
||||
* uncomment #define MPFS_HAL_SHARED_MEM_ENABLED
|
||||
* make sure common memory is allocated in the linker script
|
||||
* See app_hart_common mem section in the example platform
|
||||
* linker scripts.
|
||||
*/
|
||||
|
||||
//#define MPFS_HAL_SHARED_MEM_ENABLED
|
||||
|
||||
|
||||
/* define the required tick rate in Milliseconds */
|
||||
/* if this program is running on one hart only, only that particular hart value
|
||||
* will be used */
|
||||
#define HART0_TICK_RATE_MS 5UL
|
||||
#define HART1_TICK_RATE_MS 5UL
|
||||
#define HART2_TICK_RATE_MS 5UL
|
||||
#define HART3_TICK_RATE_MS 5UL
|
||||
#define HART4_TICK_RATE_MS 5UL
|
||||
|
||||
/*
|
||||
* Define the size of the Hart Local Storage (HLS).
|
||||
* In the MPFS HAL, we are using HLS for debug data storage during the initial
|
||||
* boot phase.
|
||||
* This includes the flags which indicate the hart state regarding boot state.
|
||||
* The HLS will take memory from top of each stack allocated at boot time.
|
||||
*
|
||||
*/
|
||||
#define HLS_DEBUG_AREA_SIZE 64
|
||||
|
||||
/*
|
||||
* Bus Error Unit (BEU) configurations
|
||||
* BEU_ENABLE => Configures the events that the BEU can report. bit value
|
||||
* 1= enabled, 0 = disabled.
|
||||
* BEU_PLIC_INT => Configures which accrued events should generate an
|
||||
* interrupt to the PLIC.
|
||||
* BEU_LOCAL_INT => Configures which accrued events should generate a
|
||||
* local interrupt to the hart on which the event accrued.
|
||||
*/
|
||||
#define BEU_ENABLE 0x0ULL
|
||||
#define BEU_PLIC_INT 0x0ULL
|
||||
#define BEU_LOCAL_INT 0x0ULL
|
||||
|
||||
/*
|
||||
* Clear memory on startup
|
||||
* 0 => do not clear DTIM and L2
|
||||
* 1 => Clears memory
|
||||
* Note: If you are the zero stage bootloader, set this to one.
|
||||
*/
|
||||
#ifndef MPFS_HAL_CLEAR_MEMORY
|
||||
#define MPFS_HAL_CLEAR_MEMORY 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Comment out the lines to disable the corresponding hardware support not required
|
||||
* in your application.
|
||||
* This is not necessary from an operational point of view as operation dictated
|
||||
* by MSS configurator settings, and items are enabled/disabled by this method.
|
||||
* The reason you may want to use below is to save code space.
|
||||
*/
|
||||
//#define SGMII_SUPPORT
|
||||
#define DDR_SUPPORT
|
||||
#define MSSIO_SUPPORT
|
||||
|
||||
/*
|
||||
* DDR software options
|
||||
*/
|
||||
|
||||
/*
|
||||
* Debug DDR startup through a UART
|
||||
* Comment out in normal operation. May be useful for debug purposes in bring-up
|
||||
* of a new board design.
|
||||
* See the weakly linked function setup_ddr_debug_port(mss_uart_instance_t * uart)
|
||||
* If you need to edit this function, make another copy of the function in your
|
||||
* application without the weak linking attribute. This copy will then get linked.
|
||||
* */
|
||||
//#define DEBUG_DDR_INIT
|
||||
//#define DEBUG_DDR_RD_RW_FAIL
|
||||
//#define DEBUG_DDR_RD_RW_PASS
|
||||
//#define DEBUG_DDR_CFG_DDR_SGMII_PHY
|
||||
//#define DEBUG_DDR_DDRCFG
|
||||
|
||||
|
||||
/*
|
||||
* The hardware configuration settings imported from Libero project get generated
|
||||
* into <project_name>/src/boards/<your-board>/<fpga-design-config> folder.
|
||||
* If you need to overwrite them for testing purposes, you can do so here.
|
||||
* e.g. If you want change the default SEG registers configuration defined by
|
||||
* LIBERO_SETTING_SEG0_0, define it here and it will take precedence.
|
||||
* #define LIBERO_SETTING_SEG0_0 0x80007F80UL
|
||||
*
|
||||
*/
|
||||
|
||||
#endif /* USER_CONFIG_MSS_USER_CONFIG_H_ */
|
||||
|
|
@ -0,0 +1,533 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2008-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* @file core_gpio.c
|
||||
* @author Microchip FPGA Embedded Systems Solutions
|
||||
* @brief CoreGPIO bare metal driver implementation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "core_gpio.h"
|
||||
#include "coregpio_regs.h"
|
||||
#include "hal/hal.h"
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
*
|
||||
*/
|
||||
#define GPIO_INT_ENABLE_MASK (uint32_t)0x00000008UL
|
||||
#define OUTPUT_BUFFER_ENABLE_MASK 0x00000004UL
|
||||
|
||||
|
||||
#define NB_OF_GPIO 32
|
||||
|
||||
#define CLEAR_ALL_IRQ32 (uint32_t)0xFFFFFFFF
|
||||
#define CLEAR_ALL_IRQ16 (uint16_t)0xFFFF
|
||||
#define CLEAR_ALL_IRQ8 (uint8_t)0xFF
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* GPIO_init()
|
||||
* See "core_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void GPIO_init
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
addr_t base_addr,
|
||||
gpio_apb_width_t bus_width
|
||||
)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
addr_t cfg_reg_addr = base_addr;
|
||||
|
||||
this_gpio->base_addr = base_addr;
|
||||
this_gpio->apb_bus_width = bus_width;
|
||||
|
||||
/* Clear configuration. */
|
||||
for( i = 0, cfg_reg_addr = base_addr; i < NB_OF_GPIO; ++i )
|
||||
{
|
||||
HW_set_8bit_reg( cfg_reg_addr, 0 );
|
||||
cfg_reg_addr += 4;
|
||||
}
|
||||
/* Clear any pending interrupts */
|
||||
switch( this_gpio->apb_bus_width )
|
||||
{
|
||||
case GPIO_APB_32_BITS_BUS:
|
||||
HAL_set_32bit_reg( this_gpio->base_addr, IRQ, CLEAR_ALL_IRQ32 );
|
||||
break;
|
||||
|
||||
case GPIO_APB_16_BITS_BUS:
|
||||
HAL_set_16bit_reg( this_gpio->base_addr, IRQ0, (uint16_t)CLEAR_ALL_IRQ16 );
|
||||
HAL_set_16bit_reg( this_gpio->base_addr, IRQ1, (uint16_t)CLEAR_ALL_IRQ16 );
|
||||
break;
|
||||
|
||||
case GPIO_APB_8_BITS_BUS:
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, IRQ0, (uint8_t)CLEAR_ALL_IRQ8 );
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, IRQ1, (uint8_t)CLEAR_ALL_IRQ8 );
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, IRQ2, (uint8_t)CLEAR_ALL_IRQ8 );
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, IRQ3, (uint8_t)CLEAR_ALL_IRQ8 );
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* GPIO_config
|
||||
* See "core_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void GPIO_config
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
gpio_id_t port_id,
|
||||
uint32_t config
|
||||
)
|
||||
{
|
||||
HAL_ASSERT( port_id < NB_OF_GPIO );
|
||||
|
||||
if ( port_id < NB_OF_GPIO )
|
||||
{
|
||||
uint32_t cfg_reg_addr = this_gpio->base_addr;
|
||||
cfg_reg_addr += (port_id * 4);
|
||||
HW_set_32bit_reg( cfg_reg_addr, config );
|
||||
|
||||
/*
|
||||
* Verify that the configuration was correctly written. Failure to read
|
||||
* back the expected value may indicate that the GPIO port was configured
|
||||
* as part of the hardware flow and cannot be modified through software.
|
||||
* It may also indicate that the base address passed as parameter to
|
||||
* GPIO_init() was incorrect.
|
||||
*/
|
||||
HAL_ASSERT( HW_get_32bit_reg( cfg_reg_addr ) == config );
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* GPIO_set_outputs
|
||||
* See "core_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void GPIO_set_outputs
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
uint32_t value
|
||||
)
|
||||
{
|
||||
switch( this_gpio->apb_bus_width )
|
||||
{
|
||||
case GPIO_APB_32_BITS_BUS:
|
||||
HAL_set_32bit_reg( this_gpio->base_addr, GPIO_OUT, value );
|
||||
break;
|
||||
|
||||
case GPIO_APB_16_BITS_BUS:
|
||||
HAL_set_16bit_reg( this_gpio->base_addr, GPIO_OUT0, (uint16_t)value );
|
||||
HAL_set_16bit_reg( this_gpio->base_addr, GPIO_OUT1, (uint16_t)(value >> 16) );
|
||||
break;
|
||||
|
||||
case GPIO_APB_8_BITS_BUS:
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT0, (uint8_t)value );
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT1, (uint8_t)(value >> 8) );
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT2, (uint8_t)(value >> 16) );
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT3, (uint8_t)(value >> 24) );
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that the output register was correctly written. Failure to read back
|
||||
* the expected value may indicate that some of the GPIOs may not exist due to
|
||||
* the number of GPIOs selected in the CoreGPIO hardware flow configuration.
|
||||
* It may also indicate that the base address or APB bus width passed as
|
||||
* parameter to the GPIO_init() function do not match the hardware design.
|
||||
*/
|
||||
HAL_ASSERT( GPIO_get_outputs( this_gpio ) == value );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* GPIO_get_inputs
|
||||
* See "core_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
uint32_t GPIO_get_inputs
|
||||
(
|
||||
gpio_instance_t * this_gpio
|
||||
)
|
||||
{
|
||||
uint32_t gpio_in = 0;
|
||||
|
||||
switch( this_gpio->apb_bus_width )
|
||||
{
|
||||
case GPIO_APB_32_BITS_BUS:
|
||||
gpio_in = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_IN );
|
||||
break;
|
||||
|
||||
case GPIO_APB_16_BITS_BUS:
|
||||
gpio_in |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_IN0 );
|
||||
gpio_in |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_IN1 ) << 16);
|
||||
break;
|
||||
|
||||
case GPIO_APB_8_BITS_BUS:
|
||||
gpio_in |= HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN0 );
|
||||
gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN1 ) << 8);
|
||||
gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN2 ) << 16);
|
||||
gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN3 ) << 24);
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return gpio_in;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* GPIO_get_outputs
|
||||
* See "core_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
uint32_t GPIO_get_outputs
|
||||
(
|
||||
gpio_instance_t * this_gpio
|
||||
)
|
||||
{
|
||||
uint32_t gpio_out = 0;
|
||||
|
||||
switch( this_gpio->apb_bus_width )
|
||||
{
|
||||
case GPIO_APB_32_BITS_BUS:
|
||||
gpio_out = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT );
|
||||
break;
|
||||
|
||||
case GPIO_APB_16_BITS_BUS:
|
||||
gpio_out |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT0 );
|
||||
gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT1 ) << 16);
|
||||
break;
|
||||
|
||||
case GPIO_APB_8_BITS_BUS:
|
||||
gpio_out |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT0 );
|
||||
gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT1 ) << 8);
|
||||
gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT2 ) << 16);
|
||||
gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT3 ) << 24);
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return gpio_out;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* GPIO_set_output
|
||||
* See "core_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void GPIO_set_output
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
gpio_id_t port_id,
|
||||
uint8_t value
|
||||
)
|
||||
{
|
||||
HAL_ASSERT( port_id < NB_OF_GPIO );
|
||||
|
||||
|
||||
switch( this_gpio->apb_bus_width )
|
||||
{
|
||||
case GPIO_APB_32_BITS_BUS:
|
||||
{
|
||||
uint32_t outputs_state;
|
||||
|
||||
outputs_state = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT );
|
||||
if ( 0 == value )
|
||||
{
|
||||
outputs_state &= ~(1 << port_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
outputs_state |= 1 << port_id;
|
||||
}
|
||||
HAL_set_32bit_reg( this_gpio->base_addr, GPIO_OUT, outputs_state );
|
||||
|
||||
/*
|
||||
* Verify that the output register was correctly written. Failure to read back
|
||||
* the expected value may indicate that some of the GPIOs may not exist due to
|
||||
* the number of GPIOs selected in the CoreGPIO hardware flow configuration.
|
||||
* It may also indicate that the base address or APB bus width passed as
|
||||
* parameter to the GPIO_init() function do not match the hardware design.
|
||||
*/
|
||||
HAL_ASSERT( HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT ) == outputs_state );
|
||||
}
|
||||
break;
|
||||
|
||||
case GPIO_APB_16_BITS_BUS:
|
||||
{
|
||||
uint16_t outputs_state;
|
||||
uint32_t gpio_out_reg_addr = this_gpio->base_addr + GPIO_OUT_REG_OFFSET + ((port_id >> 4) * 4);
|
||||
|
||||
outputs_state = HW_get_16bit_reg( gpio_out_reg_addr );
|
||||
if ( 0 == value )
|
||||
{
|
||||
outputs_state &= ~(1 << (port_id & 0x0F));
|
||||
}
|
||||
else
|
||||
{
|
||||
outputs_state |= 1 << (port_id & 0x0F);
|
||||
}
|
||||
HW_set_16bit_reg( gpio_out_reg_addr, outputs_state );
|
||||
|
||||
/*
|
||||
* Verify that the output register was correctly written. Failure to read back
|
||||
* the expected value may indicate that some of the GPIOs may not exist due to
|
||||
* the number of GPIOs selected in the CoreGPIO hardware flow configuration.
|
||||
* It may also indicate that the base address or APB bus width passed as
|
||||
* parameter to the GPIO_init() function do not match the hardware design.
|
||||
*/
|
||||
HAL_ASSERT( HW_get_16bit_reg( gpio_out_reg_addr ) == outputs_state );
|
||||
}
|
||||
break;
|
||||
|
||||
case GPIO_APB_8_BITS_BUS:
|
||||
{
|
||||
uint8_t outputs_state;
|
||||
uint32_t gpio_out_reg_addr = this_gpio->base_addr + GPIO_OUT_REG_OFFSET + ((port_id >> 3) * 4);
|
||||
|
||||
outputs_state = HW_get_8bit_reg( gpio_out_reg_addr );
|
||||
if ( 0 == value )
|
||||
{
|
||||
outputs_state &= ~(1 << (port_id & 0x07));
|
||||
}
|
||||
else
|
||||
{
|
||||
outputs_state |= 1 << (port_id & 0x07);
|
||||
}
|
||||
HW_set_8bit_reg( gpio_out_reg_addr, outputs_state );
|
||||
|
||||
/*
|
||||
* Verify that the output register was correctly written. Failure to read back
|
||||
* the expected value may indicate that some of the GPIOs may not exist due to
|
||||
* the number of GPIOs selected in the CoreGPIO hardware flow configuration.
|
||||
* It may also indicate that the base address or APB bus width passed as
|
||||
* parameter to the GPIO_init() function do not match the hardware design.
|
||||
*/
|
||||
HAL_ASSERT( HW_get_8bit_reg( gpio_out_reg_addr ) == outputs_state );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* GPIO_drive_inout
|
||||
* See "core_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void GPIO_drive_inout
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
gpio_id_t port_id,
|
||||
gpio_inout_state_t inout_state
|
||||
)
|
||||
{
|
||||
uint32_t config;
|
||||
uint32_t cfg_reg_addr = this_gpio->base_addr;
|
||||
|
||||
HAL_ASSERT( port_id < NB_OF_GPIO );
|
||||
|
||||
switch( inout_state )
|
||||
{
|
||||
case GPIO_DRIVE_HIGH:
|
||||
/* Set output high */
|
||||
GPIO_set_output( this_gpio, port_id, 1 );
|
||||
|
||||
/* Enable output buffer */
|
||||
cfg_reg_addr = this_gpio->base_addr + (port_id * 4);
|
||||
config = HW_get_8bit_reg( cfg_reg_addr );
|
||||
config |= OUTPUT_BUFFER_ENABLE_MASK;
|
||||
HW_set_8bit_reg( cfg_reg_addr, config );
|
||||
break;
|
||||
|
||||
case GPIO_DRIVE_LOW:
|
||||
/* Set output low */
|
||||
GPIO_set_output( this_gpio, port_id, 0 );
|
||||
|
||||
/* Enable output buffer */
|
||||
cfg_reg_addr = this_gpio->base_addr + (port_id * 4);
|
||||
config = HW_get_8bit_reg( cfg_reg_addr );
|
||||
config |= OUTPUT_BUFFER_ENABLE_MASK;
|
||||
HW_set_8bit_reg( cfg_reg_addr, config );
|
||||
break;
|
||||
|
||||
case GPIO_HIGH_Z:
|
||||
/* Disable output buffer */
|
||||
cfg_reg_addr = this_gpio->base_addr + (port_id * 4);
|
||||
config = HW_get_8bit_reg( cfg_reg_addr );
|
||||
config &= ~OUTPUT_BUFFER_ENABLE_MASK;
|
||||
HW_set_8bit_reg( cfg_reg_addr, config );
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* GPIO_enable_irq
|
||||
* See "core_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void GPIO_enable_irq
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
gpio_id_t port_id
|
||||
)
|
||||
{
|
||||
uint32_t cfg_value;
|
||||
uint32_t cfg_reg_addr = this_gpio->base_addr;
|
||||
|
||||
HAL_ASSERT( port_id < NB_OF_GPIO );
|
||||
|
||||
if ( port_id < NB_OF_GPIO )
|
||||
{
|
||||
cfg_reg_addr += (port_id * 4);
|
||||
cfg_value = HW_get_8bit_reg( cfg_reg_addr );
|
||||
cfg_value |= GPIO_INT_ENABLE_MASK;
|
||||
HW_set_8bit_reg( cfg_reg_addr, cfg_value );
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* GPIO_disable_irq
|
||||
* See "core_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void GPIO_disable_irq
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
gpio_id_t port_id
|
||||
)
|
||||
{
|
||||
uint32_t cfg_value;
|
||||
uint32_t cfg_reg_addr = this_gpio->base_addr;
|
||||
|
||||
HAL_ASSERT( port_id < NB_OF_GPIO );
|
||||
|
||||
if ( port_id < NB_OF_GPIO )
|
||||
{
|
||||
cfg_reg_addr += (port_id * 4);
|
||||
cfg_value = HW_get_8bit_reg( cfg_reg_addr );
|
||||
cfg_value &= ~GPIO_INT_ENABLE_MASK;
|
||||
HW_set_8bit_reg( cfg_reg_addr, cfg_value );
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* GPIO_clear_irq
|
||||
* See "core_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void GPIO_clear_irq
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
gpio_id_t port_id
|
||||
)
|
||||
{
|
||||
uint32_t irq_clr_value = ((uint32_t)1) << ((uint32_t)port_id);
|
||||
|
||||
switch( this_gpio->apb_bus_width )
|
||||
{
|
||||
case GPIO_APB_32_BITS_BUS:
|
||||
HAL_set_32bit_reg( this_gpio->base_addr, IRQ, irq_clr_value );
|
||||
break;
|
||||
|
||||
case GPIO_APB_16_BITS_BUS:
|
||||
HAL_set_16bit_reg( this_gpio->base_addr, IRQ0, irq_clr_value );
|
||||
HAL_set_16bit_reg( this_gpio->base_addr, IRQ1, irq_clr_value >> 16 );
|
||||
break;
|
||||
|
||||
case GPIO_APB_8_BITS_BUS:
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, IRQ0, irq_clr_value );
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, IRQ1, irq_clr_value >> 8 );
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, IRQ2, irq_clr_value >> 16 );
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, IRQ3, irq_clr_value >> 24 );
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* GPIO_get_irq_sources
|
||||
* See "core_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
uint32_t GPIO_get_irq_sources
|
||||
(
|
||||
gpio_instance_t * this_gpio
|
||||
)
|
||||
{
|
||||
uint32_t intr_src = 0;
|
||||
|
||||
switch( this_gpio->apb_bus_width )
|
||||
{
|
||||
case GPIO_APB_32_BITS_BUS:
|
||||
intr_src = HAL_get_32bit_reg( this_gpio->base_addr, IRQ );
|
||||
break;
|
||||
|
||||
case GPIO_APB_16_BITS_BUS:
|
||||
intr_src |= HAL_get_16bit_reg( this_gpio->base_addr, IRQ0 );
|
||||
intr_src |= (HAL_get_16bit_reg( this_gpio->base_addr, IRQ1 ) << 16);
|
||||
break;
|
||||
|
||||
case GPIO_APB_8_BITS_BUS:
|
||||
intr_src |= HAL_get_16bit_reg( this_gpio->base_addr, IRQ0 );
|
||||
intr_src |= (HAL_get_16bit_reg( this_gpio->base_addr, IRQ1 ) << 8);
|
||||
intr_src |= (HAL_get_16bit_reg( this_gpio->base_addr, IRQ2 ) << 16);
|
||||
intr_src |= (HAL_get_16bit_reg( this_gpio->base_addr, IRQ3 ) << 24);
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return intr_src;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* GPIO_clear_all_irq_sources
|
||||
* See "core_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void GPIO_clear_all_irq_sources
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
uint32_t bitmask
|
||||
)
|
||||
{
|
||||
uint32_t irq_clr_value = bitmask;
|
||||
|
||||
switch( this_gpio->apb_bus_width )
|
||||
{
|
||||
case GPIO_APB_32_BITS_BUS:
|
||||
HAL_set_32bit_reg( this_gpio->base_addr, IRQ, irq_clr_value );
|
||||
break;
|
||||
|
||||
case GPIO_APB_16_BITS_BUS:
|
||||
HAL_set_16bit_reg( this_gpio->base_addr, IRQ0, irq_clr_value );
|
||||
HAL_set_16bit_reg( this_gpio->base_addr, IRQ1, irq_clr_value >> 16 );
|
||||
break;
|
||||
|
||||
case GPIO_APB_8_BITS_BUS:
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, IRQ0, irq_clr_value );
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, IRQ1, irq_clr_value >> 8 );
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, IRQ2, irq_clr_value >> 16 );
|
||||
HAL_set_8bit_reg( this_gpio->base_addr, IRQ3, irq_clr_value >> 24 );
|
||||
break;
|
||||
|
||||
default:
|
||||
HAL_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,650 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2008-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* @file core_gpio.h
|
||||
* @author Microchip FPGA Embedded Systems Solutions
|
||||
* @brief CoreGPIO bare metal driver public API.
|
||||
*
|
||||
*/
|
||||
|
||||
/*=========================================================================*//**
|
||||
@mainpage CoreGPIO Bare Metal Driver.
|
||||
|
||||
@section intro_sec Introduction
|
||||
The CoreGPIO hardware IP includes up to 32 general purpose input output GPIOs.
|
||||
This driver provides a set of functions for controlling the GPIOs as part of a
|
||||
bare metal system where no operating system is available. These drivers
|
||||
can be adapted for use as part of an operating system but the implementation
|
||||
of the adaptation layer between this driver and the operating system's driver
|
||||
model is outside the scope of this driver.
|
||||
|
||||
@section driver_configuration Driver Configuration
|
||||
The CoreGPIO individual IOs can be configured either in the hardware flow or
|
||||
as part of the software application through calls to the GPIO_config() function.
|
||||
GPIOs configured as as part of the hardware is fixed and cannot be modified
|
||||
using a call to the GPI_config() function.
|
||||
|
||||
@section theory_op Theory of Operation
|
||||
The CoreGPIO driver uses the Actel Hardware Abstraction Layer (HAL) to access
|
||||
hardware registers. You must ensure that the Actel HAL is included as part of
|
||||
your software project. The Actel HAL is available through the Actel Firmware
|
||||
Catalog.
|
||||
|
||||
The CoreGPIO driver functions are logically grouped into the following groups:
|
||||
- Initialization
|
||||
- Configuration
|
||||
- Reading and writing GPIO state
|
||||
- Interrupt control
|
||||
|
||||
The CoreGPIO driver is initialized through a call to the GPIO_init() function.
|
||||
The GPIO_init() function must be called before any other GPIO driver functions
|
||||
can be called.
|
||||
|
||||
Each GPIO port is individually configured through a call to the
|
||||
GPIO_config() function. Configuration includes deciding if a GPIO port
|
||||
will be used as input, output or both. GPIO ports configured as inputs can be
|
||||
further configured to generate interrupts based on the input's state.
|
||||
Interrupts can be level or edge sensitive.
|
||||
Please note that a CoreGPIO hardware instance can be generated, as part of the
|
||||
hardware flow, with a fixed configuration for some or all of its IOs. Attempting
|
||||
to modify the configuration of such a hardware configured IO using the
|
||||
GPIO_config() function has no effect.
|
||||
|
||||
The state of the GPIO ports can be read and written using the following
|
||||
functions:
|
||||
- GPIO_get_inputs()
|
||||
- GPIO_get_outputs()
|
||||
- GPIO_set_outputs()
|
||||
- GPIO_drive_inout()
|
||||
|
||||
Interrupts generated by GPIO ports configured as inputs are controlled using
|
||||
the following functions:
|
||||
- GPIO_enable_irq()
|
||||
- GPIO_disable_irq()
|
||||
- GPIO_clear_irq()
|
||||
- GPIO_get_irq_sources()
|
||||
- GPIO_clear_all_irq_sources()
|
||||
|
||||
*//*=========================================================================*/
|
||||
#ifndef CORE_GPIO_H_
|
||||
#define CORE_GPIO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hal/hal.h"
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The gpio_id_t enumeration is used to identify GPIOs as part of the
|
||||
parameter to functions:
|
||||
- GPIO_config(),
|
||||
- GPIO_drive_inout(),
|
||||
- GPIO_enable_int(),
|
||||
- GPIO_disable_int(),
|
||||
- GPIO_clear_int()
|
||||
*/
|
||||
typedef enum __gpio_id_t
|
||||
{
|
||||
GPIO_0 = 0,
|
||||
GPIO_1 = 1,
|
||||
GPIO_2 = 2,
|
||||
GPIO_3 = 3,
|
||||
GPIO_4 = 4,
|
||||
GPIO_5 = 5,
|
||||
GPIO_6 = 6,
|
||||
GPIO_7 = 7,
|
||||
GPIO_8 = 8,
|
||||
GPIO_9 = 9,
|
||||
GPIO_10 = 10,
|
||||
GPIO_11 = 11,
|
||||
GPIO_12 = 12,
|
||||
GPIO_13 = 13,
|
||||
GPIO_14 = 14,
|
||||
GPIO_15 = 15,
|
||||
GPIO_16 = 16,
|
||||
GPIO_17 = 17,
|
||||
GPIO_18 = 18,
|
||||
GPIO_19 = 19,
|
||||
GPIO_20 = 20,
|
||||
GPIO_21 = 21,
|
||||
GPIO_22 = 22,
|
||||
GPIO_23 = 23,
|
||||
GPIO_24 = 24,
|
||||
GPIO_25 = 25,
|
||||
GPIO_26 = 26,
|
||||
GPIO_27 = 27,
|
||||
GPIO_28 = 28,
|
||||
GPIO_29 = 29,
|
||||
GPIO_30 = 30,
|
||||
GPIO_31 = 31
|
||||
} gpio_id_t;
|
||||
|
||||
typedef enum __gpio_apb_width_t
|
||||
{
|
||||
GPIO_APB_8_BITS_BUS = 0,
|
||||
GPIO_APB_16_BITS_BUS = 1,
|
||||
GPIO_APB_32_BITS_BUS = 2,
|
||||
GPIO_APB_UNKNOWN_BUS_WIDTH = 3
|
||||
} gpio_apb_width_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
*/
|
||||
typedef struct __gpio_instance_t
|
||||
{
|
||||
addr_t base_addr;
|
||||
gpio_apb_width_t apb_bus_width;
|
||||
} gpio_instance_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
GPIO ports definitions used to identify GPIOs as part of the parameter to
|
||||
function GPIO_set_outputs().
|
||||
These definitions can also be used to identity GPIO through logical
|
||||
operations on the return value of function GPIO_get_inputs().
|
||||
*/
|
||||
#define GPIO_0_MASK 0x00000001UL
|
||||
#define GPIO_1_MASK 0x00000002UL
|
||||
#define GPIO_2_MASK 0x00000004UL
|
||||
#define GPIO_3_MASK 0x00000008UL
|
||||
#define GPIO_4_MASK 0x00000010UL
|
||||
#define GPIO_5_MASK 0x00000020UL
|
||||
#define GPIO_6_MASK 0x00000040UL
|
||||
#define GPIO_7_MASK 0x00000080UL
|
||||
#define GPIO_8_MASK 0x00000100UL
|
||||
#define GPIO_9_MASK 0x00000200UL
|
||||
#define GPIO_10_MASK 0x00000400UL
|
||||
#define GPIO_11_MASK 0x00000800UL
|
||||
#define GPIO_12_MASK 0x00001000UL
|
||||
#define GPIO_13_MASK 0x00002000UL
|
||||
#define GPIO_14_MASK 0x00004000UL
|
||||
#define GPIO_15_MASK 0x00008000UL
|
||||
#define GPIO_16_MASK 0x00010000UL
|
||||
#define GPIO_17_MASK 0x00020000UL
|
||||
#define GPIO_18_MASK 0x00040000UL
|
||||
#define GPIO_19_MASK 0x00080000UL
|
||||
#define GPIO_20_MASK 0x00100000UL
|
||||
#define GPIO_21_MASK 0x00200000UL
|
||||
#define GPIO_22_MASK 0x00400000UL
|
||||
#define GPIO_23_MASK 0x00800000UL
|
||||
#define GPIO_24_MASK 0x01000000UL
|
||||
#define GPIO_25_MASK 0x02000000UL
|
||||
#define GPIO_26_MASK 0x04000000UL
|
||||
#define GPIO_27_MASK 0x08000000UL
|
||||
#define GPIO_28_MASK 0x10000000UL
|
||||
#define GPIO_29_MASK 0x20000000UL
|
||||
#define GPIO_30_MASK 0x40000000UL
|
||||
#define GPIO_31_MASK 0x80000000UL
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* GPIO modes
|
||||
*/
|
||||
#define GPIO_INPUT_MODE 0x0000000002UL
|
||||
#define GPIO_OUTPUT_MODE 0x0000000005UL
|
||||
#define GPIO_INOUT_MODE 0x0000000003UL
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Possible GPIO inputs interrupt configurations.
|
||||
*/
|
||||
#define GPIO_IRQ_LEVEL_HIGH 0x0000000000UL
|
||||
#define GPIO_IRQ_LEVEL_LOW 0x0000000020UL
|
||||
#define GPIO_IRQ_EDGE_POSITIVE 0x0000000040UL
|
||||
#define GPIO_IRQ_EDGE_NEGATIVE 0x0000000060UL
|
||||
#define GPIO_IRQ_EDGE_BOTH 0x0000000080UL
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Possible states for GPIO configured as INOUT.
|
||||
*/
|
||||
typedef enum gpio_inout_state
|
||||
{
|
||||
GPIO_DRIVE_LOW = 0,
|
||||
GPIO_DRIVE_HIGH,
|
||||
GPIO_HIGH_Z
|
||||
} gpio_inout_state_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The GPIO_init() function initialises a CoreGPIO hardware instance and the data
|
||||
structure associated with the CoreGPIO hardware instance.
|
||||
Please note that a CoreGPIO hardware instance can be generated with a fixed
|
||||
configuration for some or all of its IOs as part of the hardware flow. Attempting
|
||||
to modify the configuration of such a hardware configured IO using the
|
||||
GPIO_config() function has no effect.
|
||||
|
||||
@param this_gpio
|
||||
Pointer to the gpio_instance_t data structure instance holding all data
|
||||
regarding the CoreGPIO hardware instance being initialized. A pointer to the
|
||||
same data structure will be used in subsequent calls to the CoreGPIO driver
|
||||
functions in order to identify the CoreGPIO instance that should perform the
|
||||
operation implemented by the called driver function.
|
||||
|
||||
@param base_addr
|
||||
The base_addr parameter is the base address in the processor's memory map for
|
||||
the registers of the GPIO instance being initialized.
|
||||
|
||||
@param bus_width
|
||||
The bus_width parameter informs the driver of the APB bus width selected during
|
||||
the hardware flow configuration of the CoreGPIO hardware instance. It indicates
|
||||
to the driver whether the CoreGPIO hardware registers will be visible as 8, 16
|
||||
or 32 bits registers. Allowed value are:
|
||||
- GPIO_APB_8_BITS_BUS
|
||||
- GPIO_APB_16_BITS_BUS
|
||||
- GPIO_APB_32_BITS_BUS
|
||||
|
||||
@return
|
||||
none.
|
||||
|
||||
Example:
|
||||
@code
|
||||
#define COREGPIO_BASE_ADDR 0xC2000000
|
||||
|
||||
gpio_instance_t g_gpio;
|
||||
|
||||
void system_init( void )
|
||||
{
|
||||
GPIO_init( &g_gpio, COREGPIO_BASE_ADDR, GPIO_APB_32_BITS_BUS );
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
void GPIO_init
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
addr_t base_addr,
|
||||
gpio_apb_width_t bus_width
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The GPIO_config() function is used to configure an individual GPIO port.
|
||||
|
||||
@param this_gpio
|
||||
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
|
||||
all data regarding the CoreGPIO instance controlled through this function call.
|
||||
|
||||
@param port_id
|
||||
The port_id parameter identifies the GPIO port to be configured.
|
||||
An enumeration item of the form GPIO_n where n is the number of the GPIO
|
||||
port is used to identify the GPIO port. For example GPIO_0 identifies the
|
||||
first GPIO port and GPIO_31 the last one.
|
||||
|
||||
@param config
|
||||
The config parameter specifies the configuration to be applied to the GPIO
|
||||
port identified by the first parameter. It is a logical OR of GPIO mode and
|
||||
the interrupt mode. The interrupt mode is only relevant if the GPIO is
|
||||
configured as input.
|
||||
Possible modes are:
|
||||
- GPIO_INPUT_MODE,
|
||||
- GPIO_OUTPUT_MODE,
|
||||
- GPIO_INOUT_MODE.
|
||||
Possible interrupt modes are:
|
||||
- GPIO_IRQ_LEVEL_HIGH,
|
||||
- GPIO_IRQ_LEVEL_LOW,
|
||||
- GPIO_IRQ_EDGE_POSITIVE,
|
||||
- GPIO_IRQ_EDGE_NEGATIVE,
|
||||
- GPIO_IRQ_EDGE_BOTH
|
||||
|
||||
@return
|
||||
none.
|
||||
|
||||
For example the following call will configure GPIO 4 as an input generating
|
||||
interrupts on a low to high transition of the input:
|
||||
@code
|
||||
GPIO_config( &g_gpio, GPIO_4, GPIO_INPUT_MODE | GPIO_IRQ_EDGE_POSITIVE );
|
||||
@endcode
|
||||
*/
|
||||
void GPIO_config
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
gpio_id_t port_id,
|
||||
uint32_t config
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The GPIO_set_outputs() function is used to set the state of the GPIO ports
|
||||
configured as outputs.
|
||||
|
||||
@param this_gpio
|
||||
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
|
||||
all data regarding the CoreGPIO instance controlled through this function call.
|
||||
|
||||
@param value
|
||||
The value parameter specifies the state of the GPIO ports configured as
|
||||
outputs. It is a bit mask of the form (GPIO_n_MASK | GPIO_m_MASK) where n
|
||||
and m are numbers identifying GPIOs.
|
||||
For example (GPIO_0_MASK | GPIO_1_MASK | GPIO_2_MASK ) specifies that the
|
||||
first, second and third GPIOs' must be set high and all other outputs set
|
||||
low.
|
||||
|
||||
@return
|
||||
none.
|
||||
|
||||
Example 1:
|
||||
Set GPIOs outputs 0 and 8 high and all other GPIO outputs low.
|
||||
@code
|
||||
GPIO_set_outputs( &g_gpio, GPIO_0_MASK | GPIO_8_MASK );
|
||||
@endcode
|
||||
|
||||
Example 2:
|
||||
Set GPIOs outputs 2 and 4 low without affecting other GPIO outputs.
|
||||
@code
|
||||
uint32_t gpio_outputs;
|
||||
gpio_outputs = GPIO_get_outputs( &g_gpio );
|
||||
gpio_outputs &= ~( GPIO_2_MASK | GPIO_4_MASK );
|
||||
GPIO_set_outputs( &g_gpio, gpio_outputs );
|
||||
@endcode
|
||||
|
||||
@see GPIO_get_outputs()
|
||||
*/
|
||||
void GPIO_set_outputs
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
uint32_t value
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The GPIO_set_output() function is used to set the state of a single GPIO
|
||||
port configured as output.
|
||||
|
||||
@param this_gpio
|
||||
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
|
||||
all data regarding the CoreGPIO instance controlled through this function call.
|
||||
|
||||
@param port_id
|
||||
The port_id parameter specifies the GPIO port that will have its output set
|
||||
by a call to this function.
|
||||
|
||||
@param value
|
||||
The value parameter specifies the desired state for the GPIO output. A value
|
||||
of 0 will set the output low and a value of 1 will set the port high.
|
||||
|
||||
@return
|
||||
none.
|
||||
*/
|
||||
void GPIO_set_output
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
gpio_id_t port_id,
|
||||
uint8_t value
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The GPIO_get_inputs() function is used to read the state of all GPIOs
|
||||
configured as inputs.
|
||||
|
||||
@param this_gpio
|
||||
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
|
||||
all data regarding the CoreGPIO instance controlled through this function call.
|
||||
|
||||
@return
|
||||
This function returns a 32 bit unsigned integer where each bit represents
|
||||
the state of an input. The least significant bit representing the state of
|
||||
GPIO 0 and the most significant bit the state of GPIO 31.
|
||||
*/
|
||||
uint32_t GPIO_get_inputs
|
||||
(
|
||||
gpio_instance_t * this_gpio
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The GPIO_get_outputs() function is used to read the current state of all
|
||||
GPIO outputs.
|
||||
|
||||
@param this_gpio
|
||||
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
|
||||
all data regarding the CoreGPIO instance controlled through this function call.
|
||||
|
||||
@return
|
||||
This function returns a 32 bit unsigned integer where each bit represents
|
||||
the state of an output. The least significant bit representing the state
|
||||
of GPIO 0 and the most significant bit the state of GPIO 31.
|
||||
*/
|
||||
uint32_t GPIO_get_outputs
|
||||
(
|
||||
gpio_instance_t * this_gpio
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The GPIO_drive_inout() function is used to set the output state of a
|
||||
GPIO configured as INOUT. An INOUT GPIO can be in one of three states:
|
||||
- high
|
||||
- low
|
||||
- high impedance
|
||||
An INOUT output would typically be used where several devices can drive the
|
||||
state of a signal. The high and low states are equivalent to the high and low
|
||||
states of a GPIO configured as output. The high impedance state is used to
|
||||
prevent the GPIO from driving the state of the output and therefore allow
|
||||
reading the state of the GPIO as an input.
|
||||
Please note that the GPIO port you wish to use as INOUT through this function
|
||||
must be configurable through software. Therefore the GPIO ports used as INOUT
|
||||
must not have a fixed configuration selected as part of the hardware flow.
|
||||
|
||||
@param this_gpio
|
||||
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
|
||||
all data regarding the CoreGPIO instance controlled through this function call.
|
||||
|
||||
@param port_id
|
||||
The port_id parameter identifies the GPIO for which this function will
|
||||
change the output state.
|
||||
An enumeration item of the form GPIO_n where n is the number of the GPIO
|
||||
port is used to identify the GPIO port. For example GPIO_0 identifies the
|
||||
first GPIO port and GPIO_31 the last one.
|
||||
|
||||
@param inout_state
|
||||
The inout_state parameter specifies the state of the I/O identified by the
|
||||
first parameter. Possible states are:
|
||||
- GPIO_DRIVE_HIGH,
|
||||
- GPIO_DRIVE_LOW,
|
||||
- GPIO_HIGH_Z (high impedance)
|
||||
|
||||
@return
|
||||
none.
|
||||
|
||||
Example:
|
||||
The call to GPIO_drive_inout() below will set the GPIO 7 output to
|
||||
high impedance state.
|
||||
@code
|
||||
GPIO_drive_inout( &g_gpio, GPIO_7, GPIO_HIGH_Z );
|
||||
@endcode
|
||||
*/
|
||||
void GPIO_drive_inout
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
gpio_id_t port_id,
|
||||
gpio_inout_state_t inout_state
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The GPIO_enable_irq() function is used to enable an interrupt to be
|
||||
generated based on the state of the input identified as parameter.
|
||||
|
||||
@param this_gpio
|
||||
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
|
||||
all data regarding the CoreGPIO instance controlled through this function call.
|
||||
|
||||
@param port_id
|
||||
The port_id parameter identifies the GPIO input the call to
|
||||
GPIO_enable_irq() will enable to generate interrupts.
|
||||
An enumeration item of the form GPIO_n where n is the number of the GPIO
|
||||
port is used to identify the GPIO port. For example GPIO_0 identifies the
|
||||
first GPIO port and GPIO_31 the last one.
|
||||
|
||||
@return
|
||||
none.
|
||||
|
||||
Example:
|
||||
The call to GPIO_enable_irq() below will allow GPIO 8 to generate
|
||||
interrupts.
|
||||
@code
|
||||
GPIO_enable_irq( &g_gpio, GPIO_8 );
|
||||
@endcode
|
||||
*/
|
||||
void GPIO_enable_irq
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
gpio_id_t port_id
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The GPIO_disable_irq() function is used to disable interrupt from being
|
||||
generated based on the state of the input specified as parameter.
|
||||
|
||||
@param this_gpio
|
||||
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
|
||||
all data regarding the CoreGPIO instance controlled through this function call.
|
||||
|
||||
@param port_id
|
||||
The port_id parameter identifies the GPIO input the call to
|
||||
GPIO_disable_irq() will disable from generating interrupts.
|
||||
An enumeration item of the form GPIO_n where n is the number of the GPIO
|
||||
port is used to identify the GPIO port. For example GPIO_0 identifies the
|
||||
first GPIO port and GPIO_31 the last one.
|
||||
|
||||
@return
|
||||
none.
|
||||
|
||||
Example:
|
||||
The call to GPIO_disable_irq() below will prevent GPIO 8 from generating
|
||||
interrupts.
|
||||
@code
|
||||
GPIO_disable_irq( &g_gpio, GPIO_8 );
|
||||
@endcode
|
||||
*/
|
||||
void GPIO_disable_irq
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
gpio_id_t port_id
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The GPIO_clear_irq() function is used to clear the interrupt generated by
|
||||
the GPIO specified as parameter. The GPIO_clear_irq() function must be
|
||||
called as part of a GPIO interrupt service routine (ISR) in order to prevent
|
||||
the same interrupt event re-triggering a call to the GPIO ISR.
|
||||
Please note that interrupts may also need to be cleared in the processor's
|
||||
interrupt controller.
|
||||
|
||||
@param this_gpio
|
||||
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
|
||||
all data regarding the CoreGPIO instance controlled through this function call.
|
||||
|
||||
@param port_id
|
||||
The port_id parameter identifies the GPIO input for which to clear the
|
||||
interrupt.
|
||||
An enumeration item of the form GPIO_n where n is the number of the GPIO
|
||||
port is used to identify the GPIO port. For example GPIO_0 identifies the
|
||||
first GPIO port and GPIO_31 the last one.
|
||||
|
||||
@return
|
||||
none.
|
||||
|
||||
Example:
|
||||
The example below demonstrates the use of the GPIO_clear_irq() function as
|
||||
part of the GPIO 9 interrupt service routine.
|
||||
@code
|
||||
void GPIO9_IRQHandler( void )
|
||||
{
|
||||
do_interrupt_processing();
|
||||
|
||||
GPIO_clear_irq( &g_gpio, GPIO_9 );
|
||||
|
||||
NVIC_ClearPendingIRQ( GPIO9_IRQn );
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
void GPIO_clear_irq
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
gpio_id_t port_id
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The GPIO_get_irq_sources() function is used to identify the source of
|
||||
interrupt. i.e. the GPIO input line whose state change triggered the interrupt.
|
||||
The GPIO_get_irq_sources() function must be called as part of a GPIO
|
||||
interrupt service routine (ISR) in order to determine the interrupt source.
|
||||
|
||||
@param this_gpio
|
||||
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
|
||||
all data regarding the CoreGPIO instance controlled through this function call.
|
||||
|
||||
@return
|
||||
This function returns a 32 bit unsigned integer where each bit represents
|
||||
the pin number of GPIO.
|
||||
|
||||
Example:
|
||||
The example below demonstrates the use of the GPIO_get_irq_sources() function
|
||||
as part of the GPIO 9 interrupt service routine.
|
||||
@code
|
||||
void GPIO9_IRQHandler( void )
|
||||
{
|
||||
do_interrupt_processing();
|
||||
|
||||
GPIO_clear_all_irq_sources(g_p_mygpio, GPIO_get_irq_sources(g_p_mygpio));
|
||||
|
||||
NVIC_ClearPendingIRQ( GPIO9_IRQn );
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
uint32_t GPIO_get_irq_sources
|
||||
(
|
||||
gpio_instance_t * this_gpio
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The GPIO_clear_all_irq_sources() function is used to clear the all the active
|
||||
interrupt generated by the GPIO specified as parameter. The
|
||||
GPIO_clear_all_irq_sources() function must be called as part of a GPIO interrupt
|
||||
service routine (ISR) in order to prevent the same interrupt event
|
||||
re-triggering a call to the GPIO ISR.
|
||||
Please note that interrupts may also need to be cleared in the processor's
|
||||
interrupt controller.
|
||||
|
||||
@param this_gpio
|
||||
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
|
||||
all data regarding the CoreGPIO instance controlled through this function call.
|
||||
|
||||
@param bitmask
|
||||
This bitmask parameter is a 32 bit unsigned integer where each bit represents
|
||||
the GPIO pin used to clears the interrupt bit register of the corresponding
|
||||
GPIO bit. The least significant bit representing the status of GPIO 0 and
|
||||
the most significant bit the status of GPIO 31.
|
||||
|
||||
@return
|
||||
none.
|
||||
|
||||
Example:
|
||||
The example below demonstrates the use of the GPIO_clear_all_irq_sources() function as
|
||||
part of the GPIO 9 interrupt service routine.
|
||||
@code
|
||||
void GPIO9_IRQHandler( void )
|
||||
{
|
||||
do_interrupt_processing();
|
||||
|
||||
do_interrupt_processing();
|
||||
|
||||
GPIO_clear_all_irq_sources(g_p_mygpio, GPIO_get_irq_sources(g_p_mygpio));
|
||||
|
||||
NVIC_ClearPendingIRQ( GPIO9_IRQn );
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
void GPIO_clear_all_irq_sources
|
||||
(
|
||||
gpio_instance_t * this_gpio,
|
||||
uint32_t bitmask
|
||||
);
|
||||
#endif /* CORE_GPIO_H_ */
|
|
@ -0,0 +1,43 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2008-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* @file coregpio_regs.h
|
||||
* @author Microchip FPGA Embedded Systems Solutions
|
||||
* @brief CoreGPIO register definitions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CORE_GPIO_REGISTERS_H
|
||||
#define __CORE_GPIO_REGISTERS_H 1
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
#define IRQ_REG_OFFSET 0x80
|
||||
|
||||
#define IRQ0_REG_OFFSET 0x80
|
||||
#define IRQ1_REG_OFFSET 0x84
|
||||
#define IRQ2_REG_OFFSET 0x88
|
||||
#define IRQ3_REG_OFFSET 0x8C
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
#define GPIO_IN_REG_OFFSET 0x90
|
||||
|
||||
#define GPIO_IN0_REG_OFFSET 0x90
|
||||
#define GPIO_IN1_REG_OFFSET 0x94
|
||||
#define GPIO_IN2_REG_OFFSET 0x98
|
||||
#define GPIO_IN3_REG_OFFSET 0x9C
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
#define GPIO_OUT_REG_OFFSET 0xA0
|
||||
|
||||
#define GPIO_OUT0_REG_OFFSET 0xA0
|
||||
#define GPIO_OUT1_REG_OFFSET 0xA4
|
||||
#define GPIO_OUT2_REG_OFFSET 0xA8
|
||||
#define GPIO_OUT3_REG_OFFSET 0xAC
|
||||
|
||||
#endif /* __CORE_GPIO_REGISTERS_H */
|
|
@ -0,0 +1,836 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* PF_System_Services driver implementation. See file "core_syservices_pf.h" for
|
||||
* description of the functions implemented in this file.
|
||||
*
|
||||
*/
|
||||
#include "hal/hal.h"
|
||||
#include "core_sysservices_pf.h"
|
||||
#include "coresysservicespf_regs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NULL_BUFFER (( uint8_t* ) 0)
|
||||
|
||||
static uint8_t execute_ss_command
|
||||
(
|
||||
uint8_t cmd_opcode,
|
||||
const uint8_t* cmd_data,
|
||||
uint16_t cmd_data_size,
|
||||
const uint8_t* p_response,
|
||||
uint16_t response_size,
|
||||
uint16_t mb_offset,
|
||||
uint16_t response_offset
|
||||
);
|
||||
|
||||
uint32_t g_css_pf_base_addr = 0u;
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_init()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
SYS_init
|
||||
(
|
||||
uint32_t base_addr
|
||||
)
|
||||
{
|
||||
g_css_pf_base_addr = base_addr;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_get_serial_number()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t
|
||||
SYS_get_serial_number
|
||||
(
|
||||
const uint8_t * p_serial_number,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
|
||||
if (p_serial_number == NULL_BUFFER)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = execute_ss_command(SERIAL_NUMBER_REQUEST_CMD,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
p_serial_number,
|
||||
SERIAL_NUMBER_RESP_LEN,
|
||||
mb_offset,
|
||||
0u);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_get_user_code()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t
|
||||
SYS_get_user_code
|
||||
(
|
||||
const uint8_t * p_user_code,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
|
||||
if(p_user_code == NULL_BUFFER)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = execute_ss_command(USERCODE_REQUEST_CMD,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
p_user_code,
|
||||
USERCODE_RESP_LEN,
|
||||
mb_offset,
|
||||
0u);
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_get_design_info()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t
|
||||
SYS_get_design_info
|
||||
(
|
||||
const uint8_t * p_design_info,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
|
||||
if(p_design_info == NULL_BUFFER)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = execute_ss_command(DESIGN_INFO_REQUEST_CMD,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
p_design_info,
|
||||
DESIGN_INFO_RESP_LEN,
|
||||
mb_offset,
|
||||
0u);
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_get_device_certificate()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t
|
||||
SYS_get_device_certificate
|
||||
(
|
||||
const uint8_t * p_device_certificate,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
|
||||
if(p_device_certificate == NULL_BUFFER)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = execute_ss_command(DEVICE_CERTIFICATE_REQUEST_CMD,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
p_device_certificate,
|
||||
DEVICE_CERTIFICATE_RESP_LEN,
|
||||
mb_offset,
|
||||
0u);
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_read_digest()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t SYS_read_digest
|
||||
(
|
||||
const uint8_t * p_digest,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
|
||||
if(p_digest == NULL_BUFFER)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifndef CORESYSSERVICES_MPFS
|
||||
status = execute_ss_command(READ_DIGEST_REQUEST_CMD,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
p_digest,
|
||||
READ_DIGEST_RESP_LEN,
|
||||
mb_offset,
|
||||
0u);
|
||||
#else
|
||||
status = execute_ss_command(READ_DIGEST_REQUEST_CMD,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
p_digest,
|
||||
READ_DIGEST_MPFS_RESP_LEN,
|
||||
mb_offset,
|
||||
0u);
|
||||
#endif
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_query_security()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t SYS_query_security
|
||||
(
|
||||
uint8_t * p_security_locks,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
uint8_t idx = 0u;
|
||||
|
||||
if(p_security_locks == NULL_BUFFER)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifndef CORESYSSERVICES_MPFS
|
||||
uint8_t buf[12] = {0};
|
||||
/* Actual QUERY_SECURITY_RESP_LEN is 9 or 33 but PF_System_Services core
|
||||
* needs number of words instead of number of bytes to be written to or read
|
||||
* from MailBox */
|
||||
status = execute_ss_command(QUERY_SECURITY_REQUEST_CMD,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
buf,
|
||||
(QUERY_SECURITY_RESP_LEN + 3u),
|
||||
mb_offset,
|
||||
0u);
|
||||
|
||||
for (idx = 0u; idx < 9u; idx++)
|
||||
{
|
||||
*(p_security_locks+idx) = buf[idx];
|
||||
}
|
||||
|
||||
#else
|
||||
uint8_t buf[36] = {0};
|
||||
|
||||
status = execute_ss_command(QUERY_SECURITY_REQUEST_CMD,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
buf,
|
||||
(QUERY_SECURITY_MPFS_RESP_LEN + 3u),
|
||||
mb_offset,
|
||||
0u);
|
||||
|
||||
for (idx = 0u; idx < 33u; idx++)
|
||||
{
|
||||
*(p_security_locks+idx) = buf[idx];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_read_debug_info()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t SYS_read_debug_info
|
||||
(
|
||||
const uint8_t * p_debug_info,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
|
||||
if(p_debug_info == NULL_BUFFER)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = execute_ss_command(READ_DEBUG_INFO_REQUEST_CMD,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
p_debug_info,
|
||||
READ_DEBUG_INFO_RESP_LEN,
|
||||
mb_offset,
|
||||
0u);
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef CORESYSSERVICES_MPFS
|
||||
/***************************************************************************//**
|
||||
* SYS_read_envm_parameter()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t SYS_read_envm_parameter
|
||||
(
|
||||
uint8_t * p_envm_param,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
|
||||
if(p_envm_param == NULL_BUFFER)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = execute_ss_command(READ_ENVM_PARAM_REQUEST_CMD,
|
||||
NULL_BUFFER,
|
||||
0,
|
||||
p_envm_param,
|
||||
READ_ENVM_PARAM_RESP_LEN,
|
||||
mb_offset,
|
||||
0);
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_puf_emulation_service()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t SYS_puf_emulation_service
|
||||
(
|
||||
const uint8_t * p_challenge,
|
||||
uint8_t op_type,
|
||||
uint8_t* p_response,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
uint8_t mb_format[20] = {0x00};
|
||||
uint8_t index = 0u;
|
||||
|
||||
if((p_response == NULL_BUFFER) || (p_challenge == NULL_BUFFER))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Frame the data required for mailbox */
|
||||
mb_format[index] = op_type;
|
||||
|
||||
for (index = 4u; index < 20u; index++)
|
||||
{
|
||||
mb_format[index] = p_challenge[index - 4u];
|
||||
}
|
||||
|
||||
status = execute_ss_command(PUF_EMULATION_SERVICE_REQUEST_CMD,
|
||||
mb_format,
|
||||
PUF_EMULATION_SERVICE_CMD_LEN,
|
||||
p_response,
|
||||
PUF_EMULATION_SERVICE_RESP_LEN,
|
||||
mb_offset,
|
||||
5u); /* mentioning offset to number of words instead of bytes */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_digital_signature_service()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t SYS_digital_signature_service
|
||||
(
|
||||
const uint8_t* p_hash,
|
||||
uint8_t format,
|
||||
uint8_t* p_response,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
|
||||
if((p_hash == NULL_BUFFER) || (p_response == NULL_BUFFER))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
if (format == DIGITAL_SIGNATURE_RAW_FORMAT_REQUEST_CMD)
|
||||
{
|
||||
status = execute_ss_command(DIGITAL_SIGNATURE_RAW_FORMAT_REQUEST_CMD,
|
||||
p_hash,
|
||||
DIGITAL_SIGNATURE_HASH_LEN,
|
||||
p_response,
|
||||
DIGITAL_SIGNATURE_RAW_FORMAT_RESP_SIZE,
|
||||
mb_offset,
|
||||
12u); /* mentioning offset to number of words instead of bytes */
|
||||
}
|
||||
else
|
||||
{
|
||||
status = execute_ss_command(DIGITAL_SIGNATURE_DER_FORMAT_REQUEST_CMD,
|
||||
p_hash,
|
||||
DIGITAL_SIGNATURE_HASH_LEN,
|
||||
p_response,
|
||||
DIGITAL_SIGNATURE_DER_FORMAT_RESP_SIZE,
|
||||
mb_offset,
|
||||
12u); /* mentioning offset to number of words instead of bytes */
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_secure_nvm_write()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t SYS_secure_nvm_write
|
||||
(
|
||||
uint8_t format,
|
||||
uint8_t snvm_module,
|
||||
const uint8_t* p_data,
|
||||
const uint8_t* p_user_key,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t frame[256] = {0x00};
|
||||
uint8_t* p_frame = &frame[0];
|
||||
uint16_t index = 0u;
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
|
||||
HAL_ASSERT(!(NULL_BUFFER == p_data));
|
||||
HAL_ASSERT(!(NULL_BUFFER == p_user_key));
|
||||
HAL_ASSERT(!(snvm_module >= 221u));
|
||||
|
||||
if((p_data == NULL_BUFFER) || (p_user_key == NULL_BUFFER)
|
||||
|| (snvm_module >= 221))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
if ((format != SNVM_NON_AUTHEN_TEXT_REQUEST_CMD)
|
||||
|| (format != SNVM_AUTHEN_TEXT_REQUEST_CMD)
|
||||
|| (format != SNVM_AUTHEN_CIPHERTEXT_REQUEST_CMD))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
*p_frame = snvm_module; /* SNVMADDR - SNVM module */
|
||||
|
||||
p_frame += 4u; /* Next 3 bytes RESERVED - For alignment */
|
||||
|
||||
/* Copy user key and send the command/data to mailbox. */
|
||||
if ((format == SNVM_AUTHEN_TEXT_REQUEST_CMD) ||
|
||||
(format == SNVM_AUTHEN_CIPHERTEXT_REQUEST_CMD))
|
||||
{
|
||||
/* Copy user data */
|
||||
for (index = 0u; index < (AUTHENTICATED_TEXT_DATA_LEN - USER_SECRET_KEY_LEN - 4u); index++)
|
||||
{
|
||||
*p_frame = p_data[index];
|
||||
p_frame++;
|
||||
}
|
||||
|
||||
/* Copy user key */
|
||||
for (index = 0u; index < USER_SECRET_KEY_LEN; index++)
|
||||
{
|
||||
*p_frame = p_user_key[index];
|
||||
p_frame++;
|
||||
}
|
||||
|
||||
status = execute_ss_command(format,
|
||||
&frame[0],
|
||||
AUTHENTICATED_TEXT_DATA_LEN,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
mb_offset,
|
||||
0u);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy user data */
|
||||
for (index = 0u; index < (NON_AUTHENTICATED_TEXT_DATA_LEN - 4u); index++)
|
||||
{
|
||||
*(p_frame+index) = p_data[index];
|
||||
}
|
||||
|
||||
status = execute_ss_command(format,
|
||||
&frame[0],
|
||||
NON_AUTHENTICATED_TEXT_DATA_LEN,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
mb_offset,
|
||||
0u);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_secure_nvm_read()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t SYS_secure_nvm_read
|
||||
(
|
||||
uint8_t snvm_module,
|
||||
const uint8_t* p_user_key,
|
||||
uint8_t* p_admin,
|
||||
uint8_t* p_data,
|
||||
uint16_t data_len,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
/* Frame the message. */
|
||||
uint8_t frame[16] = {0x00u};
|
||||
uint8_t* p_frame = &frame[0u];
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
uint8_t response[256] = {0x00u};
|
||||
uint16_t index = 0u;
|
||||
|
||||
HAL_ASSERT(!(NULL_BUFFER == p_data));
|
||||
HAL_ASSERT(!(NULL_BUFFER == p_admin));
|
||||
HAL_ASSERT(!(snvm_module > 221u));
|
||||
|
||||
HAL_ASSERT(data_len == 236u || data_len == 252u);
|
||||
|
||||
if((p_data == NULL_BUFFER) ||
|
||||
(snvm_module >= 221) ||
|
||||
(p_admin == NULL_BUFFER))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
*p_frame = snvm_module; /* SNVMADDR - SNVM module */
|
||||
|
||||
p_frame += 4u; /* RESERVED - For alignment */
|
||||
|
||||
/* Copy user key */
|
||||
if (236u == data_len)
|
||||
{
|
||||
HAL_ASSERT(p_user_key != NULL_BUFFER);
|
||||
|
||||
if(p_user_key == NULL_BUFFER)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
for (index = 0u; index < 12u; index++)
|
||||
{
|
||||
*p_frame = p_user_key[index];
|
||||
p_frame++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p_frame += 12u;
|
||||
}
|
||||
|
||||
status = execute_ss_command(SNVM_READ_REQUEST_CMD,
|
||||
&frame[0],
|
||||
16u,
|
||||
response,
|
||||
(data_len + 4u),
|
||||
mb_offset,
|
||||
4u); /* mentioning offset to number of words instead of bytes */
|
||||
|
||||
if (SYS_SUCCESS == status)
|
||||
{
|
||||
for (index = 0u; index < 4u; index++)
|
||||
{
|
||||
*(p_admin+index) = (uint32_t)response[index];
|
||||
}
|
||||
|
||||
|
||||
/* Copy data into user buffer. */
|
||||
for (index = 4u; index < (data_len + 4u); index++)
|
||||
{
|
||||
*(p_data + (index - 4u)) = response[index];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_nonce_service()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t SYS_nonce_service
|
||||
(
|
||||
const uint8_t * p_nonce,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
|
||||
if((p_nonce == NULL_BUFFER))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = execute_ss_command(NONCE_SERVICE_REQUEST_CMD,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
p_nonce,
|
||||
NONCE_SERVICE_RESP_LEN,
|
||||
mb_offset,
|
||||
0u);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_bitstream_authenticate_service()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t SYS_bitstream_authenticate_service
|
||||
(
|
||||
uint32_t spi_flash_address,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
uint32_t l_spi_flash_address = spi_flash_address;
|
||||
status = execute_ss_command(BITSTREAM_AUTHENTICATE_CMD,
|
||||
(uint8_t* )&l_spi_flash_address,
|
||||
4u,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
mb_offset,
|
||||
0u);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_IAP_image_authenticate_service()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t SYS_IAP_image_authenticate_service
|
||||
(
|
||||
uint8_t spi_idx
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
|
||||
HAL_ASSERT(!(spi_idx == 1u));
|
||||
|
||||
if (spi_idx == 1u)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = execute_ss_command(IAP_BITSTREAM_AUTHENTICATE_CMD,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
spi_idx,
|
||||
0u);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_digest_check_service()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t SYS_digest_check_service
|
||||
(
|
||||
uint32_t options,
|
||||
uint16_t mb_offset
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
uint32_t l_options = options;
|
||||
|
||||
status = execute_ss_command(DIGEST_CHECK_CMD,
|
||||
(uint8_t* )&l_options,
|
||||
4u,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
mb_offset,
|
||||
0u);
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SYS_iap_service()
|
||||
* See "core_sysservices_pf.h" for details of how to use this function.
|
||||
*/
|
||||
uint8_t SYS_iap_service
|
||||
(
|
||||
uint8_t iap_cmd,
|
||||
uint32_t spiaddr
|
||||
)
|
||||
{
|
||||
uint8_t status = SYS_PARAM_ERR;
|
||||
uint32_t l_spiaddr = spiaddr;
|
||||
|
||||
if ((IAP_PROGRAM_BY_SPIIDX_CMD == iap_cmd) || (IAP_VERIFY_BY_SPIIDX_CMD == iap_cmd))
|
||||
{
|
||||
HAL_ASSERT(!(1u == spiaddr));
|
||||
}
|
||||
|
||||
status = execute_ss_command(iap_cmd,
|
||||
(uint8_t*)&l_spiaddr,
|
||||
4u,
|
||||
NULL_BUFFER,
|
||||
0u,
|
||||
spiaddr,
|
||||
0u);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
Internal functions.
|
||||
*/
|
||||
/*
|
||||
This function executes the SS command. If Mailbox input data is required by the
|
||||
it will first load it from cmd_data into the Mailbox. If the service requires
|
||||
the response data to be read from mailbox, it will do so and store it in p_response.
|
||||
*/
|
||||
static uint8_t execute_ss_command
|
||||
(
|
||||
uint8_t cmd_opcode,
|
||||
const uint8_t* cmd_data,
|
||||
uint16_t cmd_data_size,
|
||||
const uint8_t* p_response,
|
||||
uint16_t response_size,
|
||||
uint16_t mb_offset,
|
||||
uint16_t response_offset
|
||||
)
|
||||
{
|
||||
/* Pointer used during Writing to Mailbox memory. */
|
||||
uint32_t status = 0u;
|
||||
uint16_t idx = 0u;
|
||||
uint16_t ss_command = 0u;
|
||||
uint32_t* word_buf;
|
||||
uint16_t timeout_count = SS_TIMEOUT_COUNT;
|
||||
|
||||
/* making sure that the system controller is not executing any service i.e.
|
||||
SS_USER_BUSY is gone 0 */
|
||||
|
||||
while (1u == HAL_get_32bit_reg_field(g_css_pf_base_addr, SS_USER_BUSY))
|
||||
{
|
||||
--timeout_count;
|
||||
|
||||
if (timeout_count == 0)
|
||||
{
|
||||
return SS_USER_BUSY_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Form the SS command: bit 0to6 is the opcode, bit 7to15 is the Mailbox offset
|
||||
For some services this field has another meaning
|
||||
(e.g. for IAP bitstream auth. it means spi_idx) */
|
||||
ss_command = ((mb_offset << 7u) | (cmd_opcode & 0x7Fu));
|
||||
|
||||
/* Load the command register with the SS request command code*/
|
||||
HAL_set_32bit_reg(g_css_pf_base_addr, SS_CMD, ss_command);
|
||||
|
||||
if (cmd_data_size > 0u)
|
||||
{
|
||||
HAL_ASSERT(!(NULL_BUFFER == cmd_data));
|
||||
HAL_ASSERT(!(cmd_data_size % 4u));
|
||||
|
||||
/* Load the MBX_WCNT register with number of words */
|
||||
HAL_set_32bit_reg( g_css_pf_base_addr, MBX_WCNT, (cmd_data_size/4u));
|
||||
|
||||
/* Load the MBX_WADDR register with offset of input data (write to Mailbox)
|
||||
For all the services this offset remains either 0 or Not applicable
|
||||
for the services in which no Mailbox write is required.*/
|
||||
HAL_set_32bit_reg( g_css_pf_base_addr, MBX_WADDR, (0x00u + mb_offset));
|
||||
|
||||
}
|
||||
|
||||
if (response_size > 0u)
|
||||
{
|
||||
HAL_ASSERT(!(NULL_BUFFER == p_response));
|
||||
HAL_ASSERT(!(response_size % 4u));
|
||||
|
||||
/*
|
||||
Load the MBX_RWCNT register with number of words to be read from Mailbox
|
||||
*/
|
||||
HAL_set_32bit_reg( g_css_pf_base_addr, MBX_RCNT, (response_size/4u));
|
||||
|
||||
/*
|
||||
Load the MBX_RADRDESC register with offset address within the mailbox
|
||||
format for that particular service.
|
||||
It will be 0 for the services where there is no output data from G5CONTROL
|
||||
is expected.
|
||||
This function assumes that this value is pre-calculated by service specific
|
||||
functions as this value is fixed for each service.
|
||||
*/
|
||||
HAL_set_32bit_reg( g_css_pf_base_addr, MBX_RADDR, (response_offset + mb_offset));
|
||||
}
|
||||
|
||||
/*Set the request bit in SYS_SERV_REQ register to start the service*/
|
||||
HAL_set_32bit_reg_field(g_css_pf_base_addr, SS_REQ_REQ, 0x01u);
|
||||
|
||||
if (cmd_data_size > 0u)
|
||||
{
|
||||
word_buf = (uint32_t*)cmd_data;
|
||||
|
||||
/* Write the user data into mail box. */
|
||||
for (idx = 0u; idx < (cmd_data_size/4u); idx++)
|
||||
{
|
||||
HAL_set_32bit_reg( g_css_pf_base_addr, MBX_WDATA, word_buf[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
timeout_count = SS_TIMEOUT_COUNT;
|
||||
if (response_size > 0u)
|
||||
{
|
||||
word_buf = (uint32_t*)p_response;
|
||||
|
||||
for (idx = 0u; idx < (response_size/4u); idx++)
|
||||
{
|
||||
while (0u == HAL_get_32bit_reg_field(g_css_pf_base_addr,
|
||||
SS_USER_RDVLD))
|
||||
{
|
||||
--timeout_count;
|
||||
|
||||
if (timeout_count == 0)
|
||||
{
|
||||
return SS_USER_RDVLD_TIMEOUT;
|
||||
}
|
||||
}
|
||||
word_buf[idx] = HAL_get_32bit_reg(g_css_pf_base_addr, MBX_RDATA);
|
||||
}
|
||||
}
|
||||
|
||||
timeout_count = SS_TIMEOUT_COUNT;
|
||||
/* make sure that service is complete i.e. SS_USER_BUSY is gone 0 */
|
||||
while (1u == HAL_get_32bit_reg_field(g_css_pf_base_addr, SS_USER_BUSY))
|
||||
{
|
||||
--timeout_count;
|
||||
|
||||
if (timeout_count == 0)
|
||||
{
|
||||
return SS_USER_RDVLD_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the status returned by System Controller */
|
||||
status = HAL_get_32bit_reg(g_css_pf_base_addr, SS_STAT);
|
||||
|
||||
return (uint8_t)status;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,147 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* Register bit offsets and masks definitions for CoreSysServices_PF driver.
|
||||
*/
|
||||
|
||||
#ifndef __CORE_SYSSERV_PF_REGISTERS
|
||||
#define __CORE_SYSSERV_PF_REGISTERS 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* SYS_SERV_CMD (offset 0x04) register details
|
||||
*/
|
||||
#define SS_CMD_REG_OFFSET 0x04u
|
||||
|
||||
#define SS_CMD_OFFSET 0x04
|
||||
#define SS_CMD_MASK 0x0000FFFFu
|
||||
#define SS_CMD_SHIFT 0u
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* SYS_SERV_STAT (offset 0x08) register details
|
||||
*/
|
||||
#define SS_STAT_REG_OFFSET 0x08u
|
||||
|
||||
#define SS_STAT_OFFSET 0x08
|
||||
#define SS_STAT_MASK 0x0000FFFFu
|
||||
#define SS_STAT_SHIFT 0u
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* SYS_SERV_REQ (offset 0x0C) register details
|
||||
*/
|
||||
#define SS_REQ_REG_OFFSET 0x0Cu
|
||||
|
||||
|
||||
#define SS_REQ_REQ_OFFSET 0x0Cu
|
||||
#define SS_REQ_REQ_MASK 0x00000001UL
|
||||
#define SS_REQ_REQ_SHIFT 0u
|
||||
|
||||
#define SS_REQ_ABUSY_OFFSET 0x0Cu
|
||||
#define SS_REQ_ABUSY_MASK 0x00000002UL
|
||||
#define SS_REQ_ABUSY_SHIFT 1u
|
||||
|
||||
#define SS_REQ_NABUSY_OFFSET 0x0Cu
|
||||
#define SS_REQ_NABUSY_MASK 0x00000004UL
|
||||
#define SS_REQ_NABUSY_SHIFT 2u
|
||||
|
||||
#define SS_REQ_SSBUSY_OFFSET 0x0Cu
|
||||
#define SS_REQ_SSBUSY_MASK 0x00000008UL
|
||||
#define SS_REQ_SSBUSY_SHIFT 3u
|
||||
|
||||
#define SS_REQ_AREQ_OFFSET 0x0Cu
|
||||
#define SS_REQ_AREQ_MASK 0x00000010UL
|
||||
#define SS_REQ_AREQ_SHIFT 4u
|
||||
|
||||
#define SS_REQ_NAREQ_OFFSET 0x0Cu
|
||||
#define SS_REQ_NAREQ_MASK 0x00000020UL
|
||||
#define SS_REQ_NAREQ_SHIFT 5u
|
||||
/*------------------------------------------------------------------------------
|
||||
* MBX_ECCSTATUS (offset 0x10) register details
|
||||
*/
|
||||
#define MBX_ECCSTATUS_REG_OFFSET 0x10u
|
||||
|
||||
#define MBX_ECCSTATUS_OFFSET 0x10
|
||||
#define MBX_ECCSTATUS_MASK 0x03u
|
||||
#define MBX_ECCSTATUS_SHIFT 0u
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MBX_WCNT (offset 0x14) register details
|
||||
*/
|
||||
#define MBX_WCNT_REG_OFFSET 0x14u
|
||||
|
||||
#define MBX_WCNT_OFFSET 0x14
|
||||
#define MBX_WCNT_MASK 0x000001FFu
|
||||
#define MBX_WCNT_SHIFT 0u
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MBX_RWCNT (offset 0x18) register details
|
||||
*/
|
||||
#define MBX_RCNT_REG_OFFSET 0x18u
|
||||
|
||||
#define MBX_RCNT_OFFSET 0x18
|
||||
#define MBX_RCNT_MASK 0x000001FFu
|
||||
#define MBX_RCNT_SHIFT 0u
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MBX_WADRDESC (offset 0x1C) register details
|
||||
*/
|
||||
#define MBX_WADDR_REG_OFFSET 0x1Cu
|
||||
|
||||
#define MBX_WADDR_OFFSET 0x1C
|
||||
#define MBX_WADDR_MASK 0x000001FFu
|
||||
#define MBX_WADDR_SHIFT 0u
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MBX_RADRDESC (offset 0x20) register details
|
||||
*/
|
||||
#define MBX_RADDR_REG_OFFSET 0x20u
|
||||
|
||||
#define MBX_RADDR_OFFSET 0x20
|
||||
#define MBX_RADDR_MASK 0x000001FFu
|
||||
#define MBX_RADDR_SHIFT 0u
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MBX_WDATA (offset 0x28) register details
|
||||
*/
|
||||
#define MBX_WDATA_REG_OFFSET 0x28u
|
||||
|
||||
#define MBX_WDATA_OFFSET 0x28
|
||||
#define MBX_WDATA_MASK 0xFFFFFFFFu
|
||||
#define MBX_WDATA_SHIFT 0u
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* MBX_RDATA (offset 0x2C) register details
|
||||
*/
|
||||
#define MBX_RDATA_REG_OFFSET 0x2Cu
|
||||
|
||||
#define MBX_RDATA_OFFSET 0x2C
|
||||
#define MBX_RDATA_MASK 0xFFFFFFFFu
|
||||
#define MBX_RDATA_SHIFT 0u
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* SS_USER (offset 0x30) register details
|
||||
*/
|
||||
#define SS_USER_REG_OFFSET 0x30u
|
||||
|
||||
#define SS_USER_BUSY_OFFSET 0x30
|
||||
#define SS_USER_BUSY_MASK 0x00000001u
|
||||
#define SS_USER_BUSY_SHIFT 0u
|
||||
|
||||
#define SS_USER_RDVLD_OFFSET 0x30
|
||||
#define SS_USER_RDVLD_MASK 0x00000002u
|
||||
#define SS_USER_RDVLD_SHIFT 1u
|
||||
|
||||
#define SS_USER_CMDERR_OFFSET 0x30
|
||||
#define SS_USER_CMDERR_MASK 0x00000004u
|
||||
#define SS_USER_CMDERR_SHIFT 2u
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_SYSSERV_PF_REGISTERS */
|
|
@ -0,0 +1 @@
|
|||
This is a place holder
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,281 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2020 Microchip Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* This file contains system specific definitions for the PolarFire SoC MSS
|
||||
* Ethernet MAC device driver.
|
||||
*
|
||||
* Note: This file is maintained in the driver source repository in the same
|
||||
* folder as the driver source to keep them consistent but in the example
|
||||
* repositories the working copy resides in the current boards
|
||||
* platform_config/drivers/mss_mac folder and a reference copy is found in
|
||||
* the platform/platform_config_reference/drivers/mss_mac folder.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MICROSEMI__FIRMWARE__POLARFIRE_SOC_MSS_ETHERNET_MAC_DRIVER__1_7_107_CONFIGURATION_HEADER
|
||||
#define MICROSEMI__FIRMWARE__POLARFIRE_SOC_MSS_ETHERNET_MAC_DRIVER__1_7_107_CONFIGURATION_HEADER
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* When running the documentation scripts, this macro should be defined to make
|
||||
* sure the maximal macro selections are enabled so that the scripts pick up
|
||||
* the complete documentation.
|
||||
*
|
||||
* Some macro definitions that are not normally used will be enabled if this
|
||||
* macro is defined...
|
||||
*/
|
||||
#if 0
|
||||
#define MSS_MAC_DOCUMENTATION
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* Define this macro to add support for lower latency receive interrupt handling
|
||||
* which may improve performance for full bandwidth network performance testing.
|
||||
*
|
||||
* If using debug mode build, you might set the NDEBUG macro in the project
|
||||
* settings to further reduce interrupt overhead when using this option.
|
||||
*/
|
||||
#if defined(MSS_MAC_DOCUMENTATION)
|
||||
#define MSS_MAC_UNH_TEST
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* This macro is normally defined at project level to select MPFS as the
|
||||
* platform. The alternative is to define _TARGET_ALOE_ for the SiFive Aloe or
|
||||
* Aloe + Vera boards.
|
||||
*/
|
||||
#if defined(MSS_MAC_DOCUMENTATION)
|
||||
#define TARGET_G5_SOC
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* Driver versioning macros.
|
||||
*/
|
||||
#define CORE_VENDOR "Microsemi"
|
||||
#define CORE_LIBRARY "Firmware"
|
||||
#define CORE_NAME "PolarFire_SoC_MSS_Ethernet_MAC_Driver"
|
||||
#define CORE_VERSION "1.7.107"
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* Define this macro to add support for high speed transmission for network
|
||||
* saturation testing. Not recommended for normal builds of the code as it may
|
||||
* cause some unexpected behaviour for normal operations.
|
||||
*
|
||||
* If using debug mode build, you might set the NDEBUG macro in the project
|
||||
* settings to reduce interrupt overhead when using this option.
|
||||
*/
|
||||
#if defined(MSS_MAC_DOCUMENTATION)
|
||||
#define MSS_MAC_SPEED_TEST
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Defines for OS and network stack specific support.
|
||||
*
|
||||
* Un-comment as necessary or define in project properties etc.
|
||||
*/
|
||||
#if defined(MSS_MAC_DOCUMENTATION)
|
||||
#define USING_FREERTOS
|
||||
#define USING_LWIP
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Supported PHY interface types:
|
||||
*/
|
||||
|
||||
#define NULL_PHY (0x0001U) /*!< @brief No PHY in connection, for example GEM0 and GEM1 connected via fabric */
|
||||
#define GMII (0x0002U) /*!< @brief Currently only on Aloe board */
|
||||
#define TBI (0x0004U) /*!< @brief G5 SoC Emulation Platform designs with TBI */
|
||||
#define GMII_SGMII (0x0008U) /*!< @brief G5 SoC Emulation Platform designs with SGMII to GMII conversion */
|
||||
#if 0
|
||||
#define BASEX1000 (0x0010U) /* Not currently available */
|
||||
#define RGMII (0x0020U) /* Not currently available */
|
||||
#define RMII (0x0040U) /* Not currently available */
|
||||
#define SGMII (0x0080U) /* Not currently available */
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Supported PHY models, used to control compile time inclusion of the
|
||||
* associated PHY sub-drivers.
|
||||
*/
|
||||
|
||||
#define MSS_MAC_DEV_PHY_NULL (0x0001U) /*!< @brief No PHY device connected, for loopback and direct connection configurations */
|
||||
#define MSS_MAC_DEV_PHY_VSC8575 (0x0002U) /*!< @brief VSC8575 using full VTSS API */
|
||||
#define MSS_MAC_DEV_PHY_VSC8541 (0x0004U) /*!< @brief VSC8541 without VTSS API */
|
||||
#define MSS_MAC_DEV_PHY_DP83867 (0x0008U) /*!< @brief TI DP83867 */
|
||||
#define MSS_MAC_DEV_PHY_VSC8575_LITE (0x0010U) /*!< @brief VSC8575 using Lite VTSS API */
|
||||
#define MSS_MAC_DEV_PHY_VSC8662 (0x0020U) /*!< @brief VSC8662 without VTSS API */
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* Defines for the different hardware configurations for the applications using
|
||||
* the driver. Used to allow software configure GPIO etc, to support the
|
||||
* appropriate hardware configuration.
|
||||
*
|
||||
* Not strictly part of the driver but we manage them here to keep things tidy.
|
||||
*/
|
||||
|
||||
#define MSS_MAC_DESIGN_ALOE (0) /*!< @brief ALOE board from Sifive (GMII)*/
|
||||
#define MSS_MAC_DESIGN_EMUL_GMII (1) /*!< @brief G5 SoC Emulation Platform VSC8575 designs with GMII to SGMII bridge on GEM0 */
|
||||
#define MSS_MAC_DESIGN_EMUL_TBI (2) /*!< @brief G5 SoC Emulation Platform VSC8575 designs with TBI to SGMII bridge on GEM0 */
|
||||
#define MSS_MAC_DESIGN_EMUL_DUAL_INTERNAL (3) /*!< @brief G5 SoC Emulation Platform Dual GEM design with loopback in fabric */
|
||||
#define MSS_MAC_DESIGN_EMUL_TI_GMII (4) /*!< @brief G5 SoC Emulation Platform DP83867 design with GMII to SGMII bridge */
|
||||
#define MSS_MAC_DESIGN_EMUL_DUAL_EX_TI (5) /*!< @brief G5 SoC Emulation Platform Dual GEM design with external TI PHY on GEM1 (GMII) */
|
||||
#define MSS_MAC_DESIGN_EMUL_DUAL_EX_VTS (6) /*!< @brief G5 SoC Emulation Platform Dual GEM design with external Vitess PHY on GEM0 (GMII) */
|
||||
#define MSS_MAC_DESIGN_EMUL_GMII_GEM1 (7) /*!< @brief G5 SoC Emulation Platform VSC8575 designs with GMII to SGMII bridge on GEM 1 */
|
||||
#define MSS_MAC_DESIGN_EMUL_DUAL_EXTERNAL (8) /*!< @brief G5 SoC Emulation Platform Dual GEM design with GEM0 -> VSC, GEM1 -> TI (both GMII) */
|
||||
#define MSS_MAC_DESIGN_EMUL_TBI_GEM1 (9) /*!< @brief G5 SoC Emulation Platform VSC8575 designs with TBI to SGMII bridge GEM1 */
|
||||
#define MSS_MAC_DESIGN_EMUL_TBI_TI (10) /*!< @brief G5 SoC Emulation Platform DP83867 designs with TBI to SGMII bridge GEM0 */
|
||||
#define MSS_MAC_DESIGN_EMUL_TBI_GEM1_TI (11) /*!< @brief G5 SoC Emulation Platform DP83867 designs with TBI to SGMII bridge GEM1 */
|
||||
#define MSS_MAC_DESIGN_EMUL_GMII_LOCAL (12) /*!< @brief G5 SoC Emulation Platform VSC8575 design with GMII to SGMII bridge with local ints */
|
||||
#define MSS_MAC_DESIGN_RENODE (13) /*!< @brief Renode */
|
||||
#define MSS_MAC_DESIGN_SVG_SGMII_GEM0 (14) /*!< @brief Silicon validation board GEM0 */
|
||||
#define MSS_MAC_DESIGN_SVG_SGMII_GEM1 (15) /*!< @brief Silicon validation board GEM1 */
|
||||
#define MSS_MAC_DESIGN_SVG_DUAL_GEM (16) /*!< @brief Silicon validation board both GEMS */
|
||||
#define MSS_MAC_DESIGN_SVG_GMII_GEM0 (17) /*!< @brief Silicon validation board GEM0 */
|
||||
#define MSS_MAC_DESIGN_SVG_GMII_GEM1 (18) /*!< @brief Silicon validation board GEM1 */
|
||||
#define MSS_MAC_DESIGN_ICICLE_SGMII_GEM0 (19) /*!< @brief Icicle board GEM0 */
|
||||
#define MSS_MAC_DESIGN_ICICLE_SGMII_GEM1 (20) /*!< @brief Icicle board GEM1 */
|
||||
#define MSS_MAC_DESIGN_ICICLE_SGMII_GEMS (21) /*!< @brief Icicle board GEM0 and GEM1 */
|
||||
#define MSS_MAC_DESIGN_ICICLE_STD_GEM0 (22) /*!< @brief Icicle board GEM0 Standard Reference Design */
|
||||
#define MSS_MAC_DESIGN_ICICLE_STD_GEM1 (23) /*!< @brief Icicle board GEM1 Standard Reference Design */
|
||||
#define MSS_MAC_DESIGN_ICICLE_STD_GEMS (24) /*!< @brief Icicle board GEM0 and GEM1 Standard Reference Design */
|
||||
#define MSS_MAC_DESIGN_SVG_GMII_GEM0_SGMII_GEM1 (25) /*!< @brief Silicon validation board GEM0 (GMII) and GEM1 (SGMII) */
|
||||
|
||||
#if defined(TARGET_ALOE)
|
||||
#define MSS_MAC_PHY_INTERFACE GMII /* Only one option allowed here... */
|
||||
#define MSS_MAC_RX_RING_SIZE (4U)
|
||||
#define MSS_MAC_TX_RING_SIZE (2U)
|
||||
#define MSS_MAC_PHYS (MSS_MAC_DEV_PHY_NULL | MSS_MAC_DEV_PHY_VSC8541)
|
||||
#define MSS_MAC_HW_PLATFORM MSS_MAC_DESIGN_ALOE
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Define one of these macros if using the VSC8662 PHY recovered clock through
|
||||
* the NWC at 25MHZ or 125MHZ. You will need to configure the SGMII PLL Mux as
|
||||
* well.
|
||||
*/
|
||||
#if defined(MSS_MAC_DOCUMENTATION)
|
||||
#define MSS_MAC_VSC8662_NWC_25
|
||||
#define MSS_MAC_VSC8662_NWC_125
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_G5_SOC)
|
||||
/***************************************************************************//**
|
||||
* This macro is a bit map that indicates which PHY sub drivers are included in
|
||||
* this build.
|
||||
*/
|
||||
#define MSS_MAC_PHYS (MSS_MAC_DEV_PHY_NULL | MSS_MAC_DEV_PHY_VSC8575_LITE | MSS_MAC_DEV_PHY_DP83867 | MSS_MAC_DEV_PHY_VSC8662 | MSS_MAC_DEV_PHY_VSC8541)
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set this macro to one of the _MSS_MAC_DESIGN_XX_ macros to configure the
|
||||
* hardware platform for the application.
|
||||
*/
|
||||
#define MSS_MAC_HW_PLATFORM MSS_MAC_DESIGN_ICICLE_STD_GEM0
|
||||
//#define MSS_MAC_HW_PLATFORM MSS_MAC_DESIGN_SVG_SGMII_GEM1
|
||||
//#define MSS_MAC_HW_PLATFORM MSS_MAC_DESIGN_EMUL_DUAL_EX_VTS
|
||||
/***************************************************************************//**
|
||||
* Number of receive buffer descriptors per queue.
|
||||
*
|
||||
* Minimum size is 16 as the descriptor caching implemented by the GEM DMA
|
||||
* requires that we make sure there are valid packet descriptors in all the
|
||||
* cached buffer slots.
|
||||
*/
|
||||
#define MSS_MAC_RX_RING_SIZE (16U)
|
||||
|
||||
/***************************************************************************//**
|
||||
* Number of transmit buffer descriptors per queue.
|
||||
*
|
||||
* Minimum size is 16 as the descriptor caching implemented by the GEM DMA
|
||||
* requires that we make sure there are valid packet descriptors in all the
|
||||
* cached buffer slots.
|
||||
*/
|
||||
#if defined(MSS_MAC_SPEED_TEST)
|
||||
#define MSS_MAC_TX_RING_SIZE (4001U)
|
||||
#else
|
||||
#define MSS_MAC_TX_RING_SIZE (16U)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Macros for testing for different PHY models supported in the current build.
|
||||
*/
|
||||
#define MSS_MAC_USE_PHY_VSC8575 (0U != (MSS_MAC_PHYS & MSS_MAC_DEV_PHY_VSC8575))
|
||||
#define MSS_MAC_USE_PHY_VSC8575_LITE (0U != (MSS_MAC_PHYS & MSS_MAC_DEV_PHY_VSC8575_LITE))
|
||||
#define MSS_MAC_USE_PHY_VSC8541 (0U != (MSS_MAC_PHYS & MSS_MAC_DEV_PHY_VSC8541))
|
||||
#define MSS_MAC_USE_PHY_DP83867 (0U != (MSS_MAC_PHYS & MSS_MAC_DEV_PHY_DP83867))
|
||||
#define MSS_MAC_USE_PHY_NULL (0U != (MSS_MAC_PHYS & MSS_MAC_DEV_PHY_NULL))
|
||||
#define MSS_MAC_USE_PHY_VSC8662 (0U != (MSS_MAC_PHYS & MSS_MAC_DEV_PHY_VSC8662))
|
||||
|
||||
/***************************************************************************//**
|
||||
* Macros for selecting options which change the size of the DMA descriptors.
|
||||
* Both these features change the layout of the descriptors as there are
|
||||
* additional entries needed in the descriptors to support them.
|
||||
*/
|
||||
#if !defined(MSS_MAC_SPEED_TEST) || defined(MSS_MAC_DOCUMENTATION)
|
||||
#define MSS_MAC_TIME_STAMPED_MODE (0) /*!< @brief Enable time stamp support */
|
||||
#define MSS_MAC_64_BIT_ADDRESS_MODE (0) /*!< @brief Enable 64 bit addressing */
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Defines for different memory areas. Set the macro _MSS_MAC_USE_DDR_ to one of
|
||||
* these values to select the area of memory and buffer sizes to use when
|
||||
* testing for non LIM based areas of memory.
|
||||
*/
|
||||
|
||||
#define MSS_MAC_MEM_DDR (0)
|
||||
#define MSS_MAC_MEM_FIC0 (1)
|
||||
#define MSS_MAC_MEM_FIC1 (2)
|
||||
#define MSS_MAC_MEM_CRYPTO (3)
|
||||
|
||||
/***************************************************************************//**
|
||||
* Number of additional queues for PMAC (eMAC only has 1).
|
||||
*
|
||||
* __Note:__ We explicitly set the number of queues in the MAC structure as we
|
||||
* have to indicate the Interrupt Number so this is slightly artificial...
|
||||
*/
|
||||
#if defined(TARGET_ALOE)
|
||||
#define MSS_MAC_QUEUE_COUNT (1)
|
||||
#else
|
||||
#if defined(MSS_MAC_SPEED_TEST)
|
||||
#define MSS_MAC_QUEUE_COUNT (1)
|
||||
#else
|
||||
#define MSS_MAC_QUEUE_COUNT (4)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* Number of Type 1 and 2 screeners for pMAC.
|
||||
*/
|
||||
|
||||
#define MSS_MAC_TYPE_1_SCREENERS (4U)
|
||||
#define MSS_MAC_TYPE_2_SCREENERS (4U)
|
||||
#define MSS_MAC_TYPE_2_ETHERTYPES (4U)
|
||||
#define MSS_MAC_TYPE_2_COMPARERS (12U)
|
||||
|
||||
/***************************************************************************//**
|
||||
* Number of Type 1 and 2 screeners for eMAC.
|
||||
*
|
||||
* These are hard coded and not user selectable
|
||||
*/
|
||||
#define MSS_MAC_EMAC_TYPE_2_SCREENERS (2U)
|
||||
#define MSS_MAC_EMAC_TYPE_2_COMPARERS (6U)
|
||||
|
||||
/***************************************************************************//**
|
||||
* Define one or both of these macros to enable support for hardware based
|
||||
* Hard Reset or Soft Reset of the PHY. This will result in inclusion of the
|
||||
* MSS GPIO driver in the project.
|
||||
*/
|
||||
#if defined(MSS_MAC_DOCUMENTATION)
|
||||
#define MSS_MAC_PHY_HW_RESET /*!< @brief If this is defined, the hard reset of the PHY is controllable via GPIO. */
|
||||
#endif
|
||||
#if defined(MSS_MAC_DOCUMENTATION)
|
||||
#define MSS_MAC_PHY_HW_SRESET /*!< @brief If this is defined, the hard reset of the PHY is controllable via GPIO. */
|
||||
#endif
|
||||
|
||||
#endif /* MICROSEMI__FIRMWARE__POLARFIRE_SOC_MSS_ETHERNET_MAC_DRIVER__1_7_107_CONFIGURATION_HEADER */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,482 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2020 Microchip Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* This file contains the type definitions for the GEM Ethernet MAC as
|
||||
* implemented for the PolarFire SoC. This also covers the subset implemented for
|
||||
* the FU540 on the Aloe board with the provisio that many of the registers will
|
||||
* not be present on that device.
|
||||
*
|
||||
* We use separate MAC and eMAC definitions even though the eMAC is a subset
|
||||
* of the MAC as it helps to catch errors if we try to program registers not
|
||||
* present on the eMAC.
|
||||
*
|
||||
*/
|
||||
#ifndef MSS_ETHERNET_MAC_REGISTERS_H_
|
||||
#define MSS_ETHERNET_MAC_REGISTERS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*----------------------------------- MAC -----------------------------------*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define __I const volatile
|
||||
#define __O volatile
|
||||
#define __IO volatile
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t NETWORK_CONTROL; /* 0x0000 */
|
||||
__IO uint32_t NETWORK_CONFIG; /* 0x0004 */
|
||||
__I uint32_t NETWORK_STATUS; /* 0x0008 */
|
||||
__IO uint32_t USER_IO; /* 0x000C */
|
||||
__IO uint32_t DMA_CONFIG; /* 0x0010 */
|
||||
__IO uint32_t TRANSMIT_STATUS; /* 0x0014 */
|
||||
__IO uint32_t RECEIVE_Q_PTR; /* 0x0018 */
|
||||
__IO uint32_t TRANSMIT_Q_PTR; /* 0x001C */
|
||||
__IO uint32_t RECEIVE_STATUS; /* 0x0020 */
|
||||
__IO uint32_t INT_STATUS; /* 0x0024 */
|
||||
__IO uint32_t INT_ENABLE; /* 0x0028 */
|
||||
__IO uint32_t INT_DISABLE; /* 0x002C */
|
||||
__IO uint32_t INT_MASK; /* 0x0030 */
|
||||
__IO uint32_t PHY_MANAGEMENT; /* 0x0034 */
|
||||
__IO uint32_t PAUSE_TIME; /* 0x0038 */
|
||||
__IO uint32_t TX_PAUSE_QUANTUM; /* 0x003C */
|
||||
__IO uint32_t PBUF_TXCUTTHRU; /* 0x0040 */
|
||||
__IO uint32_t PBUF_RXCUTTHRU; /* 0x0044 */
|
||||
__IO uint32_t JUMBO_MAX_LENGTH; /* 0x0048 */
|
||||
uint32_t reserved1; /* 0x004C */
|
||||
uint32_t reserved2; /* 0x0050 */
|
||||
__IO uint32_t AXI_MAX_PIPELINE; /* 0x0054 */
|
||||
uint32_t reserved3; /* 0x0058 */
|
||||
__IO uint32_t INT_MODERATION; /* 0x005C */
|
||||
__IO uint32_t SYS_WAKE_TIME; /* 0x0060 */
|
||||
__IO uint32_t FATAL_OR_NON_FATAL_INT_SEL; /* 0x0064 */
|
||||
__IO uint32_t LOCKUP_CONFIG; /* 0x0068 */
|
||||
__IO uint32_t RX_MAC_LOCKUP_TIME; /* 0x006C */
|
||||
uint32_t reserved4; /* 0x0070 */
|
||||
uint32_t reserved5; /* 0x0074 */
|
||||
uint32_t reserved6; /* 0x0078 */
|
||||
uint32_t reserved7; /* 0x007C */
|
||||
__IO uint32_t HASH_BOTTOM; /* 0x0080 */
|
||||
__IO uint32_t HASH_TOP; /* 0x0084 */
|
||||
__IO uint32_t SPEC_ADD1_BOTTOM; /* 0x0088 */
|
||||
__IO uint32_t SPEC_ADD1_TOP; /* 0x008C */
|
||||
__IO uint32_t SPEC_ADD2_BOTTOM; /* 0x0090 */
|
||||
__IO uint32_t SPEC_ADD2_TOP; /* 0x0094 */
|
||||
__IO uint32_t SPEC_ADD3_BOTTOM; /* 0x0098 */
|
||||
__IO uint32_t SPEC_ADD3_TOP; /* 0x009C */
|
||||
__IO uint32_t SPEC_ADD4_BOTTOM; /* 0x00A0 */
|
||||
__IO uint32_t SPEC_ADD4_TOP; /* 0x00A4 */
|
||||
__IO uint32_t SPEC_TYPE1; /* 0x00A8 */
|
||||
__IO uint32_t SPEC_TYPE2; /* 0x00AC */
|
||||
__IO uint32_t SPEC_TYPE3; /* 0x00B0 */
|
||||
__IO uint32_t SPEC_TYPE4; /* 0x00B4 */
|
||||
__IO uint32_t WOL_REGISTER; /* 0x00B8 */
|
||||
__IO uint32_t STRETCH_RATIO; /* 0x00BC */
|
||||
__IO uint32_t STACKED_VLAN; /* 0x00C0 */
|
||||
__IO uint32_t TX_PFC_PAUSE; /* 0x00C4 */
|
||||
__IO uint32_t MASK_ADD1_BOTTOM; /* 0x00C8 */
|
||||
__IO uint32_t MASK_ADD1_TOP; /* 0x00CC */
|
||||
__IO uint32_t DMA_ADDR_OR_MASK; /* 0x00D0 */
|
||||
__IO uint32_t RX_PTP_UNICAST; /* 0x00D4 */
|
||||
__IO uint32_t TX_PTP_UNICAST; /* 0x00D8 */
|
||||
__IO uint32_t TSU_NSEC_CMP; /* 0x00DC */
|
||||
__IO uint32_t TSU_SEC_CMP; /* 0x00E0 */
|
||||
__IO uint32_t TSU_MSB_SEC_CMP; /* 0x00E4 */
|
||||
__IO uint32_t TSU_PTP_TX_MSB_SEC_CMP; /* 0x00E8 */
|
||||
__IO uint32_t TSU_PTP_RX_MSB_SEC_CMP; /* 0x00EC */
|
||||
__IO uint32_t TSU_PEER_TX_MSB_SEC_CMP; /* 0x00F0 */
|
||||
__IO uint32_t TSU_PEER_RX_MSB_SEC_CMP; /* 0x00F4 */
|
||||
__IO uint32_t DPRAM_FILL_DBG; /* 0x00F8 */
|
||||
__IO uint32_t REVISION_REG; /* 0x00FC */
|
||||
__IO uint32_t OCTETS_TXED_BOTTOM; /* 0x0100 */
|
||||
__IO uint32_t OCTETS_TXED_TOP; /* 0x0104 */
|
||||
__IO uint32_t FRAMES_TXED_OK; /* 0x0108 */
|
||||
__IO uint32_t BROADCAST_TXED; /* 0x010C */
|
||||
__IO uint32_t MULTICAST_TXED; /* 0x0110 */
|
||||
__IO uint32_t PAUSE_FRAMES_TXED; /* 0x0114 */
|
||||
__IO uint32_t FRAMES_TXED_64; /* 0x0118 */
|
||||
__IO uint32_t FRAMES_TXED_65; /* 0x011C */
|
||||
__IO uint32_t FRAMES_TXED_128; /* 0x0120 */
|
||||
__IO uint32_t FRAMES_TXED_256; /* 0x0124 */
|
||||
__IO uint32_t FRAMES_TXED_512; /* 0x0128 */
|
||||
__IO uint32_t FRAMES_TXED_1024; /* 0x012C */
|
||||
__IO uint32_t FRAMES_TXED_1519; /* 0x0130 */
|
||||
__IO uint32_t TX_UNDERRUNS; /* 0x0134 */
|
||||
__IO uint32_t SINGLE_COLLISIONS; /* 0x0138 */
|
||||
__IO uint32_t MULTIPLE_COLLISIONS; /* 0x013C */
|
||||
__IO uint32_t EXCESSIVE_COLLISIONS; /* 0x0140 */
|
||||
__IO uint32_t LATE_COLLISIONS; /* 0x0144 */
|
||||
__IO uint32_t DEFERRED_FRAMES; /* 0x0148 */
|
||||
__IO uint32_t CRS_ERRORS; /* 0x014C */
|
||||
__IO uint32_t OCTETS_RXED_BOTTOM; /* 0x0150 */
|
||||
__IO uint32_t OCTETS_RXED_TOP; /* 0x0154 */
|
||||
__IO uint32_t FRAMES_RXED_OK; /* 0x0158 */
|
||||
__IO uint32_t BROADCAST_RXED; /* 0x015C */
|
||||
__IO uint32_t MULTICAST_RXED; /* 0x0160 */
|
||||
__IO uint32_t PAUSE_FRAMES_RXED; /* 0x0164 */
|
||||
__IO uint32_t FRAMES_RXED_64; /* 0x0168 */
|
||||
__IO uint32_t FRAMES_RXED_65; /* 0x016C */
|
||||
__IO uint32_t FRAMES_RXED_128; /* 0x0170 */
|
||||
__IO uint32_t FRAMES_RXED_256; /* 0x0174 */
|
||||
__IO uint32_t FRAMES_RXED_512; /* 0x0178 */
|
||||
__IO uint32_t FRAMES_RXED_1024; /* 0x017C */
|
||||
__IO uint32_t FRAMES_RXED_1519; /* 0x0180 */
|
||||
__IO uint32_t UNDERSIZE_FRAMES; /* 0x0184 */
|
||||
__IO uint32_t EXCESSIVE_RX_LENGTH; /* 0x0188 */
|
||||
__IO uint32_t RX_JABBERS; /* 0x018C */
|
||||
__IO uint32_t FCS_ERRORS; /* 0x0190 */
|
||||
__IO uint32_t RX_LENGTH_ERRORS; /* 0x0194 */
|
||||
__IO uint32_t RX_SYMBOL_ERRORS; /* 0x0198 */
|
||||
__IO uint32_t ALIGNMENT_ERRORS; /* 0x019C */
|
||||
__IO uint32_t RX_RESOURCE_ERRORS; /* 0x01A0 */
|
||||
__IO uint32_t RX_OVERRUNS; /* 0x01A4 */
|
||||
__IO uint32_t RX_IP_CK_ERRORS; /* 0x01A8 */
|
||||
__IO uint32_t RX_TCP_CK_ERRORS; /* 0x01AC */
|
||||
__IO uint32_t RX_UDP_CK_ERRORS; /* 0x01B0 */
|
||||
__IO uint32_t AUTO_FLUSHED_PKTS; /* 0x01B4 */
|
||||
uint32_t reserved8; /* 0x01B8 */
|
||||
__IO uint32_t TSU_TIMER_INCR_SUB_NSEC; /* 0x01BC */
|
||||
__IO uint32_t TSU_TIMER_MSB_SEC; /* 0x01C0 */
|
||||
__IO uint32_t TSU_STROBE_MSB_SEC; /* 0x01C4 */
|
||||
__IO uint32_t TSU_STROBE_SEC; /* 0x01C8 */
|
||||
__IO uint32_t TSU_STROBE_NSEC; /* 0x01CC */
|
||||
__IO uint32_t TSU_TIMER_SEC; /* 0x01D0 */
|
||||
__IO uint32_t TSU_TIMER_NSEC; /* 0x01D4 */
|
||||
__IO uint32_t TSU_TIMER_ADJUST; /* 0x01D8 */
|
||||
__IO uint32_t TSU_TIMER_INCR; /* 0x01DC */
|
||||
__IO uint32_t TSU_PTP_TX_SEC; /* 0x01E0 */
|
||||
__IO uint32_t TSU_PTP_TX_NSEC; /* 0x01E4 */
|
||||
__IO uint32_t TSU_PTP_RX_SEC; /* 0x01E8 */
|
||||
__IO uint32_t TSU_PTP_RX_NSEC; /* 0x01EC */
|
||||
__IO uint32_t TSU_PEER_TX_SEC; /* 0x01F0 */
|
||||
__IO uint32_t TSU_PEER_TX_NSEC; /* 0x01F4 */
|
||||
__IO uint32_t TSU_PEER_RX_SEC; /* 0x01F8 */
|
||||
__IO uint32_t TSU_PEER_RX_NSEC; /* 0x01FC */
|
||||
__IO uint32_t PCS_CONTROL; /* 0x0200 */
|
||||
__IO uint32_t PCS_STATUS; /* 0x0204 */
|
||||
__IO uint32_t PCS_PHY_TOP_ID; /* 0x0208 */
|
||||
__IO uint32_t PCS_PHY_BOT_ID; /* 0x020C */
|
||||
__IO uint32_t PCS_AN_ADV; /* 0x0210 */
|
||||
__IO uint32_t PCS_AN_LP_BASE; /* 0x0214 */
|
||||
__IO uint32_t PCS_AN_EXP; /* 0x0218 */
|
||||
__IO uint32_t PCS_AN_NP_TX; /* 0x021C */
|
||||
__IO uint32_t PCS_AN_LP_NP; /* 0x0220 */
|
||||
uint32_t reserved9[6]; /* 0x0224 - 0x0238 */
|
||||
__IO uint32_t PCS_AN_EXT_STATUS; /* 0x023C */
|
||||
uint32_t reserved10[8]; /* 0x0240 - 0x025C */
|
||||
__IO uint32_t TX_PAUSE_QUANTUM1; /* 0x0260 */
|
||||
__IO uint32_t TX_PAUSE_QUANTUM2; /* 0x0264 */
|
||||
__IO uint32_t TX_PAUSE_QUANTUM3; /* 0x0268 */
|
||||
__IO uint32_t PFC_STATUS; /* 0x026C */
|
||||
__IO uint32_t RX_LPI; /* 0x0270 */
|
||||
__IO uint32_t RX_LPI_TIME; /* 0x0274 */
|
||||
__IO uint32_t TX_LPI; /* 0x0278 */
|
||||
__IO uint32_t TX_LPI_TIME; /* 0x027C */
|
||||
__IO uint32_t DESIGNCFG_DEBUG1; /* 0x0280 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG2; /* 0x0284 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG3; /* 0x0288 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG4; /* 0x028C */
|
||||
__IO uint32_t DESIGNCFG_DEBUG5; /* 0x0290 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG6; /* 0x0294 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG7; /* 0x0298 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG8; /* 0x029C */
|
||||
__IO uint32_t DESIGNCFG_DEBUG9; /* 0x02A0 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG10; /* 0x02A4 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG11; /* 0x02A8 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG12; /* 0x02AC */
|
||||
uint32_t reserved11[12]; /* 0x02B0 - 0x02DC */
|
||||
__IO uint32_t AXI_QoS_CFG_0; /* 0X02E0 */
|
||||
uint32_t reserved11a[71]; /* 0x02E4 - 0x03FC */
|
||||
__IO uint32_t INT_Q1_STATUS; /* 0x0400 */
|
||||
__IO uint32_t INT_Q2_STATUS; /* 0x0404 */
|
||||
__IO uint32_t INT_Q3_STATUS; /* 0x0408 */
|
||||
uint32_t reserved12[13]; /* 0x040C - 0x043C */
|
||||
__IO uint32_t TRANSMIT_Q1_PTR; /* 0x0440 */
|
||||
__IO uint32_t TRANSMIT_Q2_PTR; /* 0x0444 */
|
||||
__IO uint32_t TRANSMIT_Q3_PTR; /* 0x0448 */
|
||||
uint32_t reserved13[13]; /* 0x044C - 0x047C */
|
||||
__IO uint32_t RECEIVE_Q1_PTR; /* 0x0480 */
|
||||
__IO uint32_t RECEIVE_Q2_PTR; /* 0x0484 */
|
||||
__IO uint32_t RECEIVE_Q3_PTR; /* 0x0488 */
|
||||
uint32_t reserved14[5]; /* 0x048C - 0x049C */
|
||||
__IO uint32_t DMA_RXBUF_SIZE_Q1; /* 0x04A0 */
|
||||
__IO uint32_t DMA_RXBUF_SIZE_Q2; /* 0x04A4 */
|
||||
__IO uint32_t DMA_RXBUF_SIZE_Q3; /* 0x04A8 */
|
||||
uint32_t reserved15[4]; /* 0x04AC - 0x04B8 */
|
||||
__IO uint32_t CBS_CONTROL; /* 0x04BC */
|
||||
__IO uint32_t CBS_IDLESLOPE_Q_A; /* 0x04C0 */
|
||||
__IO uint32_t CBS_IDLESLOPE_Q_B; /* 0x04C4 */
|
||||
__IO uint32_t UPPER_TX_Q_BASE_ADDR; /* 0x04C8 */
|
||||
__IO uint32_t TX_BD_CONTROL; /* 0x04CC */
|
||||
__IO uint32_t RX_BD_CONTROL; /* 0x04D0 */
|
||||
__IO uint32_t UPPER_RX_Q_BASE_ADDR; /* 0x04D4 */
|
||||
uint32_t reserved16[5]; /* 0x04D8 - 0x04E8 */
|
||||
__IO uint32_t WD_COUNTER; /* 0x04EC */
|
||||
uint32_t reserved17[2]; /* 0x04F0 - 0x04F4 */
|
||||
__IO uint32_t AXI_TX_FULL_THRESH0; /* 0x04F8 */
|
||||
__IO uint32_t AXI_TX_FULL_THRESH1; /* 0x04FC */
|
||||
__IO uint32_t SCREENING_TYPE_1_REGISTER_0; /* 0x0500 */
|
||||
__IO uint32_t SCREENING_TYPE_1_REGISTER_1; /* 0x0504 */
|
||||
__IO uint32_t SCREENING_TYPE_1_REGISTER_2; /* 0x0508 */
|
||||
__IO uint32_t SCREENING_TYPE_1_REGISTER_3; /* 0x050C */
|
||||
uint32_t reserved18[12]; /* 0x0510 - 0x053C */
|
||||
__IO uint32_t SCREENING_TYPE_2_REGISTER_0; /* 0x0540 */
|
||||
__IO uint32_t SCREENING_TYPE_2_REGISTER_1; /* 0x0544 */
|
||||
__IO uint32_t SCREENING_TYPE_2_REGISTER_2; /* 0x0548 */
|
||||
__IO uint32_t SCREENING_TYPE_2_REGISTER_3; /* 0x054C */
|
||||
uint32_t reserved18b[12]; /* 0x0550 - 0x057C */
|
||||
__IO uint32_t TX_SCHED_CTRL; /* 0x0580 */
|
||||
uint32_t reserved19[3]; /* 0x0584 - 0x058C */
|
||||
__IO uint32_t BW_RATE_LIMIT_Q0TO3; /* 0x0590 */
|
||||
uint32_t reserved20[3]; /* 0x0594 - 0x059C */
|
||||
__IO uint32_t TX_Q_SEG_ALLOC_Q0TO3; /* 0x05A0 */
|
||||
uint32_t reserved21[23]; /* 0x05A4 - 0x05FC */
|
||||
__IO uint32_t INT_Q1_ENABLE; /* 0x0600 */
|
||||
__IO uint32_t INT_Q2_ENABLE; /* 0x0604 */
|
||||
__IO uint32_t INT_Q3_ENABLE; /* 0x0608 */
|
||||
uint32_t reserved22[5]; /* 0x060C - 0x061C */
|
||||
__IO uint32_t INT_Q1_DISABLE; /* 0x0620 */
|
||||
__IO uint32_t INT_Q2_DISABLE; /* 0x0624 */
|
||||
__IO uint32_t INT_Q3_DISABLE; /* 0x0628 */
|
||||
uint32_t reserved23[5]; /* 0x062C - 0x063C */
|
||||
__IO uint32_t INT_Q1_MASK; /* 0x0640 */
|
||||
__IO uint32_t INT_Q2_MASK; /* 0x0644 */
|
||||
__IO uint32_t INT_Q3_MASK; /* 0x0648 */
|
||||
uint32_t reserved24[37]; /* 0x064C - 0x06DC */
|
||||
__IO uint32_t SCREENING_TYPE_2_ETHERTYPE_REG_0; /* 0x06E0 */
|
||||
__IO uint32_t SCREENING_TYPE_2_ETHERTYPE_REG_1; /* 0x06E4 */
|
||||
__IO uint32_t SCREENING_TYPE_2_ETHERTYPE_REG_2; /* 0x06E8 */
|
||||
__IO uint32_t SCREENING_TYPE_2_ETHERTYPE_REG_3; /* 0x06EC */
|
||||
uint32_t reserved25[4]; /* 0x06F0 - 0x06FC */
|
||||
__IO uint32_t TYPE2_COMPARE_0_WORD_0; /* 0x0700 */
|
||||
__IO uint32_t TYPE2_COMPARE_0_WORD_1; /* 0x0704 */
|
||||
__IO uint32_t TYPE2_COMPARE_1_WORD_0; /* 0x0708 */
|
||||
__IO uint32_t TYPE2_COMPARE_1_WORD_1; /* 0x070C */
|
||||
__IO uint32_t TYPE2_COMPARE_2_WORD_0; /* 0x0710 */
|
||||
__IO uint32_t TYPE2_COMPARE_2_WORD_1; /* 0x0714 */
|
||||
__IO uint32_t TYPE2_COMPARE_3_WORD_0; /* 0x0718 */
|
||||
__IO uint32_t TYPE2_COMPARE_3_WORD_1; /* 0x071C */
|
||||
uint32_t reserved26[56]; /* 0x0720 - 0x07FC */
|
||||
__IO uint32_t ENST_START_TIME_Q0; /* 0x0800 */
|
||||
__IO uint32_t ENST_START_TIME_Q1; /* 0x0804 */
|
||||
__IO uint32_t ENST_START_TIME_Q2; /* 0x0808 */
|
||||
__IO uint32_t ENST_START_TIME_Q3; /* 0x080C */
|
||||
uint32_t reserved27[4]; /* 0x0810 - 0x081C */
|
||||
__IO uint32_t ENST_ON_TIME_Q0; /* 0x0820 */
|
||||
__IO uint32_t ENST_ON_TIME_Q1; /* 0x0824 */
|
||||
__IO uint32_t ENST_ON_TIME_Q2; /* 0x0828 */
|
||||
__IO uint32_t ENST_ON_TIME_Q3; /* 0x082C */
|
||||
uint32_t reserved28[4]; /* 0x0830 - 0x083C */
|
||||
__IO uint32_t ENST_OFF_TIME_Q0; /* 0x0840 */
|
||||
__IO uint32_t ENST_OFF_TIME_Q1; /* 0x0844 */
|
||||
__IO uint32_t ENST_OFF_TIME_Q2; /* 0x0848 */
|
||||
__IO uint32_t ENST_OFF_TIME_Q3; /* 0x084C */
|
||||
__IO uint32_t ENST_CONTROL; /* 0x0850 */
|
||||
uint32_t reserved29[427]; /* 0x0854 - 0x0EFC */
|
||||
__IO uint32_t MMSL_CONTROL; /* 0x0F00 */
|
||||
__IO uint32_t MMSL_STATUS; /* 0x0F04 */
|
||||
__IO uint32_t MMSL_ERR_STATS; /* 0x0F08 */
|
||||
__IO uint32_t MMSL_ASS_OK_COUNT; /* 0x0F0C */
|
||||
__IO uint32_t MMSL_FRAG_COUNT_RX; /* 0x0F10 */
|
||||
__IO uint32_t MMSL_FRAG_COUNT_TX; /* 0x0F14 */
|
||||
__IO uint32_t MMSL_INT_STATUS; /* 0x0F18 */
|
||||
__IO uint32_t MMSL_INT_ENABLE; /* 0x0F1C */
|
||||
__IO uint32_t MMSL_INT_DISABLE; /* 0x0F20 */
|
||||
__IO uint32_t MMSL_INT_MASK; /* 0x0F24 */
|
||||
uint32_t reserved30[54]; /* 0x0F28 - 0x0FFC */
|
||||
} MAC_TypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t NETWORK_CONTROL; /* 0x1000 */
|
||||
__IO uint32_t NETWORK_CONFIG; /* 0x1004 */
|
||||
__IO uint32_t NETWORK_STATUS; /* 0x1008 */
|
||||
uint32_t reserved31; /* 0x100C */
|
||||
__IO uint32_t DMA_CONFIG; /* 0x1010 */
|
||||
__IO uint32_t TRANSMIT_STATUS; /* 0x1014 */
|
||||
__IO uint32_t RECEIVE_Q_PTR; /* 0x1018 */
|
||||
__IO uint32_t TRANSMIT_Q_PTR; /* 0x101C */
|
||||
__IO uint32_t RECEIVE_STATUS; /* 0x1020 */
|
||||
__IO uint32_t INT_STATUS; /* 0x1024 */
|
||||
__IO uint32_t INT_ENABLE; /* 0x1028 */
|
||||
__IO uint32_t INT_DISABLE; /* 0x102C */
|
||||
__IO uint32_t INT_MASK; /* 0x1030 */
|
||||
__IO uint32_t PHY_MANAGEMENT; /* 0x1034 */
|
||||
__IO uint32_t PAUSE_TIME; /* 0x1038 */
|
||||
__IO uint32_t TX_PAUSE_QUANTUM; /* 0x103C */
|
||||
__IO uint32_t PBUF_TXCUTTHRU; /* 0x1040 */
|
||||
__IO uint32_t PBUF_RXCUTTHRU; /* 0x1044 */
|
||||
__IO uint32_t JUMBO_MAX_LENGTH; /* 0x1048 */
|
||||
uint32_t reserved32[2]; /* 0x104C - 0x1050 */
|
||||
__IO uint32_t AXI_MAX_PIPELINE; /* 0x1054 */
|
||||
uint32_t reserved33; /* 0x1058 */
|
||||
__IO uint32_t INT_MODERATION; /* 0x105C */
|
||||
__IO uint32_t SYS_WAKE_TIME; /* 0x1060 */
|
||||
__IO uint32_t FATAL_OR_NON_FATAL_INT_SEL; /* 0x1064 */
|
||||
__IO uint32_t LOCKUP_CONFIG; /* 0x1068 */
|
||||
__IO uint32_t RX_MAC_LOCKUP_TIME; /* 0x106C */
|
||||
uint32_t reserved34[4]; /* 0x1070 - 0x107C */
|
||||
__IO uint32_t HASH_BOTTOM; /* 0x1080 */
|
||||
__IO uint32_t HASH_TOP; /* 0x1084 */
|
||||
__IO uint32_t SPEC_ADD1_BOTTOM; /* 0x1088 */
|
||||
__IO uint32_t SPEC_ADD1_TOP; /* 0x108C */
|
||||
__IO uint32_t SPEC_ADD2_BOTTOM; /* 0x1090 */
|
||||
__IO uint32_t SPEC_ADD2_TOP; /* 0x1094 */
|
||||
__IO uint32_t SPEC_ADD3_BOTTOM; /* 0x1098 */
|
||||
__IO uint32_t SPEC_ADD3_TOP; /* 0x109C */
|
||||
__IO uint32_t SPEC_ADD4_BOTTOM; /* 0x10A0 */
|
||||
__IO uint32_t SPEC_ADD4_TOP; /* 0x10A4 */
|
||||
__IO uint32_t SPEC_TYPE1; /* 0x10A8 */
|
||||
__IO uint32_t SPEC_TYPE2; /* 0x10AC */
|
||||
__IO uint32_t SPEC_TYPE3; /* 0x10B0 */
|
||||
__IO uint32_t SPEC_TYPE4; /* 0x10B4 */
|
||||
__IO uint32_t WOL_REGISTER; /* 0x10B8 */
|
||||
__IO uint32_t STRETCH_RATIO; /* 0x10BC */
|
||||
__IO uint32_t STACKED_VLAN; /* 0x10C0 */
|
||||
__IO uint32_t TX_PFC_PAUSE; /* 0x10C4 */
|
||||
__IO uint32_t MASK_ADD1_BOTTOM; /* 0x10C8 */
|
||||
__IO uint32_t MASK_ADD1_TOP; /* 0x10CC */
|
||||
__IO uint32_t DMA_ADDR_OR_MASK; /* 0x10D0 */
|
||||
__IO uint32_t RX_PTP_UNICAST; /* 0x10D4 */
|
||||
__IO uint32_t TX_PTP_UNICAST; /* 0x10D8 */
|
||||
__IO uint32_t TSU_NSEC_CMP; /* 0x10DC */
|
||||
__IO uint32_t TSU_SEC_CMP; /* 0x10E0 */
|
||||
__IO uint32_t TSU_MSB_SEC_CMP; /* 0x10E4 */
|
||||
__IO uint32_t TSU_PTP_TX_MSB_SEC; /* 0x10E8 */
|
||||
__IO uint32_t TSU_PTP_RX_MSB_SEC; /* 0x10EC */
|
||||
__IO uint32_t TSU_PEER_TX_MSB_SEC; /* 0x10F0 */
|
||||
__IO uint32_t TSU_PEER_RX_MSB_SEC; /* 0x10F4 */
|
||||
__IO uint32_t DPRAM_FILL_DBG; /* 0x10F8 */
|
||||
__IO uint32_t REVISION_REG; /* 0x10FC */
|
||||
__IO uint32_t OCTETS_TXED_BOTTOM; /* 0x1100 */
|
||||
__IO uint32_t OCTETS_TXED_TOP; /* 0x1104 */
|
||||
__IO uint32_t FRAMES_TXED_OK; /* 0x1108 */
|
||||
__IO uint32_t BROADCAST_TXED; /* 0x110C */
|
||||
__IO uint32_t MULTICAST_TXED; /* 0x1110 */
|
||||
__IO uint32_t PAUSE_FRAMES_TXED; /* 0x1114 */
|
||||
__IO uint32_t FRAMES_TXED_64; /* 0x1118 */
|
||||
__IO uint32_t FRAMES_TXED_65; /* 0x111C */
|
||||
__IO uint32_t FRAMES_TXED_128; /* 0x1120 */
|
||||
__IO uint32_t FRAMES_TXED_256; /* 0x1124 */
|
||||
__IO uint32_t FRAMES_TXED_512; /* 0x1128 */
|
||||
__IO uint32_t FRAMES_TXED_1024; /* 0x112C */
|
||||
__IO uint32_t FRAMES_TXED_1519; /* 0x1130 */
|
||||
__IO uint32_t TX_UNDERRUNS; /* 0x1134 */
|
||||
__IO uint32_t SINGLE_COLLISIONS; /* 0x1138 */
|
||||
__IO uint32_t MULTIPLE_COLLISIONS; /* 0x113C */
|
||||
__IO uint32_t EXCESSIVE_COLLISIONS; /* 0x1140 */
|
||||
__IO uint32_t LATE_COLLISIONS; /* 0x1144 */
|
||||
__IO uint32_t DEFERRED_FRAMES; /* 0x1148 */
|
||||
__IO uint32_t CRS_ERRORS; /* 0x114C */
|
||||
__IO uint32_t OCTETS_RXED_BOTTOM; /* 0x1150 */
|
||||
__IO uint32_t OCTETS_RXED_TOP; /* 0x1154 */
|
||||
__IO uint32_t FRAMES_RXED_OK; /* 0x1158 */
|
||||
__IO uint32_t BROADCAST_RXED; /* 0x115C */
|
||||
__IO uint32_t MULTICAST_RXED; /* 0x1160 */
|
||||
__IO uint32_t PAUSE_FRAMES_RXED; /* 0x1164 */
|
||||
__IO uint32_t FRAMES_RXED_64; /* 0x1168 */
|
||||
__IO uint32_t FRAMES_RXED_65; /* 0x116C */
|
||||
__IO uint32_t FRAMES_RXED_128; /* 0x1170 */
|
||||
__IO uint32_t FRAMES_RXED_256; /* 0x1174 */
|
||||
__IO uint32_t FRAMES_RXED_512; /* 0x1178 */
|
||||
__IO uint32_t FRAMES_RXED_1024; /* 0x117C */
|
||||
__IO uint32_t FRAMES_RXED_1519; /* 0x1180 */
|
||||
__IO uint32_t UNDERSIZE_FRAMES; /* 0x1184 */
|
||||
__IO uint32_t EXCESSIVE_RX_LENGTH; /* 0x1188 */
|
||||
__IO uint32_t RX_JABBERS; /* 0x118C */
|
||||
__IO uint32_t FCS_ERRORS; /* 0x1190 */
|
||||
__IO uint32_t RX_LENGTH_ERRORS; /* 0x1194 */
|
||||
__IO uint32_t RX_SYMBOL_ERRORS; /* 0x1198 */
|
||||
__IO uint32_t ALIGNMENT_ERRORS; /* 0x119C */
|
||||
__IO uint32_t RX_RESOURCE_ERRORS; /* 0x11A0 */
|
||||
__IO uint32_t RX_OVERRUNS; /* 0x11A4 */
|
||||
__IO uint32_t RX_IP_CK_ERRORS; /* 0x11A8 */
|
||||
__IO uint32_t RX_TCP_CK_ERRORS; /* 0x11AC */
|
||||
__IO uint32_t RX_UDP_CK_ERRORS; /* 0x11B0 */
|
||||
__IO uint32_t AUTO_FLUSHED_PKTS; /* 0x11B4 */
|
||||
uint32_t reserved35; /* 0x10B8 */
|
||||
__IO uint32_t TSU_TIMER_INCR_SUB_NSEC; /* 0x11BC */
|
||||
__IO uint32_t TSU_TIMER_MSB_SEC; /* 0x11C0 */
|
||||
__IO uint32_t TSU_STROBE_MSB_SEC; /* 0x11C4 */
|
||||
__IO uint32_t TSU_STROBE_SEC; /* 0x11C8 */
|
||||
__IO uint32_t TSU_STROBE_NSEC; /* 0x11CC */
|
||||
__IO uint32_t TSU_TIMER_SEC; /* 0x11D0 */
|
||||
__IO uint32_t TSU_TIMER_NSEC; /* 0x11D4 */
|
||||
__IO uint32_t TSU_TIMER_ADJUST; /* 0x11D8 */
|
||||
__IO uint32_t TSU_TIMER_INCR; /* 0x11DC */
|
||||
__IO uint32_t TSU_PTP_TX_SEC; /* 0x11E0 */
|
||||
__IO uint32_t TSU_PTP_TX_NSEC; /* 0x11E4 */
|
||||
__IO uint32_t TSU_PTP_RX_SEC; /* 0x11E8 */
|
||||
__IO uint32_t TSU_PTP_RX_NSEC; /* 0x11EC */
|
||||
__IO uint32_t TSU_PEER_TX_SEC; /* 0x11F0 */
|
||||
__IO uint32_t TSU_PEER_TX_NSEC; /* 0x11F4 */
|
||||
__IO uint32_t TSU_PEER_RX_SEC; /* 0x11F8 */
|
||||
__IO uint32_t TSU_PEER_RX_NSEC; /* 0x11FC */
|
||||
uint32_t reserved36[24]; /* 0x1200 - 0x125C */
|
||||
__IO uint32_t TX_PAUSE_QUANTUM1; /* 0x1260 */
|
||||
__IO uint32_t TX_PAUSE_QUANTUM2; /* 0x1264 */
|
||||
__IO uint32_t TX_PAUSE_QUANTUM3; /* 0x1268 */
|
||||
__IO uint32_t PFC_STATUS; /* 0x126C */
|
||||
__IO uint32_t RX_LPI; /* 0x1270 */
|
||||
__IO uint32_t RX_LPI_TIME; /* 0x1274 */
|
||||
__IO uint32_t TX_LPI; /* 0x1278 */
|
||||
__IO uint32_t TX_LPI_TIME; /* 0x127C */
|
||||
__IO uint32_t DESIGNCFG_DEBUG1; /* 0x1280 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG2; /* 0x1284 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG3; /* 0x1288 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG4; /* 0x128C */
|
||||
__IO uint32_t DESIGNCFG_DEBUG5; /* 0x1290 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG6; /* 0x1294 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG7; /* 0x1298 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG8; /* 0x129C */
|
||||
__IO uint32_t DESIGNCFG_DEBUG9; /* 0x12A0 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG10; /* 0x12A4 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG11; /* 0x12A8 */
|
||||
__IO uint32_t DESIGNCFG_DEBUG12; /* 0x12AC */
|
||||
uint32_t reserved37[12]; /* 0x12B0 - 0x12DC */
|
||||
__IO uint32_t AXI_QoS_CFG_0; /* 0X12E0 */
|
||||
uint32_t reserved37a[118]; /* 0x12E4 - 0x14B8 */
|
||||
__IO uint32_t CBS_CONTROL; /* 0x14BC */
|
||||
__IO uint32_t CBS_IDLESLOPE_Q_A; /* 0x14C0 */
|
||||
__IO uint32_t CBS_IDLESLOPE_Q_B; /* 0x14C4 */
|
||||
__IO uint32_t UPPER_TX_Q_BASE_ADDR; /* 0x14C8 */
|
||||
__IO uint32_t TX_BD_CONTROL; /* 0x14CC */
|
||||
__IO uint32_t RX_BD_CONTROL; /* 0x14D0 */
|
||||
__IO uint32_t UPPER_RX_Q_BASE_ADDR; /* 0x14D4 */
|
||||
uint32_t reserved38[10]; /* 0x14D8 - 0x14FC */
|
||||
__IO uint32_t SCREENING_TYPE_1_REGISTER_0; /* 0x1500 - TBD PMCS Remove this and look for other possible additional registers near end of eMAC that we might be missing... */
|
||||
uint32_t reserved39[15]; /* 0x1504 - 0x153C */
|
||||
__IO uint32_t SCREENING_TYPE_2_REGISTER_0; /* 0x1540 */
|
||||
__IO uint32_t SCREENING_TYPE_2_REGISTER_1; /* 0x1544 */
|
||||
uint32_t reserved40[110]; /* 0x1548 - 0x16FC */
|
||||
__IO uint32_t TYPE2_COMPARE_0_WORD_0; /* 0x1700 */
|
||||
__IO uint32_t TYPE2_COMPARE_0_WORD_1; /* 0x1704 */
|
||||
__IO uint32_t TYPE2_COMPARE_1_WORD_0; /* 0x1708 */
|
||||
__IO uint32_t TYPE2_COMPARE_1_WORD_1; /* 0x170C */
|
||||
__IO uint32_t TYPE2_COMPARE_2_WORD_0; /* 0x1710 */
|
||||
__IO uint32_t TYPE2_COMPARE_2_WORD_1; /* 0x1714 */
|
||||
__IO uint32_t TYPE2_COMPARE_3_WORD_0; /* 0x1718 */
|
||||
__IO uint32_t TYPE2_COMPARE_3_WORD_1; /* 0x171C */
|
||||
__IO uint32_t TYPE2_COMPARE_4_WORD_0; /* 0x1720 */
|
||||
__IO uint32_t TYPE2_COMPARE_4_WORD_1; /* 0x1724 */
|
||||
__IO uint32_t TYPE2_COMPARE_5_WORD_0; /* 0x1728 */
|
||||
__IO uint32_t TYPE2_COMPARE_5_WORD_1; /* 0x172C */
|
||||
uint32_t reserved41[52]; /* 0x1730 - 0x17FC */
|
||||
__IO uint32_t ENST_START_TIME; /* 0x1800 */
|
||||
uint32_t reserved42[7]; /* 0x1804 - 0x181C */
|
||||
__IO uint32_t ENST_ON_TIME; /* 0x1820 */
|
||||
uint32_t reserved43[7]; /* 0x1824 - 0x183C */
|
||||
__IO uint32_t ENST_OFF_TIME; /* 0x1840 */
|
||||
uint32_t reserved44[15]; /* 0x1844 - 0x187C */
|
||||
__IO uint32_t ENST_CONTROL; /* 0x1820 */
|
||||
} eMAC_TypeDef;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_ETHERNET_MAC_REGISTERS_H_ */
|
|
@ -0,0 +1,129 @@
|
|||
|
||||
/*******************************************************************************
|
||||
* Copyright 2020 Microchip Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* NULL PHY implementation.
|
||||
*
|
||||
* This PHY interface is used when there is a direct connection between two GEM
|
||||
* instances which does not involve the use of a PHY device.
|
||||
*
|
||||
* Also used when setting up the default config so that the pointers for the
|
||||
* PHY functions in the config always have some valid values.
|
||||
*
|
||||
*/
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_registers.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_sw_cfg.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac.h"
|
||||
#include "drivers/mss_ethernet_mac/phy.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_NULL
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_NULL_phy_init(/* mss_mac_instance_t */ const void *v_this_mac, uint8_t phy_addr)
|
||||
{
|
||||
/* Nothing to see here... */
|
||||
(void)v_this_mac;
|
||||
(void)phy_addr;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_NULL_phy_set_link_speed(/* mss_mac_instance_t */ void *v_this_mac, uint32_t speed_duplex_select, mss_mac_speed_mode_t speed_mode)
|
||||
{
|
||||
/* Nothing to see here... */
|
||||
(void)v_this_mac;
|
||||
(void)speed_duplex_select;
|
||||
(void)speed_mode;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_NULL_phy_autonegotiate(/* mss_mac_instance_ t */ const void *v_this_mac)
|
||||
{
|
||||
/* Nothing to see here... */
|
||||
(void)v_this_mac;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_NULL_phy_mac_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac)
|
||||
{
|
||||
/* Nothing to see here... */
|
||||
(void)v_this_mac;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
uint8_t MSS_MAC_NULL_phy_get_link_status
|
||||
(
|
||||
/* mss_mac_instance_t */ const void *v_this_mac,
|
||||
mss_mac_speed_t * speed,
|
||||
uint8_t * fullduplex
|
||||
)
|
||||
{
|
||||
uint8_t link_status;
|
||||
|
||||
(void)v_this_mac;
|
||||
/* Assume link is up. */
|
||||
link_status = MSS_MAC_LINK_UP;
|
||||
|
||||
/* Pick fastest for now... */
|
||||
|
||||
*fullduplex = MSS_MAC_FULL_DUPLEX;
|
||||
*speed = MSS_MAC_1000MBPS;
|
||||
|
||||
return link_status;
|
||||
}
|
||||
|
||||
#if MSS_MAC_USE_PHY_DP83867
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
uint16_t NULL_ti_read_extended_regs(/* mss_mac_instance_t */ const void *v_this_mac, uint16_t reg)
|
||||
{
|
||||
(void)v_this_mac;
|
||||
(void)reg;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void NULL_ti_write_extended_regs(/* mss_mac_instance_t */ const void *v_this_mac, uint16_t reg, uint16_t data)
|
||||
{
|
||||
(void)v_this_mac;
|
||||
(void)reg;
|
||||
(void)data;
|
||||
|
||||
/* Nothing to see here... */
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_MAC_USE_PHY_NULL */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************** END OF FILE ******************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,400 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2020 Microchip Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Register bit definitions for MII STA (station management entity) standard
|
||||
* interface. All basic MII register bits and enhanced capability register bits
|
||||
* are defined.
|
||||
* Complies with Clauses 22, 28, 37, 40 of IEEE RFC 802.3
|
||||
*
|
||||
*/
|
||||
#ifndef PSE_PHY_H
|
||||
#define PSE_PHY_H
|
||||
#include "../mss_ethernet_mac/mss_ethernet_mac_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
/* Public definitions */
|
||||
/**************************************************************************/
|
||||
/*------------------------------------------------------------------------------
|
||||
* MII register definitions.
|
||||
*/
|
||||
/* Generic MII registers. */
|
||||
#define MII_BMCR (0X00U) /* Basic mode control register */
|
||||
#define MII_BMSR (0X01U) /* Basic mode status register */
|
||||
#define MII_PHYSID1 (0X02U) /* PHYS ID 1 */
|
||||
#define MII_PHYSID2 (0X03U) /* PHYS ID 2 */
|
||||
#define MII_ADVERTISE (0X04U) /* Advertisement control reg */
|
||||
#define MII_LPA (0X05U) /* Link partner ability reg */
|
||||
#define MII_EXPANSION (0X06U) /* Expansion register */
|
||||
#define MII_NPAR (0X07U)
|
||||
#define MII_LPNPA (0X08U)
|
||||
#define MII_CTRL1000 (0X09U) /* 1000BASE-T control */
|
||||
#define MII_STAT1000 (0X0AU) /* 1000BASE-T status */
|
||||
#define MII_ESTATUS (0X0FU) /* Extended Status */
|
||||
#define MII_DCOUNTER (0X12U) /* Disconnect counter */
|
||||
#define MII_FCSCOUNTER (0X13U) /* False carrier counter */
|
||||
#define MII_EXTEND (0X14U) /* extended PHY specific ctrl */
|
||||
#define MII_RERRCOUNTER (0X15U) /* Receive error counter */
|
||||
#define MII_SREVISION (0X16U) /* Silicon revision */
|
||||
#define MII_RESV1 (0X17U) /* Reserved... */
|
||||
#define MII_LBRERROR (0X18U) /* Lpback, rx, bypass error */
|
||||
#define MII_PHYADDR (0X19U) /* PHY address */
|
||||
#define MII_RESV2 (0X1AU) /* Reserved... */
|
||||
#define MII_TPISTATUS (0X1BU) /* TPI status for 10mbps */
|
||||
#define MII_NCONFIG (0X1CU) /* Network interface config */
|
||||
#define MII_LMCS (0X1DU)
|
||||
#define MII_PHYCTRL1 (0X1EU)
|
||||
#define MII_PHYCTRL2 (0X1FU)
|
||||
|
||||
#define MII_TI_REGCR (0X0DU)
|
||||
#define MII_TI_ADDAR (0X0EU)
|
||||
#define MII_TI_PHYCR (0X10U)
|
||||
#define MII_TI_CTRL (0X1FU)
|
||||
#define MII_TI_SGMIICTL1 (0XD3U)
|
||||
|
||||
/* Basic mode control register. */
|
||||
#define BMCR_RESV (0x003FU) /* Unused... */
|
||||
#define BMCR_SPEED1000 (0x0040U) /* MSB of Speed (1000) */
|
||||
#define BMCR_CTST (0x0080U) /* Collision test */
|
||||
#define BMCR_FULLDPLX (0x0100U) /* Full duplex */
|
||||
#define BMCR_ANRESTART (0x0200U) /* Auto negotiation restart */
|
||||
#define BMCR_ISOLATE (0x0400U) /* Disconnect DP83840 from MII */
|
||||
#define BMCR_PDOWN (0x0800U) /* Powerdown the DP83840 */
|
||||
#define BMCR_ANENABLE (0x1000U) /* Enable auto negotiation */
|
||||
#define BMCR_SPEED100 (0x2000U) /* Select 100Mbps */
|
||||
#define BMCR_LOOPBACK (0x4000U) /* TXD loopback bits */
|
||||
#define BMCR_RESET (0x8000U) /* Reset the DP83840 */
|
||||
|
||||
/* Basic mode status register. */
|
||||
#define BMSR_ERCAP (0x0001U) /* Ext-reg capability */
|
||||
#define BMSR_JCD (0x0002U) /* Jabber detected */
|
||||
#define BMSR_LSTATUS (0x0004U) /* Link status */
|
||||
#define BMSR_ANEGCAPABLE (0x0008U) /* Able to do auto-negotiation */
|
||||
#define BMSR_RFAULT (0x0010U) /* Remote fault detected */
|
||||
#define BMSR_ANEGCOMPLETE (0x0020U) /* Auto-negotiation complete */
|
||||
#define BMSR_RESV (0x00c0U) /* Unused... */
|
||||
#define BMSR_ESTATEN (0x0100U) /* Extended Status in R15 */
|
||||
#define BMSR_100HALF2 (0x0200U) /* Can do 100BASE-T2 HDX */
|
||||
#define BMSR_100FULL2 (0x0400U) /* Can do 100BASE-T2 FDX */
|
||||
#define BMSR_10HALF (0x0800U) /* Can do 10mbps, half-duplex */
|
||||
#define BMSR_10FULL (0x1000U) /* Can do 10mbps, full-duplex */
|
||||
#define BMSR_100HALF (0x2000U) /* Can do 100mbps, half-duplex */
|
||||
#define BMSR_100FULL (0x4000U) /* Can do 100mbps, full-duplex */
|
||||
#define BMSR_100BASE4 (0x8000U) /* Can do 100mbps, 4k packets */
|
||||
|
||||
/* Advertisement control register. */
|
||||
#define ADVERTISE_SLCT (0x001FU) /* Selector bits */
|
||||
#define ADVERTISE_CSMA (0x0001U) /* Only selector supported */
|
||||
#define ADVERTISE_10HALF (0x0020U) /* Try for 10mbps half-duplex */
|
||||
#define ADVERTISE_1000XFULL (0x0020U) /* Try for 1000BASE-X full-duplex */
|
||||
#define ADVERTISE_10FULL (0x0040U) /* Try for 10mbps full-duplex */
|
||||
#define ADVERTISE_1000XHALF (0x0040U) /* Try for 1000BASE-X half-duplex */
|
||||
#define ADVERTISE_100HALF (0x0080U) /* Try for 100mbps half-duplex */
|
||||
#define ADVERTISE_1000XPAUSE (0x0080U) /* Try for 1000BASE-X pause */
|
||||
#define ADVERTISE_100FULL (0x0100U) /* Try for 100mbps full-duplex */
|
||||
#define ADVERTISE_1000XPSE_ASYM (0x0100U) /* Try for 1000BASE-X asym pause */
|
||||
#define ADVERTISE_100BASE4 (0x0200U) /* Try for 100mbps 4k packets */
|
||||
#define ADVERTISE_PAUSE_CAP (0x0400U) /* Try for pause */
|
||||
#define ADVERTISE_PAUSE_ASYM (0x0800U) /* Try for asymetric pause */
|
||||
#define ADVERTISE_RESV (0x1000U) /* Unused... */
|
||||
#define ADVERTISE_RFAULT (0x2000U) /* Say we can detect faults */
|
||||
#define ADVERTISE_LPACK (0x4000U) /* Ack link partners response */
|
||||
#define ADVERTISE_NPAGE (0x8000U) /* Next page bit */
|
||||
|
||||
#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
|
||||
ADVERTISE_CSMA)
|
||||
#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
|
||||
ADVERTISE_100HALF | ADVERTISE_100FULL)
|
||||
|
||||
/* Link partner ability register. */
|
||||
#define LPA_SLCT (0x001FU) /* Same as advertise selector */
|
||||
#define LPA_10HALF (0x0020U) /* Can do 10mbps half-duplex */
|
||||
#define LPA_1000XFULL (0x0020U) /* Can do 1000BASE-X full-duplex */
|
||||
#define LPA_10FULL (0x0040U) /* Can do 10mbps full-duplex */
|
||||
#define LPA_1000XHALF (0x0040U) /* Can do 1000BASE-X half-duplex */
|
||||
#define LPA_100HALF (0x0080U) /* Can do 100mbps half-duplex */
|
||||
#define LPA_1000XPAUSE (0x0080U) /* Can do 1000BASE-X pause */
|
||||
#define LPA_100FULL (0x0100U) /* Can do 100mbps full-duplex */
|
||||
#define LPA_1000XPAUSE_ASYM (0x0100U) /* Can do 1000BASE-X pause asym*/
|
||||
#define LPA_100BASE4 (0x0200U) /* Can do 100mbps 4k packets */
|
||||
#define LPA_PAUSE_CAP (0x0400U) /* Can pause */
|
||||
#define LPA_PAUSE_ASYM (0x0800U) /* Can pause asymetrically */
|
||||
#define LPA_RESV (0x1000U) /* Unused... */
|
||||
#define LPA_RFAULT (0x2000U) /* Link partner faulted */
|
||||
#define LPA_LPACK (0x4000U) /* Link partner acked us */
|
||||
#define LPA_NPAGE (0x8000U) /* Next page bit */
|
||||
|
||||
#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
|
||||
#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
|
||||
|
||||
/* Expansion register for auto-negotiation. */
|
||||
#define EXPANSION_NWAY (0X0001U) /* Can do N-way auto-nego */
|
||||
#define EXPANSION_LCWP (0X0002U) /* Got new RX page code word */
|
||||
#define EXPANSION_ENABLENPAGE (0X0004U) /* This enables npage words */
|
||||
#define EXPANSION_NPCAPABLE (0X0008U) /* Link partner supports npage */
|
||||
#define EXPANSION_MFAULTS (0X0010U) /* Multiple faults detected */
|
||||
#define EXPANSION_RESV (0XFFE0U) /* Unused... */
|
||||
|
||||
#define ESTATUS_1000_TFULL (0x2000U) /* Can do 1000BT Full */
|
||||
#define ESTATUS_1000_THALF (0x1000U) /* Can do 1000BT Half */
|
||||
|
||||
/* N-way test register. */
|
||||
#define NWAYTEST_RESV1 (0X00FFU) /* Unused... */
|
||||
#define NWAYTEST_LOOPBACK (0X0100U) /* Enable loopback for N-way */
|
||||
#define NWAYTEST_RESV2 (0XFE00U) /* Unused... */
|
||||
|
||||
/* 1000BASE-T Control register */
|
||||
#define ADVERTISE_1000FULL (0x0200U) /* Advertise 1000BASE-T full duplex */
|
||||
#define ADVERTISE_1000HALF (0x0100U) /* Advertise 1000BASE-T half duplex */
|
||||
|
||||
/* 1000BASE-T Status register */
|
||||
#define LPA_1000LOCALRXOK (0x2000U) /* Link partner local receiver status */
|
||||
#define LPA_1000REMRXOK (0x1000U) /* Link partner remote receiver status */
|
||||
#define LPA_1000FULL (0x0800U) /* Link partner 1000BASE-T full duplex */
|
||||
#define LPA_1000HALF (0x0400U) /* Link partner 1000BASE-T half duplex */
|
||||
|
||||
/* Indicates what features are supported by the interface. */
|
||||
#define SUPPORTED_10baseT_Half (1U << 0)
|
||||
#define SUPPORTED_10baseT_Full (1U << 1)
|
||||
#define SUPPORTED_100baseT_Half (1U << 2)
|
||||
#define SUPPORTED_100baseT_Full (1U << 3)
|
||||
#define SUPPORTED_1000baseT_Half (1U << 4)
|
||||
#define SUPPORTED_1000baseT_Full (1U << 5)
|
||||
#define SUPPORTED_Autoneg (1U << 6)
|
||||
#define SUPPORTED_TP (1U << 7)
|
||||
#define SUPPORTED_AUI (1U << 8)
|
||||
#define SUPPORTED_MII (1U << 9)
|
||||
#define SUPPORTED_FIBRE (1U << 10)
|
||||
#define SUPPORTED_BNC (1U << 11)
|
||||
#define SUPPORTED_10000baseT_Full (1U << 12)
|
||||
#define SUPPORTED_Pause (1U << 13)
|
||||
#define SUPPORTED_Asym_Pause (1U << 14)
|
||||
#define SUPPORTED_2500baseX_Full (1U << 15)
|
||||
#define SUPPORTED_Backplane (1U << 16)
|
||||
#define SUPPORTED_1000baseKX_Full (1U << 17)
|
||||
#define SUPPORTED_10000baseKX4_Full (1U << 18)
|
||||
#define SUPPORTED_10000baseKR_Full (1U << 19)
|
||||
#define SUPPORTED_10000baseR_FEC (1U << 20)
|
||||
|
||||
/* Indicates what features are advertised by the interface. */
|
||||
#define ADVERTISED_10baseT_Half (1U << 0)
|
||||
#define ADVERTISED_10baseT_Full (1U << 1)
|
||||
#define ADVERTISED_100baseT_Half (1U << 2)
|
||||
#define ADVERTISED_100baseT_Full (1U << 3)
|
||||
#define ADVERTISED_1000baseT_Half (1U << 4)
|
||||
#define ADVERTISED_1000baseT_Full (1U << 5)
|
||||
#define ADVERTISED_Autoneg (1U << 6)
|
||||
#define ADVERTISED_TP (1U << 7)
|
||||
#define ADVERTISED_AUI (1U << 8)
|
||||
#define ADVERTISED_MII (1U << 9)
|
||||
#define ADVERTISED_FIBRE (1U << 10)
|
||||
#define ADVERTISED_BNC (1U << 11)
|
||||
#define ADVERTISED_10000baseT_Full (1U << 12)
|
||||
#define ADVERTISED_Pause (1U << 13)
|
||||
#define ADVERTISED_Asym_Pause (1U << 14)
|
||||
#define ADVERTISED_2500baseX_Full (1U << 15)
|
||||
#define ADVERTISED_Backplane (1U << 16)
|
||||
#define ADVERTISED_1000baseKX_Full (1U << 17)
|
||||
#define ADVERTISED_10000baseKX4_Full (1U << 18)
|
||||
#define ADVERTISED_10000baseKR_Full (1U << 19)
|
||||
#define ADVERTISED_10000baseR_FEC (1U << 20)
|
||||
|
||||
/* TI DP83867 PHY Control Register */
|
||||
|
||||
#define PHYCR_TX_FIFO_DEPTH (0xC000U)
|
||||
#define PHYCR_RX_FIFO_DEPTH (0x3000U)
|
||||
#define PHYCR_SGMII_EN (0x0800U)
|
||||
#define PHYCR_FORCE_LINK_GOOD (0x0400U)
|
||||
#define PHYCR_POWER_SAVE_MODE (0x0300U)
|
||||
#define PHYCR_DEEP_POWER_DOWN_EN (0x0080U)
|
||||
#define PHYCR_MDI_CROSSOVER (0x0060U)
|
||||
#define PHYCR_DISABLE_CLK_125 (0x0010U)
|
||||
#define PHYCR_STANDBY_MODE (0x0004U)
|
||||
#define PHYCR_LINE_DRIVER_INV_EN (0x0002U)
|
||||
#define PHYCR_DISABLE_JABBER (0x0001U)
|
||||
|
||||
/* TI DP83867 Control Register */
|
||||
|
||||
#define CTRL_SW_RESET (0x8000U)
|
||||
#define CTRL_SW_RESTART (0x4000U)
|
||||
|
||||
/* TI DP83867 SGMII Control Register 1 */
|
||||
|
||||
#define SGMII_TYPE_6_WIRE (0x4000U)
|
||||
|
||||
/* Different PHY MDIO addresses for our current designs */
|
||||
|
||||
#if defined(TARGET_ALOE)
|
||||
#define PHY_VSC8541_MDIO_ADDR (0U) /* Aloe board PHY */
|
||||
#else
|
||||
#define PHY_VSC8541_MDIO_ADDR (26U) /* SVG MSS board PHY */
|
||||
#endif
|
||||
#define PHY_VSC8662_0_MDIO_ADDR (8U) /* SVG MSS board port 0 */
|
||||
#define PHY_VSC8662_1_MDIO_ADDR (9U) /* SVG MSS board port 1 */
|
||||
#define PHY_VSC8575_MDIO_ADDR (4U) /* G5 SoC Emulation Platform Peripheral Daughter Board PHY */
|
||||
#define PHY_DP83867_MDIO_ADDR (3U) /* G5 SoC Emulation Platform native PHY */
|
||||
#define PHY_NULL_MDIO_ADDR (0U) /* No PHY here actually... */
|
||||
#define SGMII_MDIO_ADDR (16U) /* Internal PHY in G5 SoC Emulation Platform SGMII to GMII core */
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* Public function declarations */
|
||||
/**************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
void MSS_MAC_phy_init(mss_mac_instance_t *this_mac, uint8_t phy_addr);
|
||||
*/
|
||||
#if MSS_MAC_USE_PHY_VSC8541
|
||||
void MSS_MAC_VSC8541_phy_init(/* mss_mac_instance_t */ const void *v_this_mac, uint8_t phy_addr);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8575 || MSS_MAC_USE_PHY_VSC8575_LITE
|
||||
void MSS_MAC_VSC8575_phy_init(/* mss_mac_instance_t */ const void *v_this_mac, uint8_t phy_addr);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8662
|
||||
void MSS_MAC_VSC8662_phy_init(/* mss_mac_instance_t */ const void *v_this_mac, uint8_t phy_addr);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_DP83867
|
||||
void MSS_MAC_DP83867_phy_init(/* mss_mac_instance_t */ const void *v_this_mac, uint8_t phy_addr);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_NULL
|
||||
void MSS_MAC_NULL_phy_init(/* mss_mac_instance_t */ const void *v_this_mac, uint8_t phy_addr);
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
|
||||
*/
|
||||
#if MSS_MAC_USE_PHY_VSC8541
|
||||
void MSS_MAC_VSC8541_phy_set_link_speed(/* mss_mac_instance_t*/ void *v_this_mac, uint32_t speed_duplex_select, mss_mac_speed_mode_t speed_mode);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8575 || MSS_MAC_USE_PHY_VSC8575_LITE
|
||||
void MSS_MAC_VSC8575_phy_set_link_speed(/* mss_mac_instance_t */ void *v_this_mac, uint32_t speed_duplex_select, mss_mac_speed_mode_t speed_mode);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8662
|
||||
void MSS_MAC_VSC8662_phy_set_link_speed(/* mss_mac_instance_t */ void *v_this_mac, uint32_t speed_duplex_select, mss_mac_speed_mode_t speed_mode);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_DP83867
|
||||
void MSS_MAC_DP83867_phy_set_link_speed(/* mss_mac_instance_t */ void *v_this_mac, uint32_t speed_duplex_select, mss_mac_speed_mode_t speed_mode);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_NULL
|
||||
void MSS_MAC_NULL_phy_set_link_speed(/* mss_mac_instance_t */ void *v_this_mac, uint32_t speed_duplex_select, mss_mac_speed_mode_t speed_mode);
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
|
||||
*/
|
||||
#if MSS_MAC_USE_PHY_VSC8541
|
||||
void MSS_MAC_VSC8541_phy_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac);
|
||||
void MSS_MAC_VSC8541_mac_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8575 || MSS_MAC_USE_PHY_VSC8575_LITE
|
||||
void MSS_MAC_VSC8575_phy_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac);
|
||||
void MSS_MAC_VSC8575_mac_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8662
|
||||
void MSS_MAC_VSC8662_phy_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac);
|
||||
void MSS_MAC_VSC8662_mac_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_DP83867
|
||||
void MSS_MAC_DP83867_phy_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac);
|
||||
void MSS_MAC_DP83867_mac_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac);
|
||||
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_NULL
|
||||
void MSS_MAC_NULL_phy_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac);
|
||||
void MSS_MAC_NULL_phy_mac_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac);
|
||||
#endif
|
||||
/***************************************************************************//**
|
||||
|
||||
*/
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8541
|
||||
uint8_t MSS_MAC_VSC8541_phy_get_link_status
|
||||
(
|
||||
/* mss_mac_instance_t */ const void *v_this_mac,
|
||||
mss_mac_speed_t * speed,
|
||||
uint8_t * fullduplex
|
||||
);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8575 || MSS_MAC_USE_PHY_VSC8575_LITE
|
||||
uint8_t MSS_MAC_VSC8575_phy_get_link_status
|
||||
(
|
||||
/* mss_mac_instance_t */ const void *v_this_mac,
|
||||
mss_mac_speed_t * speed,
|
||||
uint8_t * fullduplex
|
||||
);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8662
|
||||
uint8_t MSS_MAC_VSC8662_phy_get_link_status
|
||||
(
|
||||
/* mss_mac_instance_t */ const void *v_this_mac,
|
||||
mss_mac_speed_t * speed,
|
||||
uint8_t * fullduplex
|
||||
);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_DP83867
|
||||
uint8_t MSS_MAC_DP83867_phy_get_link_status
|
||||
(
|
||||
/* mss_mac_instance_t */ const void *v_this_mac,
|
||||
mss_mac_speed_t * speed,
|
||||
uint8_t * fullduplex
|
||||
);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_NULL
|
||||
uint8_t MSS_MAC_NULL_phy_get_link_status
|
||||
(
|
||||
/* mss_mac_instance_t */ const void *v_this_mac,
|
||||
mss_mac_speed_t * speed,
|
||||
uint8_t * fullduplex
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
#if MSS_MAC_USE_PHY_DP83867
|
||||
/***************************************************************************//**
|
||||
|
||||
*/
|
||||
void ti_write_extended_regs(/* mss_mac_instance_t */ const void *v_this_mac, uint16_t reg, uint16_t data);
|
||||
|
||||
#if MSS_MAC_USE_PHY_NULL
|
||||
void NULL_ti_write_extended_regs(/* mss_mac_instance_t */ const void *v_this_mac, uint16_t reg, uint16_t data);
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
|
||||
*/
|
||||
uint16_t ti_read_extended_regs(/* mss_mac_instance_t */ const void *v_this_mac, uint16_t reg);
|
||||
|
||||
#if MSS_MAC_USE_PHY_NULL
|
||||
uint16_t NULL_ti_read_extended_regs(/* mss_mac_instance_t */ const void *v_this_mac, uint16_t reg);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSE_PHY_H */
|
||||
|
||||
|
|
@ -0,0 +1,517 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2020 Microchip Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* TI DP83867ISRGZ PHY interface driver implementation for use with the G5 SoC
|
||||
* Emulation Platform.
|
||||
*
|
||||
* This system uses the SGMII interface.
|
||||
*
|
||||
* The following are the default selections from the hardware strapping:
|
||||
*
|
||||
* RX_D0 - Strap option 4, PHY_ADD0 = 1, PHY_ADD1 = 1
|
||||
* RX_D2 - Strap option 0, PHY_ADD2 = 0, PHY_ADD1 = 0
|
||||
* RX_CTRL - Strap option 0, N/A - the following note applies:
|
||||
* Strap modes 1 and 2 are not applicable for RX_CTRL. The RX_CTRL
|
||||
* strap must be configured for strap mode 3 or strap mode 4. If the
|
||||
* RX_CTRL pin cannot be strapped to mode 3 or mode 4, bit[7] of
|
||||
* Configuration Register 4 (address 0x0031) must be cleared to 0.
|
||||
* GPIO_0 - Strap option 0, RGMII Clock Skew RX[0] = 0. GPIO_0 is connected to
|
||||
* I/O pin AR22 on the VU9P FPGA device.
|
||||
* GPIO_1 - Strap option 0, RGMII Clock Skew RX[1] = 0,
|
||||
* RGMII Clock Skew RX[2] = 0
|
||||
* LED_2 - Strap option 2, RGMII Clock Skew TX[0] = 1,
|
||||
* RGMII Clock Skew TX[1] = 0
|
||||
* LED_1 - Strap option 2, RGMII Clock Skew TX[2] = 1, ANEG_SEL = 0
|
||||
* LED_0 - Strap option 2, SGMII_Enable = 1, Mirror Enable = 0
|
||||
*
|
||||
*/
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
#include "hal/hal.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_registers.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_sw_cfg.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac.h"
|
||||
#include "drivers/mss_ethernet_mac/phy.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_DP83867
|
||||
|
||||
/**************************************************************************/
|
||||
/* Preprocessor Macros */
|
||||
/**************************************************************************/
|
||||
|
||||
#define BMSR_AUTO_NEGOTIATION_COMPLETE (0x0020U)
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_DP83867_phy_init(/* mss_mac_instance_t */ const void *v_this_mac, uint8_t phy_addr)
|
||||
{
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
uint16_t phy_reg;
|
||||
(void)phy_addr;
|
||||
|
||||
/* Start by doing a software reset of the PHY */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_CTRL, CTRL_SW_RESET);
|
||||
|
||||
/* Enable SGMII interface */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_PHYCR);
|
||||
phy_reg |= PHYCR_SGMII_EN;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_PHYCR, phy_reg);
|
||||
|
||||
/* Enable 6 wire SGMII so that the 625MHz clock to the SGMII core is active */
|
||||
#if 0
|
||||
ti_write_extended_regs(this_mac, MII_TI_SGMIICTL1, SGMII_TYPE_6_WIRE);
|
||||
#endif
|
||||
|
||||
if(GMII_SGMII == this_mac->interface_type)
|
||||
{
|
||||
/* Reset SGMII core side of I/F. */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR);
|
||||
phy_reg |= 0x9000U; /* Reset and start autonegotiation */
|
||||
phy_reg &= 0xFBFFU; /* Clear Isolate bit */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR, phy_reg);
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR);
|
||||
phy_reg &= 0xFBFFU; /* Clear Isolate bit */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR, phy_reg);
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR);
|
||||
phy_reg |= 0x1000U; /* Kick off autonegotiation - belt and braces approach...*/
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR, phy_reg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_DP83867_phy_set_link_speed(/* mss_mac_instance_t */ void *v_this_mac, uint32_t speed_duplex_select, mss_mac_speed_mode_t speed_mode)
|
||||
{
|
||||
mss_mac_instance_t *this_mac = (mss_mac_instance_t *)v_this_mac;
|
||||
uint16_t phy_reg;
|
||||
uint32_t inc;
|
||||
uint32_t speed_select;
|
||||
const uint16_t mii_advertise_bits[4] = {ADVERTISE_10FULL, ADVERTISE_10HALF,
|
||||
ADVERTISE_100FULL, ADVERTISE_100HALF};
|
||||
|
||||
this_mac->speed_mode = speed_mode;
|
||||
|
||||
if(MSS_MAC_SPEED_AN == speed_mode) /* Set auto-negotiation advertisement. */
|
||||
{
|
||||
/* Set auto-negotiation advertisement. */
|
||||
|
||||
/* Set 10Mbps and 100Mbps advertisement. */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_ADVERTISE);
|
||||
phy_reg &= (uint16_t)(~(ADVERTISE_10HALF | ADVERTISE_10FULL |
|
||||
ADVERTISE_100HALF | ADVERTISE_100FULL));
|
||||
|
||||
phy_reg |= 0x0C00U; /* Set Asymmetric pause and symmetric pause bits */
|
||||
|
||||
speed_select = speed_duplex_select;
|
||||
for(inc = 0U; inc < 4U; ++inc)
|
||||
{
|
||||
uint32_t advertise;
|
||||
advertise = speed_select & 0x00000001U;
|
||||
if(advertise != 0U)
|
||||
{
|
||||
phy_reg |= mii_advertise_bits[inc];
|
||||
}
|
||||
speed_select = speed_select >> 1;
|
||||
}
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_ADVERTISE, phy_reg);
|
||||
|
||||
/* Set 1000Mbps advertisement. */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000);
|
||||
phy_reg &= (uint16_t)(~(ADVERTISE_1000FULL | ADVERTISE_1000HALF));
|
||||
|
||||
if((speed_duplex_select & MSS_MAC_ANEG_1000M_FD) != 0U)
|
||||
{
|
||||
phy_reg |= ADVERTISE_1000FULL;
|
||||
}
|
||||
|
||||
if((speed_duplex_select & MSS_MAC_ANEG_1000M_HD) != 0U)
|
||||
{
|
||||
phy_reg |= ADVERTISE_1000HALF;
|
||||
}
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, phy_reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t temp_reg = 0x0000U; /* Default with 10M, half duplex */
|
||||
|
||||
if((MSS_MAC_10_FDX == this_mac->speed_mode) || (MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_1000_FDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_FULLDPLX;
|
||||
}
|
||||
|
||||
if((MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_100_HDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_SPEED100;
|
||||
}
|
||||
|
||||
if((MSS_MAC_1000_FDX == this_mac->speed_mode) || (MSS_MAC_1000_HDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_SPEED1000;
|
||||
/* Set Master mode */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000);
|
||||
phy_reg |= 0x1800U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, phy_reg);
|
||||
}
|
||||
|
||||
/* Apply static speed/duplex selection */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMCR, temp_reg);
|
||||
|
||||
/* Full duplex mode or half duplex, single port device */
|
||||
if((MSS_MAC_10_FDX == this_mac->speed_mode) || (MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_1000_FDX == this_mac->speed_mode))
|
||||
{
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, (uint16_t)(ADVERTISE_1000FULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, (uint16_t)(ADVERTISE_1000HALF));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_DP83867_phy_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac)
|
||||
{
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
volatile uint16_t phy_reg;
|
||||
uint16_t autoneg_complete;
|
||||
volatile uint32_t copper_aneg_timeout = 1000000U;
|
||||
volatile uint32_t sgmii_aneg_timeout = 100000U;
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 2);
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 3);
|
||||
|
||||
/* Enable auto-negotiation. */
|
||||
phy_reg = 0x1340U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMCR, phy_reg);
|
||||
|
||||
/* Wait for copper auto-negotiation to complete. */
|
||||
do {
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMSR);
|
||||
autoneg_complete = phy_reg & BMSR_AUTO_NEGOTIATION_COMPLETE;
|
||||
--copper_aneg_timeout;
|
||||
} while((0u == autoneg_complete) && (0U != copper_aneg_timeout) && (0xFFFFU != phy_reg));
|
||||
|
||||
if(GMII_SGMII == this_mac->interface_type)
|
||||
{
|
||||
/* Initiate auto-negotiation on the SGMII link. */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, 0x00U);
|
||||
phy_reg |= 0x1000U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, 0x00U, phy_reg);
|
||||
phy_reg |= 0x0200U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, 0x00U, phy_reg);
|
||||
|
||||
/* Wait for SGMII auto-negotiation to complete. */
|
||||
do {
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMSR);
|
||||
autoneg_complete = phy_reg & BMSR_AUTO_NEGOTIATION_COMPLETE;
|
||||
--sgmii_aneg_timeout;
|
||||
} while((0U == autoneg_complete) && (0U != sgmii_aneg_timeout));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_DP83867_mac_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac)
|
||||
{
|
||||
(void)v_this_mac;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
uint8_t MSS_MAC_DP83867_phy_get_link_status
|
||||
(
|
||||
/* mss_mac_instance_t*/ const void *v_this_mac,
|
||||
mss_mac_speed_t * speed,
|
||||
uint8_t * fullduplex
|
||||
)
|
||||
{
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
uint16_t phy_reg;
|
||||
uint16_t link_up;
|
||||
uint8_t link_status;
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMSR);
|
||||
link_up = phy_reg & BMSR_LSTATUS;
|
||||
|
||||
if(link_up != MSS_MAC_LINK_DOWN)
|
||||
{
|
||||
uint16_t duplex;
|
||||
uint16_t speed_field;
|
||||
|
||||
/* Link is up. */
|
||||
link_status = MSS_MAC_LINK_UP;
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x11U); /* Device Auxillary Control and Status */
|
||||
duplex = phy_reg & 0x2000U;
|
||||
speed_field = phy_reg >> 14;
|
||||
|
||||
if(MSS_MAC_HALF_DUPLEX == duplex)
|
||||
{
|
||||
*fullduplex = MSS_MAC_HALF_DUPLEX;
|
||||
}
|
||||
else
|
||||
{
|
||||
*fullduplex = MSS_MAC_FULL_DUPLEX;
|
||||
}
|
||||
|
||||
switch(speed_field)
|
||||
{
|
||||
case 0U:
|
||||
*speed = MSS_MAC_10MBPS;
|
||||
break;
|
||||
|
||||
case 1U:
|
||||
*speed = MSS_MAC_100MBPS;
|
||||
break;
|
||||
|
||||
case 2U:
|
||||
*speed = MSS_MAC_1000MBPS;
|
||||
break;
|
||||
|
||||
default:
|
||||
link_status = (uint8_t)MSS_MAC_LINK_DOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Link is down. */
|
||||
link_status = (uint8_t)MSS_MAC_LINK_DOWN;
|
||||
}
|
||||
|
||||
return link_status;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* TI DP83867 PHY has 32 standard registers and a collection of additional
|
||||
* registers that are accessed through the use of registers 0x0D and 0x0E.
|
||||
* Register 0x0D (REGCR) holds the control bits which determine what register
|
||||
* 0x0E (ADDAR) does.
|
||||
*
|
||||
* The following extended registers are available:
|
||||
*
|
||||
* 0x0025 - Testmode Channel Control
|
||||
* 0x002D - Fast Link Drop Configuration
|
||||
* 0x0031 - Configuration Register 4
|
||||
* 0x0032 - RGMII Control Register
|
||||
* 0x0033 - RGMII Control Register 2
|
||||
* 0x0037 - SGMII Auto-Negotiation Status
|
||||
* 0x0043 - 100BASE-TX Configuration
|
||||
* 0x0055 - Skew FIFO Status
|
||||
* 0x006E - Strap Configuration Status Register 1
|
||||
* 0x006F - Strap Configuration Status Register 2
|
||||
* 0x0071 - BIST Control and Status Register 1
|
||||
* 0x0072 - BIST Control and Status Register 2
|
||||
* 0x0086 - RGMII Delay Control Register
|
||||
* 0x00D3 - SGMII Control Register 1
|
||||
* 0x00E9 - Sync FIFO Control
|
||||
* 0x00FE - Loopback Configuration Register
|
||||
* 0x0134 - Receive Configuration Register
|
||||
* 0x0135 - Receive Status Register
|
||||
* 0x0136 - Pattern Match Data Register 1
|
||||
* 0x0137 - Pattern Match Data Register 2
|
||||
* 0x0138 - Pattern Match Data Register 3
|
||||
* 0x0139 - SecureOn Pass Register 1
|
||||
* 0x013A - SecureOn Pass Register 2
|
||||
* 0x013B - SecureOn Pass Register 3
|
||||
* 0x013C - 0x015B - Receive Pattern Registers 1 to 32
|
||||
* 0x015C - Receive Pattern Byte Mask Register 1
|
||||
* 0x015D - Receive Pattern Byte Mask Register 2
|
||||
* 0x015E - Receive Pattern Byte Mask Register 3
|
||||
* 0x015F - Receive Pattern Byte Mask Register 4
|
||||
* 0x0161 - Receive Pattern Control
|
||||
* 0x016F - 10M SGMII Configuration
|
||||
* 0x0170 - I/O configuration
|
||||
* 0x0172 - GPIO Mux Control Register
|
||||
* 0x0180 - TDR General Configuration Register 1
|
||||
* 0x01A7 - Advanced Link Cable Diagnostics Control Register
|
||||
* 0x0000 - MMD3 PCS Control Register - indirect addressing only
|
||||
*
|
||||
*/
|
||||
|
||||
uint16_t phy_reg_list[25] =
|
||||
{
|
||||
0x0025U, /* 00 Testmode Channel Control */
|
||||
0x002DU, /* 01 Fast Link Drop Configuration */
|
||||
0x0031U, /* 02 Configuration Register 4 */
|
||||
0x0032U, /* 03 RGMII Control Register */
|
||||
0x0033U, /* 04 RGMII Control Register 2 */
|
||||
0x0037U, /* 05 SGMII Auto-Negotiation Status */
|
||||
0x0043U, /* 06 100BASE-TX Configuration */
|
||||
0x0055U, /* 07 Skew FIFO Status */
|
||||
0x006EU, /* 08 Strap Configuration Status Register 1 */
|
||||
0x006FU, /* 09 Strap Configuration Status Register 2 */
|
||||
0x0071U, /* 10 BIST Control and Status Register 1 */
|
||||
0x0072U, /* 11 BIST Control and Status Register 2 */
|
||||
0x0086U, /* 12 RGMII Delay Control Register */
|
||||
0x00D3U, /* 13 SGMII Control Register 1 */
|
||||
0x00E9U, /* 14 Sync FIFO Control */
|
||||
0x00FEU, /* 15 Loopback Configuration Register */
|
||||
0x0134U, /* 16 Receive Configuration Register */
|
||||
0x0135U, /* 17 Receive Status Register */
|
||||
0x016FU, /* 18 10M SGMII Configuration */
|
||||
0x0170U, /* 19 I/O configuration */
|
||||
0x0172U, /* 20 GPIO Mux Control Register */
|
||||
0x0180U, /* 21 TDR General Configuration Register 1 */
|
||||
0x01A7U, /* 22 Advanced Link Cable Diagnostics Control Register */
|
||||
0x0000U, /* 23 MMD3 PCS Control Register - indirect addressing only */
|
||||
0xFFFFU /* 24 End of list... */
|
||||
};
|
||||
|
||||
uint16_t TI_reg_0[32];
|
||||
uint16_t TI_reg_1[25];
|
||||
uint16_t TI_MSS_SGMII_reg[17];
|
||||
uint32_t TI_MSS_MAC_reg[80];
|
||||
uint32_t TI_MSS_PLIC_REG[80];
|
||||
|
||||
|
||||
void dump_ti_regs(const mss_mac_instance_t * this_mac);
|
||||
void dump_ti_regs(const mss_mac_instance_t * this_mac)
|
||||
{
|
||||
int32_t count;
|
||||
uint16_t old_ctrl;
|
||||
uint16_t old_addr;
|
||||
uint32_t *pbigdata;
|
||||
volatile psr_t lev;
|
||||
|
||||
for(count = 0; count <= 0x1F; count++)
|
||||
{
|
||||
lev = HAL_disable_interrupts();
|
||||
TI_reg_0[count] = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, (uint8_t)count);
|
||||
HAL_restore_interrupts(lev);
|
||||
}
|
||||
|
||||
lev = HAL_disable_interrupts();
|
||||
old_ctrl = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR); /* Fetch current REGCR value */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, 0x001FU); /* Select Address mode */
|
||||
old_addr = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_ADDAR); /* Fetch current indirect address */
|
||||
HAL_restore_interrupts(lev);
|
||||
|
||||
for(count = 0; 0xFFFFU != phy_reg_list[count]; count++)
|
||||
{
|
||||
lev = HAL_disable_interrupts();
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, 0x001FU); /* Select Address mode */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_ADDAR, phy_reg_list[count]); /* Select new indirect Address */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, 0x401FU); /* Select simple data mode */
|
||||
TI_reg_1[count] = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_ADDAR); /* Finally, read the data */
|
||||
HAL_restore_interrupts(lev);
|
||||
}
|
||||
|
||||
lev = HAL_disable_interrupts();
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, 0x001FU); /* Select Address mode */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_ADDAR, old_addr); /* Restore old address */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, old_ctrl); /* Restore old control mode */
|
||||
HAL_restore_interrupts(lev);
|
||||
|
||||
for(count = 0; count <= 0x10; count++)
|
||||
{
|
||||
TI_MSS_SGMII_reg[count] = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, (uint8_t)count);
|
||||
}
|
||||
|
||||
pbigdata = (uint32_t *)0x20110000UL;
|
||||
for(count = 0; count < 19; count++)
|
||||
{
|
||||
TI_MSS_MAC_reg[count] = *pbigdata;
|
||||
pbigdata++;
|
||||
}
|
||||
pbigdata =(uint32_t *)0x0C000000UL;
|
||||
for(count = 0; count < 8; count++)
|
||||
{
|
||||
TI_MSS_PLIC_REG[count] = *pbigdata;
|
||||
pbigdata++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
uint16_t ti_read_extended_regs(/* mss_mac_instance_t*/ const void *v_this_mac, uint16_t reg)
|
||||
{
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
uint16_t old_ctrl;
|
||||
uint16_t old_addr;
|
||||
uint16_t ret_val = 0U;
|
||||
volatile psr_t lev;
|
||||
|
||||
lev = HAL_disable_interrupts();
|
||||
old_ctrl = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR); /* Fetch current REGCR value */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, 0x001FU); /* Select Address mode */
|
||||
old_addr = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_ADDAR); /* Fetch current indirect address */
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, 0x001FU); /* Select Address mode */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_ADDAR, reg); /* Select new indirect Address */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, 0x401FU); /* Select simple data mode */
|
||||
ret_val = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_ADDAR); /* Finally, read the data */
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, 0x001FU); /* Select Address mode */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_ADDAR, old_addr); /* Restore old address */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, old_ctrl); /* Restore old control mode */
|
||||
HAL_restore_interrupts(lev);
|
||||
|
||||
return(ret_val);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void ti_write_extended_regs(/* mss_mac_instance_t*/ const void *v_this_mac, uint16_t reg, uint16_t data)
|
||||
{
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
uint16_t old_ctrl;
|
||||
uint16_t old_addr;
|
||||
volatile psr_t lev;
|
||||
|
||||
lev = HAL_disable_interrupts();
|
||||
old_ctrl = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR); /* Fetch current REGCR value */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, 0x001FU); /* Select Address mode */
|
||||
old_addr = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_ADDAR); /* Fetch current indirect address */
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, 0x001FU); /* Select Address mode */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_ADDAR, reg); /* Select new indirect Address */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, 0x401FU); /* Select simple data mode */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_ADDAR, data); /* Now write the data */
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, 0x001FU); /* Select Address mode */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_ADDAR, old_addr); /* Restore old address */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_TI_REGCR, old_ctrl); /* Restore old control mode */
|
||||
HAL_restore_interrupts(lev);
|
||||
}
|
||||
#endif /* #if defined(TARGET_ALOE) */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************** END OF FILE ******************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,520 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2020 Microchip Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Microsemi VSC8541 PHY interface driver implementation to support the FU540
|
||||
* Aloe board.
|
||||
*
|
||||
*/
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
#include "hal/hal.h"
|
||||
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_registers.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_sw_cfg.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac.h"
|
||||
#include "drivers/mss_ethernet_mac/phy.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8541
|
||||
|
||||
/**************************************************************************/
|
||||
/* Preprocessor Macros */
|
||||
/**************************************************************************/
|
||||
|
||||
#define BMSR_AUTO_NEGOTIATION_COMPLETE (0x0020U)
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t INPUT_VAL; /* 0x0000 */
|
||||
__IO uint32_t INPUT_EN; /* 0x0004 */
|
||||
__IO uint32_t OUTPUT_VAL; /* 0x0008 */
|
||||
__IO uint32_t OUTPUT_EN; /* 0x000C */
|
||||
__IO uint32_t PUE; /* 0x0010 */
|
||||
__IO uint32_t DS; /* 0x0014 */
|
||||
__IO uint32_t RISE_IE; /* 0x0018 */
|
||||
__IO uint32_t RISE_IP; /* 0x001C */
|
||||
__IO uint32_t FALL_IE; /* 0x0020 */
|
||||
__IO uint32_t FALL_IP; /* 0x0024 */
|
||||
__IO uint32_t HIGH_IE; /* 0x0028 */
|
||||
__IO uint32_t HIGH_IP; /* 0x002C */
|
||||
__IO uint32_t LOW_IE; /* 0x0030 */
|
||||
__IO uint32_t LOW_IP; /* 0x0034 */
|
||||
__IO uint32_t reserved0; /* 0x0038 */
|
||||
__IO uint32_t reserved1; /* 0x003C */
|
||||
__IO uint32_t OUT_XOR; /* 0x0040 */
|
||||
} AloeGPIO_TypeDef;
|
||||
|
||||
|
||||
void MSS_MAC_VSC8541_phy_init(/* mss_mac_instance_t */ const void *v_this_mac, uint8_t phy_addr)
|
||||
{
|
||||
#if defined(TARGET_ALOE)
|
||||
volatile uint32_t loop;
|
||||
AloeGPIO_TypeDef *g_aloe_gpio = (AloeGPIO_TypeDef *)0x10060000UL;
|
||||
|
||||
(void)v_this_mac;
|
||||
(void)phy_addr;
|
||||
/*
|
||||
* Init includes toggling the reset line which is connected to GPIO 0 pin 12.
|
||||
* This is the only pin I can see on the 16 GPIO which is currently set as an.
|
||||
* output. We will hard code the setup here to avoid having to have a GPIO
|
||||
* driver as well...
|
||||
*
|
||||
* The Aloe board is strapped for unmanaged mode and needs two pulses of the
|
||||
* reset line to configure the device properly.
|
||||
*
|
||||
* The RX_CLK, TX_CLK and RXD7 pins are strapped high and the remainder low.
|
||||
* This selects GMII mode with auto 10/100/1000 and 125MHz clkout.
|
||||
*/
|
||||
g_aloe_gpio->OUTPUT_EN |= 0x00001000UL; /* Configure pin 12 as an output */
|
||||
g_aloe_gpio->OUTPUT_VAL &= 0x0000EFFFUL; /* Clear pin 12 to reset PHY */
|
||||
for(loop = 0U; loop != 1000U; loop++) /* Short delay, I'm not sure how much is needed... */
|
||||
{
|
||||
;
|
||||
}
|
||||
g_aloe_gpio->OUTPUT_VAL |= 0x00001000UL; /* Take PHY^ out of reset */
|
||||
for(loop = 0U; loop != 1000U; loop++) /* Short delay, I'm not sure how much is needed... */
|
||||
{
|
||||
;
|
||||
}
|
||||
g_aloe_gpio->OUTPUT_VAL &= 0x0000EFFFUL; /* Second reset pulse */
|
||||
for(loop = 0U; loop != 1000U; loop++) /* Short delay, I'm not sure how much is needed... */
|
||||
{
|
||||
;
|
||||
}
|
||||
g_aloe_gpio->OUTPUT_VAL |= 0x00001000UL; /* Out of reset once more */
|
||||
|
||||
/* Need at least 15mS delay before accessing PHY after reset... */
|
||||
for(loop = 0U; loop != 10000000U; loop++) /* Long delay, I'm not sure how much is needed... */
|
||||
{
|
||||
;
|
||||
}
|
||||
#else
|
||||
volatile uint16_t temp_reg;
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
mss_mac_instance_t *phy_mac;
|
||||
|
||||
/* Assume this is done by app for the moment */
|
||||
#if 0
|
||||
/* Do hardware reset if possible/necessary */
|
||||
|
||||
/* Phy is actually attached to another MAC... */
|
||||
if((struct mss_mac_instance *)0UL != this_mac->phy_controller)
|
||||
{
|
||||
phy_mac = (mss_mac_instance_t *)this_mac->phy_controller;
|
||||
}
|
||||
else
|
||||
{
|
||||
phy_mac = (mss_mac_instance_t *)this_mac;
|
||||
}
|
||||
|
||||
if(0 == phy_mac->phy_hard_reset_done)
|
||||
{
|
||||
/* Active low reset pulse */
|
||||
MSS_MAC_phy_reset(phy_mac, MSS_MAC_SOFT_RESET, false);
|
||||
MSS_MAC_phy_reset(phy_mac, MSS_MAC_SOFT_RESET, true);
|
||||
|
||||
#if defined(TARGET_G5_SOC)
|
||||
/*
|
||||
* Multiple MACs may be involved and we need to ensure all relevant MACs
|
||||
* have the phy_hard_reset_done flag set
|
||||
*/
|
||||
|
||||
if(phy_mac != this_mac) /* Simple case, set flag for all 4 MACs */
|
||||
{
|
||||
g_mac0.phy_hard_reset_done = true;
|
||||
g_emac0.phy_hard_reset_done = true;
|
||||
g_mac1.phy_hard_reset_done = true;
|
||||
g_emac1.phy_hard_reset_done = true;
|
||||
}
|
||||
else if((&g_mac0 == phy_mac) || (&g_emac0 == phy_mac))
|
||||
{
|
||||
g_mac0.phy_hard_reset_done = true;
|
||||
g_emac0.phy_hard_reset_done = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_mac1.phy_hard_reset_done = true;
|
||||
g_emac1.phy_hard_reset_done = true;
|
||||
}
|
||||
#else
|
||||
phy_mac->phy_hard_reset_done = true;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Select standard registers page */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 31, 0x0000U);
|
||||
|
||||
/* Select GMII mode */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 23, (uint16_t)(0x0000));
|
||||
|
||||
/* Software Reset */
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, phy_addr, 0);
|
||||
temp_reg |= 0x8000U;
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 0, temp_reg);
|
||||
|
||||
/* Wait for soft reset to complete */
|
||||
do
|
||||
{
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, phy_addr, 0);
|
||||
} while(0 != (temp_reg & 0x8000U));
|
||||
|
||||
/* Full duplex, autonegotiation and 1000Mbps as starting point */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, MII_BMCR, (uint16_t)(BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000));
|
||||
|
||||
/* Full duplex modes */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, MII_ADVERTISE, (uint16_t)(ADVERTISE_FULL));
|
||||
|
||||
/* Full duplex mode */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, MII_CTRL1000, (uint16_t)(ADVERTISE_1000FULL));
|
||||
|
||||
|
||||
/* Select page 2 */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 31, 0x0002U);
|
||||
|
||||
/* Adjust MAC interface slew rate - default is 111 but recommended for 3.3V i/o is 100 */
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, phy_addr, 27);
|
||||
temp_reg &= 0xFF1FU;
|
||||
temp_reg |= 0x0080U;
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 27, temp_reg);
|
||||
|
||||
/* Select page 0 */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 31, 0x0000U);
|
||||
|
||||
#if 0
|
||||
/* Auto MDI/MDI-X, Do not ignore advertised ability, disable CLKOUT */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 18, (uint16_t)(0x0084U));
|
||||
|
||||
/* Enable SGMII MAC link autonegotiation and Force copper media only */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 23, (uint16_t)(0x2880U));
|
||||
|
||||
/* SGMII no input preamble, 2 byte output preamble, 9/12K jumbo frames (12K for 60ppm clock) */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 23, (uint16_t)(0xC050U));
|
||||
|
||||
/* Select selection of LED activity modes for 4 LEDs */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 29, (uint16_t)(0x0123U));
|
||||
|
||||
/* Clear this for consistency as many bits are CMODE selections */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 30, (uint16_t)(0x0000U));
|
||||
|
||||
/* Select extended registers page */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 31, 0x0001U);
|
||||
|
||||
/* Clear SIGDET polarity to active high */
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, phy_addr, 19);
|
||||
temp_reg &= 0xFFFE;
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 19, temp_reg);
|
||||
|
||||
/* Ensure all CMODE bits are clear */
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, phy_addr, 20);
|
||||
temp_reg &= 0xFE6F;
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 20, temp_reg);
|
||||
|
||||
/* Select general purpose registers page */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 31, 0x0010U);
|
||||
|
||||
/* Disable SIGDET operation */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 13, (uint16_t)(0x000FU));
|
||||
|
||||
/* Select standard registers page */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 31, 0x0000U);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_VSC8541_phy_set_link_speed(/* mss_mac_instance_t */ void *v_this_mac, uint32_t speed_duplex_select, mss_mac_speed_mode_t speed_mode)
|
||||
{
|
||||
mss_mac_instance_t *this_mac = (mss_mac_instance_t *)v_this_mac;
|
||||
uint16_t phy_reg;
|
||||
uint32_t inc;
|
||||
uint32_t speed_select;
|
||||
const uint16_t mii_advertise_bits[4] = {ADVERTISE_10FULL, ADVERTISE_10HALF,
|
||||
ADVERTISE_100FULL, ADVERTISE_100HALF};
|
||||
|
||||
this_mac->speed_mode = speed_mode;
|
||||
|
||||
if(MSS_MAC_SPEED_AN == speed_mode) /* Set auto-negotiation advertisement. */
|
||||
{
|
||||
/* Set 10Mbps and 100Mbps advertisement. */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_ADVERTISE);
|
||||
phy_reg &= (uint16_t)(~(ADVERTISE_10HALF | ADVERTISE_10FULL |
|
||||
ADVERTISE_100HALF | ADVERTISE_100FULL));
|
||||
|
||||
speed_select = speed_duplex_select;
|
||||
for(inc = 0U; inc < 4U; ++inc)
|
||||
{
|
||||
uint32_t advertise;
|
||||
advertise = speed_select & 0x00000001U;
|
||||
if(advertise != 0U)
|
||||
{
|
||||
phy_reg |= mii_advertise_bits[inc];
|
||||
}
|
||||
speed_select = speed_select >> 1U;
|
||||
}
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_ADVERTISE, phy_reg);
|
||||
|
||||
/* Set 1000Mbps advertisement. */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000);
|
||||
phy_reg &= (uint16_t)(~(ADVERTISE_1000FULL | ADVERTISE_1000HALF));
|
||||
|
||||
if((speed_duplex_select & MSS_MAC_ANEG_1000M_FD) != 0U)
|
||||
{
|
||||
phy_reg |= ADVERTISE_1000FULL;
|
||||
}
|
||||
|
||||
if((speed_duplex_select & MSS_MAC_ANEG_1000M_HD) != 0U)
|
||||
{
|
||||
phy_reg |= ADVERTISE_1000HALF;
|
||||
}
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, phy_reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t temp_reg = 0x0000U; /* Default with 10M, half duplex */
|
||||
|
||||
if((MSS_MAC_10_FDX == this_mac->speed_mode) || (MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_1000_FDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_FULLDPLX;
|
||||
}
|
||||
|
||||
if((MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_100_HDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_SPEED100;
|
||||
}
|
||||
|
||||
if((MSS_MAC_1000_FDX == this_mac->speed_mode) || (MSS_MAC_1000_HDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_SPEED1000;
|
||||
/* Set Master mode */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000);
|
||||
phy_reg |= 0x1800U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, phy_reg);
|
||||
}
|
||||
|
||||
/* Apply static speed/duplex selection */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMCR, temp_reg);
|
||||
|
||||
/* Full duplex mode or half duplex, single port device */
|
||||
if((MSS_MAC_10_FDX == this_mac->speed_mode) || (MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_1000_FDX == this_mac->speed_mode))
|
||||
{
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, (uint16_t)(ADVERTISE_1000FULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, (uint16_t)(ADVERTISE_1000HALF));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_VSC8541_phy_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac)
|
||||
{
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
volatile uint16_t phy_reg;
|
||||
uint16_t autoneg_complete;
|
||||
volatile uint32_t copper_aneg_timeout = 10000U;
|
||||
|
||||
if(MSS_MAC_SPEED_AN == this_mac->speed_mode) /* Only do if allowed */
|
||||
{
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 2U);
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 3U);
|
||||
|
||||
/* Enable auto-negotiation. */
|
||||
phy_reg = 0x1340U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMCR, phy_reg);
|
||||
|
||||
/* Wait for copper auto-negotiation to complete. */
|
||||
do {
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMSR);
|
||||
autoneg_complete = phy_reg & BMSR_AUTO_NEGOTIATION_COMPLETE;
|
||||
--copper_aneg_timeout;
|
||||
} while(((0U == autoneg_complete) && (copper_aneg_timeout != 0u)) || (0xFFFF == phy_reg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_VSC8541_mac_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac)
|
||||
{
|
||||
(void)v_this_mac;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
uint8_t MSS_MAC_VSC8541_phy_get_link_status
|
||||
(
|
||||
/* mss_mac_instance_t*/ const void *v_this_mac,
|
||||
mss_mac_speed_t * speed,
|
||||
uint8_t * fullduplex
|
||||
)
|
||||
{
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
uint16_t phy_reg;
|
||||
uint16_t link_up;
|
||||
uint8_t link_status;
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMSR);
|
||||
link_up = phy_reg & BMSR_LSTATUS;
|
||||
if(link_up != MSS_MAC_LINK_DOWN)
|
||||
{
|
||||
uint16_t duplex;
|
||||
uint16_t speed_field;
|
||||
|
||||
/* Link is up. */
|
||||
link_status = MSS_MAC_LINK_UP;
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1CU); /* Device Auxillary Control and Status */
|
||||
duplex = phy_reg & 0x0020U;
|
||||
speed_field = phy_reg & 0x0018U;
|
||||
|
||||
if(MSS_MAC_HALF_DUPLEX == duplex)
|
||||
{
|
||||
*fullduplex = MSS_MAC_HALF_DUPLEX;
|
||||
}
|
||||
else
|
||||
{
|
||||
*fullduplex = MSS_MAC_FULL_DUPLEX;
|
||||
}
|
||||
|
||||
switch(speed_field >> 3)
|
||||
{
|
||||
case 0U:
|
||||
*speed = MSS_MAC_10MBPS;
|
||||
break;
|
||||
|
||||
case 1U:
|
||||
*speed = MSS_MAC_100MBPS;
|
||||
break;
|
||||
|
||||
case 2U:
|
||||
*speed = MSS_MAC_1000MBPS;
|
||||
break;
|
||||
|
||||
default:
|
||||
link_status = (uint8_t)MSS_MAC_LINK_DOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Link is down. */
|
||||
link_status = (uint8_t)MSS_MAC_LINK_DOWN;
|
||||
}
|
||||
|
||||
return link_status;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
uint16_t VSC8541_reg_0[32];
|
||||
uint16_t VSC8541_reg_1[16];
|
||||
uint16_t VSC8541_reg_2[16];
|
||||
uint16_t VSC8541_reg_16[32];
|
||||
|
||||
void dump_vsc8541_regs(const mss_mac_instance_t * this_mac);
|
||||
void dump_vsc8541_regs(const mss_mac_instance_t * this_mac)
|
||||
{
|
||||
volatile int32_t count;
|
||||
volatile uint16_t page;
|
||||
volatile uint16_t old_page;
|
||||
volatile uint16_t *pdata;
|
||||
volatile psr_t lev;
|
||||
|
||||
for(page = 0U; page <= 0x10U; page++)
|
||||
{
|
||||
if(0U == page)
|
||||
{
|
||||
pdata = VSC8541_reg_0;
|
||||
}
|
||||
else if(1U == page)
|
||||
{
|
||||
pdata = VSC8541_reg_1;
|
||||
}
|
||||
else if(2U == page)
|
||||
{
|
||||
pdata = VSC8541_reg_2;
|
||||
}
|
||||
else if(16U == page)
|
||||
{
|
||||
pdata = VSC8541_reg_16;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdata = VSC8541_reg_0;
|
||||
}
|
||||
|
||||
if((0U == page) || (0x10U == page))
|
||||
{
|
||||
for(count = 0; count <= 0x1F; count++)
|
||||
{
|
||||
lev = HAL_disable_interrupts();
|
||||
old_page = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, page);
|
||||
|
||||
pdata[count] = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, (uint8_t)count);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, old_page);
|
||||
MSS_MAC_read_phy_reg(this_mac, (uint8_t)10, (uint8_t)count);
|
||||
HAL_restore_interrupts(lev);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(count = 0x10; count <= 0x1F; count++)
|
||||
{
|
||||
lev = HAL_disable_interrupts();
|
||||
old_page = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, page);
|
||||
|
||||
pdata[count - 0X10] = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, (uint8_t)count);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, old_page);
|
||||
HAL_restore_interrupts(lev);
|
||||
}
|
||||
}
|
||||
|
||||
if(2U == page)
|
||||
{
|
||||
page = 0x0FU;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #if defined(TARGET_ALOE) */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************** END OF FILE ******************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,881 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2020 Microchip Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Microsemi VSC8575 PHY interface driver implementation to support the
|
||||
* peripheral daughter board for the G5 SoC Emulation Platform.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
#include "hal/hal.h"
|
||||
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_registers.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_sw_cfg.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac.h"
|
||||
#include "drivers/mss_ethernet_mac/phy.h"
|
||||
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_types.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#if MSS_MAC_USE_PHY_VSC8575
|
||||
#include "vtss_api.h" /* For BOOL and friends */
|
||||
#include "vtss_phy_api.h" /* For PHY API Pre and Post Resets */
|
||||
#include "vtss_init_api.h"
|
||||
|
||||
extern int32_t viper_fmc_board_init(vtss_init_conf_t *config);
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8575_LITE
|
||||
#include "vtss_phy_common.h"
|
||||
#include "vtss_viper_phy_prototypes.h"
|
||||
|
||||
extern int32_t viper_fmc_board_init(struct phy_control_t *control);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
/* Preprocessor Macros */
|
||||
/**************************************************************************/
|
||||
|
||||
#define BMSR_AUTO_NEGOTIATION_COMPLETE (0x0020U)
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
uint16_t VSC8575_reg_0[32];
|
||||
uint16_t VSC8575_reg_1[16];
|
||||
uint16_t VSC8575_reg_2[16];
|
||||
uint16_t VSC8575_reg_3[20]; /* Additional 4 to hold MAC Serdes RX and TX stats */
|
||||
uint16_t VSC8575_reg_4[16];
|
||||
uint16_t VSC8575_reg_16[32];
|
||||
uint16_t VSC8575_MSS_SGMII_reg16[17];
|
||||
uint32_t VSC8575_MSS_MAC_reg[80];
|
||||
uint32_t VSC8575_MSS_PLIC_REG[80];
|
||||
|
||||
void dump_vsc8575_regs(const mss_mac_instance_t * this_mac);
|
||||
void dump_vsc8575_regs(const mss_mac_instance_t * this_mac)
|
||||
{
|
||||
int32_t count;
|
||||
uint16_t page;
|
||||
uint16_t old_page;
|
||||
uint16_t *pdata;
|
||||
volatile psr_t lev;
|
||||
|
||||
for(page = 0U; page <= 0x10U; page++)
|
||||
{
|
||||
if(0U == page)
|
||||
{
|
||||
pdata = VSC8575_reg_0;
|
||||
}
|
||||
else if(1U == page)
|
||||
{
|
||||
pdata = VSC8575_reg_1;
|
||||
}
|
||||
else if(2U == page)
|
||||
{
|
||||
pdata = VSC8575_reg_2;
|
||||
}
|
||||
else if(3U == page)
|
||||
{
|
||||
pdata = VSC8575_reg_3;
|
||||
}
|
||||
else if(4U == page)
|
||||
{
|
||||
pdata = VSC8575_reg_4;
|
||||
}
|
||||
else if(16U == page)
|
||||
{
|
||||
pdata = VSC8575_reg_16;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdata = VSC8575_reg_0;
|
||||
}
|
||||
|
||||
if((0U == page) || (0x10U == page))
|
||||
{
|
||||
for(count = 0; count <= 0x1F; count++)
|
||||
{
|
||||
lev = HAL_disable_interrupts();
|
||||
old_page = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, page);
|
||||
|
||||
pdata[count] = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, (uint8_t)count);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, old_page);
|
||||
HAL_restore_interrupts(lev);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(count = 0x10; count <= 0x1F; count++)
|
||||
{
|
||||
lev = HAL_disable_interrupts();
|
||||
old_page = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, page);
|
||||
|
||||
pdata[count - 0X10] = MSS_MAC_read_phy_reg(this_mac,(uint8_t) this_mac->phy_addr, (uint8_t)count);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, old_page);
|
||||
HAL_restore_interrupts(lev);
|
||||
}
|
||||
|
||||
if(3U == page) /* Circle back and get MAC Serdes stats... */
|
||||
{
|
||||
lev = HAL_disable_interrupts();
|
||||
old_page = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, page);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1DU, 0x4000U); /* Select MAC stats */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x16U, 0x4000U); /* Select MAC stats */
|
||||
|
||||
pdata[0x10] = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1CU); /* Fetch MAC stats */
|
||||
pdata[0x11] = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1DU);
|
||||
pdata[0x12] = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x15U); /* Fetch MAC stats */
|
||||
pdata[0x13] = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x16U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x16U, 0x0000U); /* Select Media stats */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1DU, 0x0000U); /* Select Media stats */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, old_page);
|
||||
HAL_restore_interrupts(lev);
|
||||
}
|
||||
}
|
||||
|
||||
if(4U == page)
|
||||
{
|
||||
page = 0x0FU;
|
||||
}
|
||||
}
|
||||
|
||||
for(count = 0; count <= 0x10; count++)
|
||||
{
|
||||
VSC8575_MSS_SGMII_reg16[count] = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, (uint8_t)count);
|
||||
}
|
||||
|
||||
#if 0 /* Only enable as necessary as reading some regs can interfere with ISR operation */
|
||||
{
|
||||
uint32_t *pbigdata;
|
||||
|
||||
pbigdata = (uint32_t *)0x20110000UL;
|
||||
for(count = 0; count < 19; count++, pbigdata++)
|
||||
{
|
||||
VSC8575_MSS_MAC_reg[count] = *pbigdata;
|
||||
}
|
||||
|
||||
pbigdata =(uint32_t *)0x0C000000UL;
|
||||
for(count = 0; count < 8; count++, pbigdata++)
|
||||
{
|
||||
VSC8575_MSS_PLIC_REG[count] = *pbigdata;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* Note: The following assumes there is only one VSC8757 PHY in the system.
|
||||
* We will need to revisit it at some stage to provide for multiple
|
||||
* devices connected to separate GEMs or for the case of multiple
|
||||
* GEMs connected to the same PHY but to different ports.
|
||||
*
|
||||
* For now we need to at least record somewhere which GEM this PHY
|
||||
* is associated with so that the MDIO functions can work correctly as
|
||||
* it is currently assumed GEM0 is the one connected to the VSC8575.
|
||||
*
|
||||
* May need to consider adding entry to vtss_inst_t to hold the mac
|
||||
* reference so MDIO can figure out who to talk to. This will also mean
|
||||
* that the some or all of following globals will need to be changed to
|
||||
* allow for multiple connections...
|
||||
*
|
||||
*/
|
||||
|
||||
mss_mac_instance_t *g_my_mac = (mss_mac_instance_t *)0;
|
||||
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8575
|
||||
void MSS_MAC_VSC8575_phy_init(/* mss_mac_instance_t*/ const void *v_this_mac, uint8_t phy_addr)
|
||||
{
|
||||
static vtss_inst_t g_vtss_inst_p;
|
||||
static vtss_inst_create_t g_vtss_create_inst;
|
||||
static vtss_init_conf_t g_vtss_init_conf;
|
||||
static vtss_phy_conf_t g_phy;
|
||||
static vtss_phy_conf_1g_t g_phy_conf_1g;
|
||||
static vtss_phy_reset_conf_t g_phy_reset_conf;
|
||||
|
||||
static vtss_phy_reset_conf_t vts_phy_init_params = {VTSS_PORT_INTERFACE_SGMII, VTSS_PHY_MEDIA_IF_CU, {1,2},
|
||||
{TRUE},VTSS_PHY_FORCE_RESET, VTSS_PHY_PKT_MODE_IEEE_1_5_KB, TRUE};
|
||||
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
volatile vtss_rc vrc;
|
||||
volatile int32_t vrc_i32;
|
||||
|
||||
(void)phy_addr;
|
||||
g_my_mac = this_mac; /* For now, simply record which MAC we are associated with
|
||||
* assuming there is only one...
|
||||
*/
|
||||
(void)memset (&g_phy, 0, sizeof(vtss_phy_conf_t));
|
||||
|
||||
g_vtss_create_inst.target = VTSS_TARGET_CU_PHY;
|
||||
|
||||
vrc = vtss_inst_create(&g_vtss_create_inst, &g_vtss_inst_p);
|
||||
|
||||
vrc = vtss_init_conf_get(g_vtss_inst_p, &g_vtss_init_conf);
|
||||
vrc_i32 = viper_fmc_board_init(&g_vtss_init_conf);
|
||||
|
||||
g_vtss_init_conf.warm_start_enable = 0;
|
||||
g_vtss_init_conf.restart_info_src = VTSS_RESTART_INFO_SRC_CU_PHY;
|
||||
g_vtss_init_conf.restart_info_port = 0;
|
||||
|
||||
vrc = vtss_init_conf_set(g_vtss_inst_p, &g_vtss_init_conf);
|
||||
|
||||
(void)memset(&g_phy_reset_conf, 0, sizeof(g_phy_reset_conf));
|
||||
|
||||
g_phy_reset_conf.mac_if = VTSS_PORT_INTERFACE_SGMII;
|
||||
g_phy_reset_conf.media_if = VTSS_PHY_MEDIA_IF_CU;
|
||||
g_phy_reset_conf.rgmii.rx_clk_skew_ps = 0;
|
||||
g_phy_reset_conf.rgmii.tx_clk_skew_ps = 0;
|
||||
g_phy_reset_conf.tbi.aneg_enable = 1;
|
||||
|
||||
vrc = vtss_phy_pre_reset(g_vtss_inst_p, 0);
|
||||
/* HH: unsure why vts_phy_init_params being passed instead of g_phy_reset_conf to vtss_phy_reset(...) ??? */
|
||||
vrc = vtss_phy_reset(g_vtss_inst_p, 0, &vts_phy_init_params);
|
||||
/* HH: moved SerDes calibration to after the MAC PCS settings configured */
|
||||
|
||||
/* Configure PHY 1G master/slave preference (for SyncE timing) */
|
||||
(void)memset(&g_phy_conf_1g, 0, sizeof(g_phy_conf_1g));
|
||||
/* HH: conf_get to pre-populate all entries with valid defaults, prior to application settings */
|
||||
vtss_phy_conf_get(g_vtss_inst_p, 0 /* port_no */, &g_phy);
|
||||
|
||||
g_phy_conf_1g.master.cfg = TRUE; /* 1=Enabled */
|
||||
g_phy_conf_1g.master.val = TRUE; /* 1=Master */
|
||||
|
||||
/* HH move conf get/set until after port conf setting configured below */
|
||||
|
||||
g_phy.mode = VTSS_PHY_MODE_ANEG;
|
||||
|
||||
/* Example for PHY speed support for auto-neg */
|
||||
g_phy.aneg.speed_10m_hdx = 1;
|
||||
g_phy.aneg.speed_10m_fdx = 1;
|
||||
g_phy.aneg.speed_100m_hdx = 1;
|
||||
g_phy.aneg.speed_100m_fdx = 1;
|
||||
g_phy.aneg.speed_1g_hdx = 0;
|
||||
g_phy.aneg.speed_1g_fdx = 1;
|
||||
|
||||
g_phy.sigdet = VTSS_PHY_SIGDET_POLARITY_ACT_HIGH;
|
||||
|
||||
/* Example for PHY flow control settings */
|
||||
g_phy.aneg.symmetric_pause = 1;
|
||||
g_phy.aneg.tx_remote_fault = 1;
|
||||
|
||||
g_phy.mdi = VTSS_PHY_MDIX_AUTO; /* always enable auto detection of crossed/non-crossed cables */
|
||||
g_phy.flf = VTSS_PHY_FAST_LINK_FAIL_DISABLE;
|
||||
|
||||
/* Setup the MAC Interface PCS Parameters */
|
||||
g_phy.mac_if_pcs.disable = 0;
|
||||
g_phy.mac_if_pcs.restart = 0;
|
||||
g_phy.mac_if_pcs.pd_enable = 0;
|
||||
g_phy.mac_if_pcs.aneg_restart = 0;
|
||||
g_phy.mac_if_pcs.force_adv_ability = 0;
|
||||
g_phy.mac_if_pcs.sgmii_in_pre = VTSS_PHY_MAC_SERD_PCS_SGMII_IN_PRE_NONE;
|
||||
g_phy.mac_if_pcs.sgmii_out_pre = 0;
|
||||
g_phy.mac_if_pcs.serdes_aneg_ena = 1;
|
||||
g_phy.mac_if_pcs.serdes_pol_inv_in = 0;
|
||||
g_phy.mac_if_pcs.serdes_pol_inv_out = 0;
|
||||
g_phy.mac_if_pcs.fast_link_stat_ena = 0;
|
||||
g_phy.mac_if_pcs.inhibit_odd_start = 0; /* Does nothing as this bit id default on... */
|
||||
|
||||
/* Setup the MEDIA Interface PCS Parameters */
|
||||
g_phy.media_if_pcs.remote_fault = VTSS_PHY_MEDIA_SERD_PCS_REM_FAULT_NO_ERROR;
|
||||
g_phy.media_if_pcs.aneg_pd_detect = 0;
|
||||
g_phy.media_if_pcs.force_adv_ability = 0;
|
||||
g_phy.media_if_pcs.serdes_pol_inv_in = 0;
|
||||
g_phy.media_if_pcs.serdes_pol_inv_out = 0;
|
||||
g_phy.media_if_pcs.inhibit_odd_start = 1;
|
||||
g_phy.media_if_pcs.force_hls = 0;
|
||||
g_phy.media_if_pcs.force_fefi = 0;
|
||||
g_phy.media_if_pcs.force_fefi_value = 0;
|
||||
|
||||
#if 0
|
||||
{
|
||||
vtss_phy_clock_conf_t clock_conf;
|
||||
clock_conf.freq = VTSS_PHY_FREQ_125M;
|
||||
clock_conf.squelch = VTSS_PHY_CLK_SQUELCH_MAX;
|
||||
clock_conf.src = 0;
|
||||
vtss_phy_clock_conf_set(g_vtss_inst_p, 0, 0, &clock_conf);
|
||||
}
|
||||
#endif
|
||||
|
||||
vrc = vtss_phy_conf_set(g_vtss_inst_p, 0 /*port_no*/, &g_phy);
|
||||
|
||||
/* HH: moved SerDes calibration here */
|
||||
vrc = vtss_phy_post_reset(g_vtss_inst_p, 0);
|
||||
|
||||
{
|
||||
uint16_t old_page;
|
||||
uint16_t temp_reg;
|
||||
|
||||
old_page = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, 3U);
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x17U);
|
||||
temp_reg &= (uint16_t)(~0x0010U); /* Clear media inhibit odd start delay bit */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x17U, temp_reg);
|
||||
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x10U);
|
||||
temp_reg &= (uint16_t)(~0x0004U); /* Clear mac inhibit odd start delay bit */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x10U, temp_reg);
|
||||
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x10U);
|
||||
temp_reg &= (uint16_t)(~0x0100U); /* Turn off 2 byte preamble */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x10U, temp_reg);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, old_page);
|
||||
}
|
||||
{
|
||||
uint16_t phy_reg;
|
||||
volatile uint32_t sgmii_aneg_timeout = 100000U;
|
||||
uint16_t autoneg_complete;
|
||||
|
||||
if(TBI == this_mac->interface_type)
|
||||
{
|
||||
phy_reg = (uint16_t)this_mac->mac_base->PCS_CONTROL;
|
||||
phy_reg |= 0x1000U;
|
||||
this_mac->mac_base->PCS_CONTROL = phy_reg;
|
||||
phy_reg |= 0x0200U;
|
||||
this_mac->mac_base->PCS_CONTROL = phy_reg;
|
||||
|
||||
/* Wait for SGMII auto-negotiation to complete. */
|
||||
do {
|
||||
phy_reg = (uint16_t)this_mac->mac_base->PCS_STATUS;
|
||||
autoneg_complete = phy_reg & BMSR_AUTO_NEGOTIATION_COMPLETE;
|
||||
--sgmii_aneg_timeout;
|
||||
} while(((0U == autoneg_complete) && (0U != sgmii_aneg_timeout)) || (0xFFFF == phy_reg));
|
||||
}
|
||||
|
||||
if(GMII_SGMII == this_mac->interface_type)
|
||||
{
|
||||
/*
|
||||
* SGMII to GMII core with embedded MDIO interface for SGMII
|
||||
* link control.
|
||||
*
|
||||
* Reset SGMII core side of I/F.
|
||||
*/
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR);
|
||||
phy_reg |= 0x9000U; /* Reset and start autonegotiation */
|
||||
phy_reg &= 0xFBFFU; /* Clear Isolate bit */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR, phy_reg);
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR);
|
||||
phy_reg |= 0x1000U; /* start autonegotiation */
|
||||
phy_reg &= 0xFBFFU; /* Clear gmii Isolate bit */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR, phy_reg);
|
||||
}
|
||||
#if 0
|
||||
/* Far-end loopback - enable at your peril... DO NOT try this on an open network*/
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x17U);
|
||||
phy_reg |= 0x8U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x17U, phy_reg);
|
||||
#endif
|
||||
/* LED control - configure LED 0 as RX indicator and LED 1 as TX indicator */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1DU);
|
||||
phy_reg &= 0xFF00U;
|
||||
phy_reg |= 0x00ABU;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1DU, phy_reg);
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1EU);
|
||||
phy_reg |= 0x4000U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1EU, phy_reg);
|
||||
#if 0
|
||||
/* Ethernet Packet Generator - enable at your peril... DO NOT try this on an open network */
|
||||
old_page = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, 1U);
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1DU);
|
||||
phy_reg |= 0xC000U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1DU, phy_reg);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, old_page);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* MSS_MAC_USE_PHY_VSC8575 */
|
||||
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8575_LITE
|
||||
extern int32_t usleep(uint32_t usecs);
|
||||
|
||||
void MSS_MAC_VSC8575_phy_init(/* mss_mac_instance_t */ const void *v_this_mac, uint8_t phy_addr)
|
||||
{
|
||||
static vsc_phy_loopback_t loopback;
|
||||
static vsc_phy_control_t cntrl;
|
||||
static vsc_phy_conf_t phy_config;
|
||||
static vsc_phy_port_status_t phy_status;
|
||||
|
||||
uint16_t old_page;
|
||||
uint16_t temp_reg;
|
||||
uint16_t phy_reg;
|
||||
volatile uint32_t sgmii_aneg_timeout = 100000U;
|
||||
uint16_t autoneg_complete;
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
volatile int32_t rc; /* Volatile so we can see rc when debugging as
|
||||
* otherwise it tends to get removed as we don't use
|
||||
* it.
|
||||
*/
|
||||
|
||||
(void)phy_addr;
|
||||
/* For now, simply record which MAC we are associated with, this is not
|
||||
* going to work with more than 1 VSC8575 in the system so we should really
|
||||
* have this stored in the cntrl structure but this involves modifying the
|
||||
* API code...
|
||||
*/
|
||||
g_my_mac = this_mac;
|
||||
|
||||
/* Start out blank for consistency */
|
||||
(void)memset (&cntrl, 0, sizeof(cntrl));
|
||||
(void)memset (&phy_config, 0, sizeof(phy_config));
|
||||
(void)memset (&phy_status, 0, sizeof(phy_status));
|
||||
(void)memset (&loopback, 0, sizeof(vsc_phy_loopback_t));
|
||||
|
||||
phy_config.mode = VSC_PHY_MODE_ANEG;
|
||||
|
||||
/* Forced Mode Config */
|
||||
phy_config.forced.port_speed = VSC_SPEED_1G;
|
||||
phy_config.forced.fdx = 1;
|
||||
|
||||
/* ANEG Config */
|
||||
phy_config.aneg.speed_10m_hdx = 1U;
|
||||
phy_config.aneg.speed_10m_fdx = 1U;
|
||||
phy_config.aneg.speed_100m_hdx = 1U;
|
||||
phy_config.aneg.speed_100m_fdx = 1U;
|
||||
phy_config.aneg.speed_1g_hdx = 0U;
|
||||
phy_config.aneg.speed_1g_fdx = 1U;
|
||||
phy_config.aneg.symmetric_pause = 1U;
|
||||
phy_config.aneg.asymmetric_pause = 0U;
|
||||
phy_config.aneg.tx_remote_fault = 1U;
|
||||
|
||||
/* forced Mode, 1G Config of Master/Slave */
|
||||
phy_config.conf_1g.master.cfg = 0U; /* Manual Master/Slave config to Force Master cfg */
|
||||
phy_config.conf_1g.master.val = 0U; /* Master=1, Slave=0 */
|
||||
|
||||
/* MDI/MDIX Config */
|
||||
phy_config.mdi = VSC_PHY_AUTO_MDIX;
|
||||
|
||||
/* FastLink Fail Config */
|
||||
phy_config.flf.flf = VSC_PHY_FAST_LINK_FAIL_DISABLE;
|
||||
|
||||
/* SigDet Config */
|
||||
phy_config.sigdet = VSC_PHY_SIGDET_POLARITY_ACT_HIGH;
|
||||
|
||||
/* UniDirectional Config */
|
||||
phy_config.unidir = VSC_PHY_UNIDIR_DISABLE;
|
||||
|
||||
/* Pkt Mode Config */
|
||||
phy_config.pkt_mode = VSC_PHY_PKT_MODE_IEEE_1_5_KB;
|
||||
|
||||
/* MAC PCS Config */
|
||||
/* Note: MAC PCS Config only sets bits, does not clear bits */
|
||||
/* Therefore, to use Chip Defaults, just use all 0's */
|
||||
phy_config.mac_if_pcs.disable = 0U;
|
||||
phy_config.mac_if_pcs.restart = 0U;
|
||||
phy_config.mac_if_pcs.pd_enable = 0U;
|
||||
phy_config.mac_if_pcs.aneg_restart = 0U;
|
||||
phy_config.mac_if_pcs.force_adv_ability = 0U;
|
||||
phy_config.mac_if_pcs.sgmii_in_pre = 0U;
|
||||
phy_config.mac_if_pcs.sgmii_out_pre = 0U;
|
||||
phy_config.mac_if_pcs.serdes_aneg_ena = 1U;
|
||||
phy_config.mac_if_pcs.serdes_pol_inv_in = 0U;
|
||||
phy_config.mac_if_pcs.serdes_pol_inv_out = 0U;
|
||||
phy_config.mac_if_pcs.fast_link_stat_ena = 0U;
|
||||
phy_config.mac_if_pcs.inhibit_odd_start = 0U;
|
||||
|
||||
/* Media PCS Config */
|
||||
/* Note: Media PCS Config only sets bits, does not clear bits */
|
||||
/* Therefore, to use Chip Defaults, just use all 0's */
|
||||
phy_config.media_if_pcs.remote_fault = VSC_PHY_MEDIA_SERD_PCS_REM_FAULT_NO_ERROR;
|
||||
phy_config.media_if_pcs.aneg_pd_detect = 1U;
|
||||
phy_config.media_if_pcs.force_adv_ability = 0U;
|
||||
phy_config.media_if_pcs.serdes_pol_inv_in = 0U;
|
||||
phy_config.media_if_pcs.serdes_pol_inv_out = 0U;
|
||||
phy_config.media_if_pcs.inhibit_odd_start = 1U;
|
||||
phy_config.media_if_pcs.force_hls = 0U;
|
||||
phy_config.media_if_pcs.force_fefi = 0U;
|
||||
phy_config.media_if_pcs.force_fefi_value = 0U;
|
||||
|
||||
rc = viper_fmc_board_init(&cntrl);
|
||||
|
||||
cntrl.phy_addr = 0U; /* This is actually the port number 0-3 on the VSC8575 */
|
||||
cntrl.phy_usleep = usleep;
|
||||
|
||||
rc = vsc_get_phy_type(&cntrl);
|
||||
cntrl.mac_if = PHY_MAC_IF_MODE_SGMII;
|
||||
cntrl.media_if = PHY_MEDIA_IF_CU;
|
||||
|
||||
/*------------------------------------------------------------------------------------------------
|
||||
* Initialize PHY, Only run on Base Port of the PHY, Run any Init Scripts and Micro-Patch Downloads
|
||||
*------------------------------------------------------------------------------------------------*/
|
||||
rc = initialize_viper_phy(&cntrl);
|
||||
|
||||
/*------------------------------------------------------------------------------------------------
|
||||
* Reset the PHY Port, Run on each Port of the PHY, Run any configs, etc.
|
||||
*------------------------------------------------------------------------------------------------*/
|
||||
rc = reset_viper_phy(&cntrl);
|
||||
rc = viper_phy_config_set(&cntrl, &phy_config);
|
||||
|
||||
/* The cntrl struct only saves the MEDIA i/f for the current port */
|
||||
/* Adjust the 1G SerDes SigDet Input Threshold and Signal Sensitivity for 100FX */
|
||||
/* This function gets called from Port 0, ie. cntrl->portAddr == BasePort
|
||||
* The tgt_port_no is the port_no that the operation is to occur upon.
|
||||
* The tgt_media_if is the tgt_port_no's Media i/f setting, which may or may
|
||||
* not be the same as Port 0, found in the cntl struct.
|
||||
*/
|
||||
#if 0 /* Not needed for our setup as we are Cu only... */
|
||||
cntrl.phy_addr = 0U;
|
||||
rc = viper_phy_media_sig_adjust(&cntrl, cntrl.media_if, 0);
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------------------------
|
||||
* Post-Reset the PHY, Run on the Base Port of the PHY, This will release Comma Mode
|
||||
*------------------------------------------------------------------------------------------------*/
|
||||
/* Now Run Post Reset on PHY Port 0, Initialized the 6G SerDes */
|
||||
rc = post_reset_viper_phy(&cntrl);
|
||||
|
||||
/*------------------------------------------------------------------------------------------------
|
||||
* Manually tweak some settings in the PHY
|
||||
*------------------------------------------------------------------------------------------------*/
|
||||
old_page = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, 3U);
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x17U);
|
||||
temp_reg &= (uint16_t)(~0x0010U); /* Clear media inhibit odd start delay bit */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x17U, temp_reg);
|
||||
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x10U);
|
||||
temp_reg &= (uint16_t)(~0x0004U); /* Clear mac inhibit odd start delay bit */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x10U, temp_reg);
|
||||
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x10U);
|
||||
temp_reg &= (uint16_t)(~0x0100U); /* Turn off 2 byte preamble */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x10U, temp_reg);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, old_page);
|
||||
|
||||
if(TBI == this_mac->interface_type)
|
||||
{
|
||||
phy_reg = (uint16_t)this_mac->mac_base->PCS_CONTROL;
|
||||
phy_reg |= 0x1000U;
|
||||
this_mac->mac_base->PCS_CONTROL = phy_reg;
|
||||
phy_reg |= 0x0200U;
|
||||
this_mac->mac_base->PCS_CONTROL = phy_reg;
|
||||
|
||||
/* Wait for SGMII auto-negotiation to complete. */
|
||||
do {
|
||||
phy_reg = (uint16_t)this_mac->mac_base->PCS_STATUS;
|
||||
autoneg_complete = phy_reg & BMSR_AUTO_NEGOTIATION_COMPLETE;
|
||||
--sgmii_aneg_timeout;
|
||||
} while(((0U == autoneg_complete) && (0U != sgmii_aneg_timeout)) || (0xFFFFU == phy_reg));
|
||||
}
|
||||
|
||||
if(GMII_SGMII == this_mac->interface_type)
|
||||
{
|
||||
/*
|
||||
* SGMII to GMII core with embedded MDIO interface for SGMII
|
||||
* link control.
|
||||
*
|
||||
* Reset SGMII core side of I/F.
|
||||
*/
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR);
|
||||
phy_reg |= 0x9000U; /* Reset and start autonegotiation */
|
||||
phy_reg &= 0xFBFFU; /* Clear Isolate bit */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR, phy_reg);
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR);
|
||||
phy_reg |= 0x1000U; /* start autonegotiation */
|
||||
phy_reg &= 0xFBFFU; /* Clear gmii Isolate bit */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR, phy_reg);
|
||||
}
|
||||
#if 0
|
||||
/* Far-end loopback - enable at your peril... DO NOT try this on an open network*/
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x17U);
|
||||
phy_reg |= 0x8U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x17U, phy_reg);
|
||||
#endif
|
||||
/* LED control - configure LED 0 as RX indicator and LED 1 as TX indicator */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1DU);
|
||||
phy_reg &= 0xFF00U;
|
||||
phy_reg |= 0x00ABU;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1DU, phy_reg);
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1EU);
|
||||
phy_reg |= 0x4000U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1EU, phy_reg);
|
||||
#if 0
|
||||
/* Ethernet Packet Generator - enable at your peril... DO NOT try this on an open network */
|
||||
old_page = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, 1U);
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1DU);
|
||||
phy_reg |= 0xC000U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1DU, phy_reg);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, old_page);
|
||||
#endif
|
||||
}
|
||||
#endif /* MSS_MAC_USE_PHY_VSC8575_LITE */
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_VSC8575_phy_set_link_speed(/* mss_mac_instance_t */ void *v_this_mac, uint32_t speed_duplex_select, mss_mac_speed_mode_t speed_mode)
|
||||
{
|
||||
mss_mac_instance_t *this_mac = (mss_mac_instance_t *)v_this_mac;
|
||||
uint16_t phy_reg;
|
||||
uint32_t inc;
|
||||
uint32_t speed_select;
|
||||
const uint16_t mii_advertise_bits[4] = {ADVERTISE_10FULL, ADVERTISE_10HALF,
|
||||
ADVERTISE_100FULL, ADVERTISE_100HALF};
|
||||
this_mac->speed_mode = speed_mode;
|
||||
|
||||
if(MSS_MAC_SPEED_AN == speed_mode) /* Set auto-negotiation advertisement. */
|
||||
{
|
||||
/* Set 10Mbps and 100Mbps advertisement. */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_ADVERTISE);
|
||||
phy_reg &= (uint16_t)(~(ADVERTISE_10HALF | ADVERTISE_10FULL |
|
||||
ADVERTISE_100HALF | ADVERTISE_100FULL));
|
||||
|
||||
speed_select = speed_duplex_select;
|
||||
for(inc = 0U; inc < 4U; ++inc)
|
||||
{
|
||||
uint32_t advertise;
|
||||
advertise = speed_select & 0x00000001U;
|
||||
if(advertise != 0U)
|
||||
{
|
||||
phy_reg |= mii_advertise_bits[inc];
|
||||
}
|
||||
speed_select = speed_select >> 1U;
|
||||
}
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_ADVERTISE, phy_reg);
|
||||
|
||||
/* Set 1000Mbps advertisement. */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000);
|
||||
phy_reg &= (uint16_t)(~(ADVERTISE_1000FULL | ADVERTISE_1000HALF));
|
||||
|
||||
if((speed_duplex_select & MSS_MAC_ANEG_1000M_FD) != 0U)
|
||||
{
|
||||
phy_reg |= ADVERTISE_1000FULL;
|
||||
}
|
||||
|
||||
if((speed_duplex_select & MSS_MAC_ANEG_1000M_HD) != 0U)
|
||||
{
|
||||
phy_reg |= ADVERTISE_1000HALF;
|
||||
}
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, phy_reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t temp_reg = 0x0000U; /* Default with 10M, half duplex */
|
||||
|
||||
if((MSS_MAC_10_FDX == this_mac->speed_mode) || (MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_1000_FDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_FULLDPLX;
|
||||
}
|
||||
|
||||
if((MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_100_HDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_SPEED100;
|
||||
}
|
||||
|
||||
if((MSS_MAC_1000_FDX == this_mac->speed_mode) || (MSS_MAC_1000_HDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_SPEED1000;
|
||||
/* Set Master mode */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000);
|
||||
phy_reg |= 0x1800U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, phy_reg);
|
||||
}
|
||||
|
||||
/* Apply static speed/duplex selection */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMCR, temp_reg);
|
||||
|
||||
/* Full duplex mode or half duplex, multi port device */
|
||||
if((MSS_MAC_10_FDX == this_mac->speed_mode) || (MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_1000_FDX == this_mac->speed_mode))
|
||||
{
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, (uint16_t)(ADVERTISE_1000FULL | 0x0400U ));
|
||||
}
|
||||
else
|
||||
{
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, (uint16_t)(ADVERTISE_1000HALF | 0x0400U ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_VSC8575_phy_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac)
|
||||
{
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
uint8_t link_fullduplex;
|
||||
mss_mac_speed_t link_speed;
|
||||
uint8_t copper_link_up;
|
||||
volatile uint16_t phy_reg;
|
||||
uint16_t autoneg_complete;
|
||||
volatile uint32_t sgmii_aneg_timeout = 100000U;
|
||||
|
||||
copper_link_up = this_mac->phy_get_link_status(this_mac, &link_speed, &link_fullduplex);
|
||||
if(1U == copper_link_up)
|
||||
{
|
||||
#if 0 /* PMCS fixup */
|
||||
SYSREG->MAC_CR = (SYSREG->MAC_CR & ~MAC_CONFIG_SPEED_MASK) | link_speed;
|
||||
/* Configure duplex mode */
|
||||
if(0U == link_fullduplex)
|
||||
{
|
||||
/* half duplex */
|
||||
MAC->CFG2 &= ~CFG2_FDX_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* full duplex */
|
||||
MAC->CFG2 |= CFG2_FDX_MASK;
|
||||
}
|
||||
#endif
|
||||
if(TBI == this_mac->interface_type)
|
||||
{
|
||||
phy_reg = (uint16_t)this_mac->mac_base->PCS_CONTROL;
|
||||
phy_reg |= 0x1000U;
|
||||
this_mac->mac_base->PCS_CONTROL = phy_reg;
|
||||
phy_reg |= 0x0200U;
|
||||
this_mac->mac_base->PCS_CONTROL = phy_reg;
|
||||
|
||||
/* Wait for SGMII auto-negotiation to complete. */
|
||||
do {
|
||||
phy_reg = (uint16_t)this_mac->mac_base->PCS_STATUS;
|
||||
autoneg_complete = phy_reg & BMSR_AUTO_NEGOTIATION_COMPLETE;
|
||||
--sgmii_aneg_timeout;
|
||||
} while(((0U == autoneg_complete) && (0U != sgmii_aneg_timeout)) || (0xFFFFU == phy_reg));
|
||||
}
|
||||
|
||||
if(GMII_SGMII == this_mac->interface_type)
|
||||
{
|
||||
/*
|
||||
* SGMII to GMII core with embedded MDIO interface for SGMII
|
||||
* link control.
|
||||
*
|
||||
* Initiate auto-negotiation on the SGMII link.
|
||||
*/
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, 0x00U);
|
||||
phy_reg |= 0x1000U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, 0x00U, phy_reg);
|
||||
phy_reg |= 0x0200U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, 0x00U, phy_reg);
|
||||
|
||||
/* Wait for SGMII auto-negotiation to complete. */
|
||||
do {
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMSR);
|
||||
autoneg_complete = phy_reg & BMSR_AUTO_NEGOTIATION_COMPLETE;
|
||||
--sgmii_aneg_timeout;
|
||||
} while((0U == autoneg_complete) && (0U != sgmii_aneg_timeout));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_VSC8575_mac_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac)
|
||||
{
|
||||
(void)v_this_mac;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
|
||||
uint8_t MSS_MAC_VSC8575_phy_get_link_status
|
||||
(
|
||||
/* mss_mac_instance_t*/ const void *v_this_mac,
|
||||
mss_mac_speed_t * speed,
|
||||
uint8_t * fullduplex
|
||||
)
|
||||
{
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
volatile uint16_t phy_reg;
|
||||
uint16_t copper_link_up;
|
||||
uint8_t link_status;
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMSR);
|
||||
copper_link_up = phy_reg & BMSR_LSTATUS;
|
||||
|
||||
if(copper_link_up != MSS_MAC_LINK_DOWN)
|
||||
{
|
||||
uint16_t op_mode;
|
||||
|
||||
/* Link is up. */
|
||||
link_status = MSS_MAC_LINK_UP;
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1CU);
|
||||
|
||||
op_mode = (phy_reg >> 3) & 0x0003U;
|
||||
if(0U == (phy_reg & 0x0020U))
|
||||
{
|
||||
*fullduplex = MSS_MAC_HALF_DUPLEX;
|
||||
}
|
||||
else
|
||||
{
|
||||
*fullduplex = MSS_MAC_FULL_DUPLEX;
|
||||
}
|
||||
|
||||
switch(op_mode)
|
||||
{
|
||||
case 0U:
|
||||
*speed = MSS_MAC_10MBPS;
|
||||
break;
|
||||
|
||||
case 1U:
|
||||
*speed = MSS_MAC_100MBPS;
|
||||
break;
|
||||
|
||||
case 2U:
|
||||
*speed = MSS_MAC_1000MBPS;
|
||||
break;
|
||||
|
||||
default:
|
||||
link_status = (uint8_t)MSS_MAC_LINK_DOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Link is down. */
|
||||
link_status = (uint8_t)MSS_MAC_LINK_DOWN;
|
||||
}
|
||||
|
||||
return link_status;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/******************************** END OF FILE ******************************/
|
||||
|
||||
|
|
@ -0,0 +1,531 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2020 Microchip Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Support routines for the VTS API for the Microsemi VSC8575 PHY interface
|
||||
* to support the peripheral daughter board for the G5 SoC Emulation Platform.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h> /* For va_list */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
#include "hal/hal.h"
|
||||
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_sw_cfg.h"
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8575
|
||||
#include "vtss_api.h" /* For BOOL and friends */
|
||||
#include "vtss_phy_api.h" /* For PHY API Pre and Post Resets */
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8575_LITE
|
||||
#include "vtss_phy_common.h"
|
||||
#include "vtss_viper_phy_prototypes.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_registers.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac.h"
|
||||
#include "drivers/mss_ethernet_mac/phy.h"
|
||||
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_types.h"
|
||||
|
||||
#ifdef _ZL303XX_FMC_BOARD
|
||||
/* Only needed if SPI interfaces required */
|
||||
#include "mss_spi.h"
|
||||
#include "core_spi.h"
|
||||
#endif
|
||||
/* Kernel includes. */
|
||||
#if defined(USING_FREERTOS)
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#else
|
||||
extern volatile uint64_t g_tick_counter;
|
||||
#endif
|
||||
|
||||
/* Uncomment the following to enable logging of MDIO writes to memory */
|
||||
/* VSC8575_DEBUG_MDIO */
|
||||
|
||||
#ifdef __DEBUG_SOCKET__
|
||||
|
||||
#ifndef T_E
|
||||
#define T_E(...) \
|
||||
printf("Error: %s, %s, %d, \n", __FILE__, __FUNCTION__, __LINE__); \
|
||||
printf(__VA_ARGS__);
|
||||
#endif
|
||||
|
||||
#ifndef T_W
|
||||
#define T_W(...) \
|
||||
printf("Warning: %s, %s, %d, \n", __FILE__, __FUNCTION__, __LINE__); \
|
||||
printf(__VA_ARGS__);
|
||||
#endif
|
||||
|
||||
#ifndef T_N
|
||||
#define T_N(...) \
|
||||
printf("Notify: %s, %s, %d, \n", __FILE__, __FUNCTION__, __LINE__); \
|
||||
printf(__VA_ARGS__);
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define T_E(...)
|
||||
#define T_W(...)
|
||||
#define T_N(...)
|
||||
#endif
|
||||
|
||||
extern mss_mac_instance_t *g_my_mac;
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8575
|
||||
/* ================================================================= *
|
||||
* Trace
|
||||
* ================================================================= */
|
||||
|
||||
vtss_trace_conf_t vtss_appl_trace_conf = {
|
||||
.level = {VTSS_TRACE_LEVEL_ERROR, VTSS_TRACE_LEVEL_ERROR}
|
||||
};
|
||||
|
||||
static void printf_trace_head(const vtss_trace_layer_t layer,
|
||||
const vtss_trace_group_t group,
|
||||
const vtss_trace_level_t level,
|
||||
const char *file,
|
||||
const int line,
|
||||
const char *function,
|
||||
const char *lcont)
|
||||
{
|
||||
time_t t;
|
||||
int h, m, s;
|
||||
|
||||
(void)group;
|
||||
(void)file;
|
||||
(void)line;
|
||||
t = 0; /* time(NULL); */
|
||||
h = (int)(t / 3600 % 24);
|
||||
m = (int)(t / 60 % 60);
|
||||
s = (int)(t % 60);
|
||||
printf("%u:%02u:%02u %s/%s %s%s",
|
||||
h, m, s,
|
||||
layer == VTSS_TRACE_LAYER_COUNT ? "APPL": layer == VTSS_TRACE_LAYER_AIL ? "AIL" : "CIL",
|
||||
level == VTSS_TRACE_LEVEL_ERROR ? "Error" :
|
||||
level == VTSS_TRACE_LEVEL_INFO ? "Info " :
|
||||
level == VTSS_TRACE_LEVEL_DEBUG ? "Debug" :
|
||||
level == VTSS_TRACE_LEVEL_NOISE ? "Noise" : "?????",
|
||||
function, lcont);
|
||||
}
|
||||
|
||||
|
||||
/* Trace callout function */
|
||||
void vtss_callout_trace_printf(const vtss_trace_layer_t layer,
|
||||
const vtss_trace_group_t group,
|
||||
const vtss_trace_level_t level,
|
||||
const char *file,
|
||||
const int line,
|
||||
const char *function,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
va_list va;
|
||||
printf_trace_head(layer, group, level, file, line, function, ": ");
|
||||
|
||||
va_start(va, format);
|
||||
vprintf(format, va);
|
||||
va_end(va);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
/* Trace hex-dump callout function */
|
||||
void vtss_callout_trace_hex_dump(const vtss_trace_layer_t layer,
|
||||
const vtss_trace_group_t group,
|
||||
const vtss_trace_level_t level,
|
||||
const char *file,
|
||||
const int line,
|
||||
const char *function,
|
||||
const unsigned char *byte_p,
|
||||
const int byte_cnt)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf_trace_head(layer, group, level, file, line, function, "\n");
|
||||
|
||||
for (i= 0; i < byte_cnt; i += 16) {
|
||||
int j = 0;
|
||||
printf("%04x:", i);
|
||||
while (j+i < byte_cnt && j < 16) {
|
||||
printf(" %02x", byte_p[i+j]);
|
||||
j++;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
vtss_rc miim_read(const vtss_inst_t inst,
|
||||
const vtss_port_no_t phy_port,
|
||||
const u8 phy_reg,
|
||||
u16 *const value);
|
||||
|
||||
vtss_rc miim_write(const vtss_inst_t inst,
|
||||
const vtss_port_no_t phy_port,
|
||||
const u8 phy_reg,
|
||||
const u16 value);
|
||||
|
||||
int32_t viper_fmc_board_init(vtss_init_conf_t *target);
|
||||
|
||||
|
||||
|
||||
/* Function for initializing the hardware board. */
|
||||
int32_t viper_fmc_board_init(vtss_init_conf_t *target)
|
||||
{
|
||||
#ifdef _ZL303XX_FMC_BOARD
|
||||
/* 0x30200000U is the base address of the CoreSPI in the fabric */
|
||||
SPI_init(&g_vsc_spi, 0x30200000U , 32); /* Now is probably a good time to take care of this... */
|
||||
/*
|
||||
* Note: for the FMC board, the APB clock frequency is 83MHz and the maximum
|
||||
* allowed clock frequency for the 1588 SPI interface is 25MHz. We can only choose
|
||||
* even clock divisors and a divisor of 4 used in the design gives us a 20.75MHz SPI clock.
|
||||
*/
|
||||
SPI_configure_master_mode(&g_vsc_spi); /* Motorola Mode 0, 8 bits selected in design */
|
||||
SPI_set_slave_select(&g_vsc_spi, SPI_SLAVE_0);
|
||||
|
||||
target->spi_read_write = spi_read_write; /* Set pointer to SPI interface r/w function for this board */
|
||||
#endif
|
||||
|
||||
target->miim_read = miim_read; /* Set pointer to the MIIM read function for this board. */
|
||||
target->miim_write = miim_write; /* Set pointer to the MIIM write function for this board. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void vtss_callout_lock(const vtss_api_lock_t *const lock)
|
||||
{
|
||||
(void)lock;
|
||||
}
|
||||
|
||||
|
||||
void vtss_callout_unlock(const vtss_api_lock_t *const lock)
|
||||
{
|
||||
(void)lock;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* brief SPI read/write function
|
||||
*
|
||||
* param inst [IN] Vitesse API instance.
|
||||
* param port_no [IN] Port number.
|
||||
* param bitsize [IN] Size (in bytes) of bitstream following this parameter.
|
||||
* param data [IN|OUT] Pointer to the data to be written to SPI Slave, if doing write operation.
|
||||
* Pointer to the data read from SPI Slave, if doing read operation.
|
||||
*
|
||||
* return Return code.
|
||||
**/
|
||||
/* G5 SOC Emulation platform has no SPI interface at the moment... */
|
||||
#ifdef _ZL303XX_FMC_BOARD
|
||||
|
||||
vtss_rc spi_read_write(const vtss_inst_t inst,
|
||||
const vtss_port_no_t port_no,
|
||||
const u8 bitsize,
|
||||
u8 *const bitstream);
|
||||
vtss_rc spi_read_write(const vtss_inst_t inst,
|
||||
const vtss_port_no_t port_no,
|
||||
const u8 bitsize,
|
||||
u8 *const bitstream)
|
||||
{
|
||||
(void)inst;
|
||||
(void)port_no;
|
||||
/*
|
||||
* The VTSS API transfers 32 bit values using this function.
|
||||
*
|
||||
* We use the bitsize parameter to determine read vs write as
|
||||
* it will be 7 for writes and 10 for reads.
|
||||
*
|
||||
* The first 3 bytes are the R/W status and the register address
|
||||
* information.
|
||||
*
|
||||
* When writing, the next 4 values are the frame to write,
|
||||
* When reading, the next 3 values are padding and the last 4
|
||||
* bytes are the read data.
|
||||
*/
|
||||
if(7 == bitsize) /* Write operation */
|
||||
{
|
||||
SPI_transfer_block_vsc(&g_vsc_spi, bitstream, bitsize, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SPI_transfer_block_vsc(&g_vsc_spi, bitstream, 6, &bitstream[6], 4);
|
||||
}
|
||||
return VTSS_RC_OK;
|
||||
}
|
||||
#endif /* _ZL303XX_FMC_BOARD */
|
||||
|
||||
|
||||
|
||||
/* ================================================================= *
|
||||
* Misc. functions
|
||||
* ================================================================= */
|
||||
#if 0 /* PMCS: Remove for now */
|
||||
/* Function defining the port interface. */
|
||||
static vtss_port_interface_t port_interface(vtss_port_no_t port_no)
|
||||
{
|
||||
return VTSS_PORT_INTERFACE_SGMII;
|
||||
}
|
||||
|
||||
/* Function defining the port interface. */
|
||||
static void viper_phy_pre_reset(void)
|
||||
{
|
||||
vtss_rc rc;
|
||||
rc = vtss_phy_pre_reset (NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Function defining the port interface. */
|
||||
static vtss_rc viper_phy_post_reset(void)
|
||||
{
|
||||
return (vtss_phy_post_reset (NULL, 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Each board can have it own way of communicating with the chip. The miim read and write function are called by the API
|
||||
* when the API needs to do register access.
|
||||
*
|
||||
* Miim read access specific for this board.
|
||||
* In : port_no - The port to access.
|
||||
* addr - The address to access
|
||||
*
|
||||
* In/Out: value - Pointer to the value to be returned
|
||||
*/
|
||||
|
||||
|
||||
vtss_rc miim_read(const vtss_inst_t inst,
|
||||
const vtss_port_no_t phy_port,
|
||||
const u8 phy_reg,
|
||||
u16 *const value)
|
||||
{
|
||||
#ifdef __DEBUG_SOCKET__
|
||||
const uint16_t port_no = (uint16_t) phy_port;
|
||||
uint8_t addr = (uint8_t)phy_reg & 0xff;
|
||||
#endif
|
||||
(void)inst;
|
||||
if((void *)0 != g_my_mac)
|
||||
{
|
||||
*value = MSS_MAC_read_phy_reg(g_my_mac, (uint8_t)(phy_port + g_my_mac->phy_addr), (uint8_t)phy_reg); /* TBD: PMCS Warning only works for single MAC/VSC8575 combination */
|
||||
}
|
||||
|
||||
T_N("miim read port_no = %d, addr = %d, value = 0x%X", port_no, addr, *value);
|
||||
|
||||
return VTSS_RC_OK;
|
||||
}
|
||||
|
||||
|
||||
#if defined(VSC8575_DEBUG_MDIO)
|
||||
/* Store all in 32 bit values so mem dump can view them neatly on 16 byte boundaries... */
|
||||
typedef struct mii_debug_data
|
||||
{
|
||||
#if defined(USING_FREERTOS)
|
||||
TickType_t time;
|
||||
#else
|
||||
uint64_t time;
|
||||
#endif
|
||||
/* vtss_port_no_t */ uint32_t page;
|
||||
/* u8 */ uint32_t reg;
|
||||
/*u16 */ uint32_t data;
|
||||
} mii_debug_data_t;
|
||||
|
||||
mii_debug_data_t mii_data[1000];
|
||||
uint32_t mii_data_index = 0;
|
||||
uint32_t mii_page;
|
||||
#endif
|
||||
/*
|
||||
* Miim write access specific for this board.
|
||||
* In : port_no - The port to access.
|
||||
* addr - The address to access
|
||||
* value - The value to written
|
||||
*/
|
||||
vtss_rc miim_write(const vtss_inst_t inst,
|
||||
const vtss_port_no_t phy_port,
|
||||
const u8 phy_reg,
|
||||
const u16 value)
|
||||
{
|
||||
#ifdef __DEBUG_SOCKET__
|
||||
const uint16_t port_no = (uint16_t) phy_port;
|
||||
uint8_t addr = phy_reg & 0xff;
|
||||
#endif
|
||||
|
||||
(void)inst;
|
||||
#if defined(VSC8575_DEBUG_MDIO)
|
||||
if(0x1f == phy_reg)
|
||||
{
|
||||
mii_page = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(USING_FREERTOS)
|
||||
mii_data[mii_data_index].time = xTaskGetTickCount();
|
||||
#else
|
||||
mii_data[mii_data_index].time = g_tick_counter;
|
||||
#endif
|
||||
mii_data[mii_data_index].page = mii_page;
|
||||
mii_data[mii_data_index].reg = phy_reg;
|
||||
mii_data[mii_data_index].data = value;
|
||||
mii_data_index++;
|
||||
if(1000 == mii_data_index)
|
||||
{
|
||||
mii_data_index = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
T_N("miim_writes port_no = %d, addr = %d, value = 0x%X", port_no, addr ,value);
|
||||
if((void *)0 != g_my_mac)
|
||||
{
|
||||
MSS_MAC_write_phy_reg(g_my_mac, (uint8_t)(phy_port + g_my_mac->phy_addr), (uint8_t)phy_reg, value); /* TBD: PMCS Warning only works for single MAC/VSC8575 combination */
|
||||
}
|
||||
|
||||
return VTSS_RC_OK;
|
||||
}
|
||||
#endif /* MSS_MAC_USE_PHY_VSC8575 */
|
||||
#if MSS_MAC_USE_PHY_VSC8575_LITE
|
||||
int32_t miim_read(const uint32_t phy_port, const uint16_t phy_reg, uint16_t *const value);
|
||||
int32_t miim_write(const uint32_t phy_port, const uint16_t phy_reg, const uint16_t value);
|
||||
int32_t usleep(uint32_t usecs);
|
||||
int32_t viper_fmc_board_init(struct phy_control_t *cntrl);
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
* emulate the Unix usleep function using the taskdelay functionality of
|
||||
* FreeRTOS. It is not very close as our example system currently uses a 1mS
|
||||
* tick but all the instances of usleep() being called in the VTSS API Lite are
|
||||
* for 1000uS so it should do...
|
||||
*/
|
||||
int32_t usleep(uint32_t usecs)
|
||||
{
|
||||
#if defined(USING_FREERTOS)
|
||||
uint32_t ustick = portTICK_PERIOD_MS * 1000U; /* calculate microseconds per tick */
|
||||
|
||||
/* convert uS to ticks, rounding up to the nearest tick */
|
||||
usecs = (usecs + (ustick - 1)) / ustick;
|
||||
|
||||
vTaskDelay(usecs);
|
||||
#else
|
||||
/* Assumes 1mS tick... */
|
||||
volatile uint64_t timeout = g_tick_counter + (((uint64_t)usecs + 999ULL) / 1000ULL);
|
||||
volatile uint64_t index = 0U;
|
||||
|
||||
while(g_tick_counter <= timeout)
|
||||
{
|
||||
index++; /* Stop debugger from locking up... */
|
||||
}
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Each board can have it own way of communicating with the chip. The miim read and write function are called by the API
|
||||
* when the API needs to do register access.
|
||||
*
|
||||
* Miim read access specific for this board.
|
||||
* In : port_no - The port to access.
|
||||
* addr - The address to access
|
||||
*
|
||||
* In/Out: value - Pointer to the value to be returned
|
||||
*/
|
||||
int32_t miim_read( const uint32_t phy_port,
|
||||
const uint16_t phy_reg,
|
||||
uint16_t *const value)
|
||||
{
|
||||
#ifdef __DEBUG_SOCKET__
|
||||
const uint16_t port_no = (uint16_t) phy_port;
|
||||
uint8_t addr = (uint8_t)phy_reg & 0xff;
|
||||
#endif
|
||||
|
||||
if((void *)0 != g_my_mac)
|
||||
{
|
||||
*value = MSS_MAC_read_phy_reg(g_my_mac, (uint8_t)(phy_port + g_my_mac->phy_addr), (uint8_t)phy_reg); /* TBD: PMCS Warning only works for single MAC/VSC8575 combination */
|
||||
}
|
||||
|
||||
T_N("miim read port_no = %d, addr = %d, value = 0x%X", port_no, addr, *value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Miim write access specific for this board.
|
||||
* In : port_no - The port to access.
|
||||
* addr - The address to access
|
||||
* value - The value to written
|
||||
*
|
||||
* Store all in 32 bit values so mem dump can view them neatly on 16 byte boundaries...
|
||||
*/
|
||||
#if defined(VSC8575_DEBUG_MDIO)
|
||||
typedef struct mii_debug_data
|
||||
{
|
||||
TickType_t time;
|
||||
/* vtss_port_no_t */ uint32_t page;
|
||||
/* u8 */ uint32_t reg;
|
||||
/*u16 */ uint32_t data;
|
||||
} mii_debug_data_t;
|
||||
|
||||
mii_debug_data_t mii_data[1000];
|
||||
uint32_t mii_data_index = 0;
|
||||
uint32_t mii_page = 0;
|
||||
#endif
|
||||
int32_t miim_write( const uint32_t phy_port,
|
||||
const uint16_t phy_reg,
|
||||
const uint16_t value)
|
||||
{
|
||||
#ifdef __DEBUG_SOCKET__
|
||||
const uint16_t port_no = (uint16_t) phy_port;
|
||||
uint8_t addr = phy_reg & 0xff;
|
||||
#endif
|
||||
|
||||
#if defined(VSC8575_DEBUG_MDIO)
|
||||
if(0 == phy_port)
|
||||
{
|
||||
if(0x1f == phy_reg)
|
||||
{
|
||||
mii_page = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mii_data[mii_data_index].time = xTaskGetTickCount();
|
||||
mii_data[mii_data_index].page = mii_page;
|
||||
mii_data[mii_data_index].reg = phy_reg;
|
||||
mii_data[mii_data_index].data = value;
|
||||
mii_data_index++;
|
||||
if(1000 == mii_data_index)
|
||||
{
|
||||
mii_data_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
T_N("miim_writes port_no = %d, addr = %d, value = 0x%X", port_no, addr ,value);
|
||||
if((void *)0 != g_my_mac)
|
||||
{
|
||||
MSS_MAC_write_phy_reg(g_my_mac, (uint8_t)(phy_port + g_my_mac->phy_addr), (uint8_t)phy_reg, value); /* TBD: PMCS Warning only works for single MAC/VSC8575 combination */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Function for initializing the hardware board. */
|
||||
int32_t viper_fmc_board_init(struct phy_control_t *cntrl)
|
||||
{
|
||||
cntrl->phy_reg_read = miim_read; /* Set pointer to the MIIM read function for this board. */
|
||||
cntrl->phy_reg_write = miim_write; /* Set pointer to the MIIM write function for this board. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MSS_MAC_USE_PHY_VSC8575_LITE */
|
|
@ -0,0 +1,744 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2020 Microchip Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Microsemi VSC8662 PHY interface driver implementation to support the silicon
|
||||
* validation board.
|
||||
*
|
||||
* Will need to modify FW based on MSS GPIO configuration.
|
||||
*
|
||||
*/
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
#include "hal/hal.h"
|
||||
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_registers.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac_sw_cfg.h"
|
||||
#include "drivers/mss_ethernet_mac/mss_ethernet_mac.h"
|
||||
#include "drivers/mss_ethernet_mac/phy.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if MSS_MAC_USE_PHY_VSC8662
|
||||
|
||||
/**************************************************************************/
|
||||
/* Preprocessor Macros */
|
||||
/**************************************************************************/
|
||||
|
||||
#define BMSR_AUTO_NEGOTIATION_COMPLETE (0x0020U)
|
||||
|
||||
/**************************************************************************//**
|
||||
* Ensure ports 2 and 3 are shut down as they are not bonded out for the
|
||||
* VSC8862.
|
||||
*/
|
||||
static void vsc8662_post_reset_step_01(const mss_mac_instance_t *this_mac)
|
||||
{
|
||||
uint32_t phy_base_address;
|
||||
|
||||
phy_base_address = this_mac->phy_addr & 0xFCU; /* Calculate base address for chip */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + 2), 31, 0x0000U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + 2), 0, 0x0800U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + 3), 31, 0x0000U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + 3), 0, 0x0800U);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* Enable broadcast writes for the VSC8662
|
||||
*/
|
||||
static void vsc8662_enable_bcast_writes(const mss_mac_instance_t *this_mac)
|
||||
{
|
||||
uint32_t phy_base_address;
|
||||
uint16_t temp_reg;
|
||||
|
||||
phy_base_address = this_mac->phy_addr & 0xFCU; /* Calculate base address for chip */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address), 31, 0x0000U);
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)(phy_base_address), 22);
|
||||
temp_reg |= 0x0001U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address), 22, temp_reg);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* Disable broadcast writes for the VSC8662
|
||||
*/
|
||||
static void vsc8662_disable_bcast_writes(const mss_mac_instance_t *this_mac)
|
||||
{
|
||||
uint32_t phy_base_address;
|
||||
uint16_t temp_reg;
|
||||
|
||||
phy_base_address = this_mac->phy_addr & 0xFCU; /* Calculate base address for chip */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address), 31, 0x0000U);
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)(phy_base_address), 22);
|
||||
temp_reg &= 0xFFFEU;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address), 22, temp_reg);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* Enable LED blinking for the VSC8662
|
||||
*/
|
||||
static void vsc8662_enable_LED_blink(const mss_mac_instance_t *this_mac)
|
||||
{
|
||||
uint32_t phy_base_address;
|
||||
uint16_t temp_reg;
|
||||
uint32_t count;
|
||||
|
||||
phy_base_address = this_mac->phy_addr & 0xFCU; /* Calculate base address for chip */
|
||||
|
||||
for(count = 0; count != 2; count++)
|
||||
{
|
||||
/* Enable LED blink port[count] */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 31, 0x0001U);
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 19);
|
||||
temp_reg |= 0x0800U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 19, temp_reg);
|
||||
|
||||
/* Soft reset port[count] */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 31, 0x0000U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 0, 0x9040U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* Apply 100/1000BASE-T amplitude correction fix for the VSC8662.
|
||||
*/
|
||||
static void vsc8662_100tx_1000t_amplitude_fix(const mss_mac_instance_t *this_mac)
|
||||
{
|
||||
uint32_t phy_base_address;
|
||||
uint16_t temp_reg;
|
||||
uint32_t count;
|
||||
|
||||
phy_base_address = this_mac->phy_addr & 0xFCU; /* Calculate base address for chip */
|
||||
|
||||
for(count = 0; count != 2; count++)
|
||||
{
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 31, 0x52B5U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0000U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x003FU);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x8794U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x00F7U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0xADB4U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x879EU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0000U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x0032U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87A0U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0041U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x0410U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87A2U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0041U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x0410U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87A4U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0041U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x0284U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87A6U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0092U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0xBCB8U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87A8U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0003U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0xCFBFU);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87AAU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0049U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x2451U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87ACU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0001U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x1410U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87C0U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0010U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0xB498U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87E8U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0071U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0xE7DDU);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87EAU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0069U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x6512U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87ECU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0049U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x2451U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87EEU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0045U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x0410U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87F0U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0041U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x0410U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87F2U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0000U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x0010U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x87F4U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 31, 0x2A30U);
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 9);
|
||||
temp_reg = (uint16_t)((temp_reg & 0xFFFFU) | 0x0040U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 9, temp_reg);
|
||||
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 22);
|
||||
temp_reg = (uint16_t)((temp_reg & 0xFFFFU) | 0x0010U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 22, temp_reg);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 31, 0x0000U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* Apply 10BASE-T performance fix for the VSC8662.
|
||||
*/
|
||||
static void vsc8662_10t_performance_fix(const mss_mac_instance_t *this_mac)
|
||||
{
|
||||
uint32_t phy_base_address;
|
||||
uint16_t temp_reg;
|
||||
uint32_t count;
|
||||
|
||||
phy_base_address = this_mac->phy_addr & 0xFCU; /* Calculate base address for chip */
|
||||
|
||||
for(count = 0; count != 2; count++)
|
||||
{
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 31, 0x2A30U);
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 0);
|
||||
temp_reg = (uint16_t)((temp_reg & 0xFFEFU) | 0x0060U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 0, temp_reg);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 31, 0x52B5U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0012U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x480AU);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x8F82U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0000U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x0422U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x8F86U);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x003CU);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0x3800U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x8F8AU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 18, 0x0008U);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 17, 0xE33FU);
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 16, 0x83AEU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)(phy_base_address + count), 31, 0x0000U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_VSC8662_phy_init(/* mss_mac_instance_t*/ const void *v_this_mac, uint8_t phy_addr)
|
||||
{
|
||||
uint16_t temp_reg;
|
||||
volatile uint16_t phy_reg;
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
mss_mac_instance_t *phy_mac;
|
||||
volatile uint32_t sgmii_aneg_timeout = 100000U;
|
||||
uint16_t autoneg_complete;
|
||||
volatile uint64_t timer_count = 1000000;
|
||||
|
||||
/* Do hardware reset if possible/necessary */
|
||||
|
||||
/* Phy is actually attached to another MAC... */
|
||||
if((struct mss_mac_instance *)0UL != this_mac->phy_controller)
|
||||
{
|
||||
phy_mac = (mss_mac_instance_t *)this_mac->phy_controller;
|
||||
}
|
||||
else
|
||||
{
|
||||
phy_mac = (mss_mac_instance_t *)this_mac;
|
||||
}
|
||||
#if defined(MSS_MAC_PHY_HW_RESET) || defined(MSS_MAC_PHY_HW_SRESET)
|
||||
if(0 == phy_mac->phy_hard_reset_done)
|
||||
{
|
||||
/* Active low reset pulse */
|
||||
MSS_MAC_phy_reset(phy_mac, MSS_MAC_HARD_RESET, false);
|
||||
MSS_MAC_phy_reset(phy_mac, MSS_MAC_HARD_RESET, true);
|
||||
|
||||
#if defined(TARGET_G5_SOC)
|
||||
/*
|
||||
* Multiple MACs may be involved and we need to ensure all relevant MACs
|
||||
* have the phy_hard_reset_done flag set
|
||||
*/
|
||||
|
||||
if(phy_mac != this_mac) /* Simple case, set flag for all 4 MACs */
|
||||
{
|
||||
g_mac0.phy_hard_reset_done = true;
|
||||
g_emac0.phy_hard_reset_done = true;
|
||||
g_mac1.phy_hard_reset_done = true;
|
||||
g_emac1.phy_hard_reset_done = true;
|
||||
}
|
||||
else if((&g_mac0 == phy_mac) || (&g_emac0 == phy_mac))
|
||||
{
|
||||
g_mac0.phy_hard_reset_done = true;
|
||||
g_emac0.phy_hard_reset_done = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_mac1.phy_hard_reset_done = true;
|
||||
g_emac1.phy_hard_reset_done = true;
|
||||
}
|
||||
#else
|
||||
phy_mac->phy_hard_reset_done = true;
|
||||
#endif
|
||||
}
|
||||
#endif /* defined(MSS_MAC_PHY_HW_RESET) || defined(MSS_MAC_PHY_HW_RESET) */
|
||||
|
||||
/* Select standard registers page */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 31, 0x0000U);
|
||||
|
||||
/*
|
||||
* Enable SGMII MAC link autonegotiation and Force copper media only
|
||||
*
|
||||
* According to a VSC8664 app note this register needs to be updated first
|
||||
* followed by a soft reset, the scripts and finally the rest of the user
|
||||
* setup.
|
||||
*/
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 23, (uint16_t)(0x2880U));
|
||||
|
||||
/* Soft reset */
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, phy_addr, 0);
|
||||
temp_reg |= 0x8000;
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 0, temp_reg);
|
||||
|
||||
/*
|
||||
* Need at least a 4uS pause here after setting reset bit before accessing
|
||||
* PHY again
|
||||
*/
|
||||
while(0 != timer_count)
|
||||
{
|
||||
--timer_count;
|
||||
}
|
||||
|
||||
/* First take care of all the fixes and adjustments from the data sheet */
|
||||
vsc8662_post_reset_step_01(this_mac);
|
||||
vsc8662_enable_LED_blink(this_mac);
|
||||
vsc8662_100tx_1000t_amplitude_fix(this_mac);
|
||||
vsc8662_10t_performance_fix(this_mac);
|
||||
|
||||
/* Select standard registers page */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 31, 0x0000U);
|
||||
|
||||
if(MSS_MAC_SPEED_AN == this_mac->speed_mode)
|
||||
{
|
||||
/* Full duplex, autonegotiation and 1000Mbps as starting point */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, MII_BMCR, (uint16_t)(BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000));
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_reg = 0x0000U; /* Default with 10M, half duplex */
|
||||
|
||||
if((MSS_MAC_10_FDX == this_mac->speed_mode) || (MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_1000_FDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_FULLDPLX;
|
||||
}
|
||||
|
||||
if((MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_100_HDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_SPEED100;
|
||||
}
|
||||
|
||||
if((MSS_MAC_1000_FDX == this_mac->speed_mode) || (MSS_MAC_1000_HDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_SPEED1000;
|
||||
}
|
||||
|
||||
/* Apply static speed/duplex selection */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, MII_BMCR, temp_reg);
|
||||
}
|
||||
|
||||
/* Full duplex modes */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, MII_ADVERTISE, (uint16_t)(ADVERTISE_FULL));
|
||||
|
||||
/* Full duplex mode or half duplex, multi port device */
|
||||
if((MSS_MAC_10_FDX == this_mac->speed_mode) || (MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_1000_FDX == this_mac->speed_mode))
|
||||
{
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, MII_CTRL1000, (uint16_t)(ADVERTISE_1000FULL | 0x0400U ));
|
||||
}
|
||||
else
|
||||
{
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, MII_CTRL1000, (uint16_t)(ADVERTISE_1000HALF | 0x0400U ));
|
||||
}
|
||||
/* Auto MDI/MDI-X, Do not ignore advertised ability, enable CLKOUT */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 18, (uint16_t)(0x0089U));
|
||||
|
||||
/* SGMII no input preamble, 2 byte output preamble, 9/12K jumbo frames (12K for 60ppm clock) */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 24, (uint16_t)(0xC050U));
|
||||
|
||||
/* Select selection of LED activity modes for 4 LEDs */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 29, (uint16_t)(0x0123U));
|
||||
|
||||
/* Clear this for consistency as many bits are CMODE selections */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 30, (uint16_t)(0x0000U));
|
||||
|
||||
/* Select extended registers page */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 31, 0x0001U);
|
||||
|
||||
/* Enable RX Equalization and Hysteresis on SERDES interface */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 11, (uint16_t)(0x0292U));
|
||||
|
||||
/* Clear SIGDET polarity to active high */
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, phy_addr, 19);
|
||||
temp_reg &= 0xFFFE;
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 19, temp_reg);
|
||||
|
||||
/* Ensure all CMODE bits are clear */
|
||||
temp_reg = MSS_MAC_read_phy_reg(this_mac, phy_addr, 20);
|
||||
temp_reg &= 0xFE6F;
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 20, temp_reg);
|
||||
|
||||
/* Select general purpose registers page */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 31, 0x0010U);
|
||||
|
||||
/* Disable SIGDET operation */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 13, (uint16_t)(0x000FU));
|
||||
|
||||
#if defined(MSS_MAC_VSC8662_NWC_25)
|
||||
/* 25MHZ Recovered clock 1 and 2 enabled with ref clock source and no squelch */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 23, (uint16_t)(0x8033U));
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 24, (uint16_t)(0x8033U));
|
||||
#elif defined(MSS_MAC_VSC8662_NWC_125)
|
||||
/* 125MHZ Recovered clock 1 and 2 enabled with ref clock source and no squelch */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 23, (uint16_t)(0x8133U));
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 24, (uint16_t)(0x8133U));
|
||||
#endif
|
||||
|
||||
/* Select standard registers page */
|
||||
MSS_MAC_write_phy_reg(this_mac, phy_addr, 31, 0x0000U);
|
||||
|
||||
phy_reg = (uint16_t)this_mac->mac_base->PCS_CONTROL;
|
||||
phy_reg |= 0x1000U;
|
||||
this_mac->mac_base->PCS_CONTROL = phy_reg;
|
||||
phy_reg |= 0x0200U;
|
||||
this_mac->mac_base->PCS_CONTROL = phy_reg;
|
||||
|
||||
/* Wait for SGMII auto-negotiation to complete. */
|
||||
do {
|
||||
phy_reg = (uint16_t)this_mac->mac_base->PCS_STATUS;
|
||||
autoneg_complete = phy_reg & BMSR_AUTO_NEGOTIATION_COMPLETE;
|
||||
--sgmii_aneg_timeout;
|
||||
} while(((0U == autoneg_complete) && (0U != sgmii_aneg_timeout)) || (0xFFFFU == phy_reg));
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_VSC8662_phy_set_link_speed(/* mss_mac_instance_t */ void *v_this_mac, uint32_t speed_duplex_select, mss_mac_speed_mode_t speed_mode)
|
||||
{
|
||||
mss_mac_instance_t *this_mac = (mss_mac_instance_t *)v_this_mac;
|
||||
uint16_t phy_reg;
|
||||
uint32_t inc;
|
||||
uint32_t speed_select;
|
||||
const uint16_t mii_advertise_bits[4] = {ADVERTISE_10FULL, ADVERTISE_10HALF,
|
||||
ADVERTISE_100FULL, ADVERTISE_100HALF};
|
||||
|
||||
this_mac->speed_mode = speed_mode;
|
||||
|
||||
if(MSS_MAC_SPEED_AN == speed_mode) /* Set auto-negotiation advertisement. */
|
||||
{
|
||||
/* Set 10Mbps and 100Mbps advertisement. */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_ADVERTISE);
|
||||
phy_reg &= (uint16_t)(~(ADVERTISE_10HALF | ADVERTISE_10FULL |
|
||||
ADVERTISE_100HALF | ADVERTISE_100FULL));
|
||||
|
||||
speed_select = speed_duplex_select;
|
||||
for(inc = 0U; inc < 4U; ++inc)
|
||||
{
|
||||
uint32_t advertise;
|
||||
advertise = speed_select & 0x00000001U;
|
||||
if(advertise != 0U)
|
||||
{
|
||||
phy_reg |= mii_advertise_bits[inc];
|
||||
}
|
||||
speed_select = speed_select >> 1U;
|
||||
}
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_ADVERTISE, phy_reg);
|
||||
|
||||
/* Set 1000Mbps advertisement. */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000);
|
||||
phy_reg &= (uint16_t)(~(ADVERTISE_1000FULL | ADVERTISE_1000HALF));
|
||||
|
||||
if((speed_duplex_select & MSS_MAC_ANEG_1000M_FD) != 0U)
|
||||
{
|
||||
phy_reg |= ADVERTISE_1000FULL;
|
||||
}
|
||||
|
||||
if((speed_duplex_select & MSS_MAC_ANEG_1000M_HD) != 0U)
|
||||
{
|
||||
phy_reg |= ADVERTISE_1000HALF;
|
||||
}
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, phy_reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t temp_reg = 0x0000U; /* Default with 10M, half duplex */
|
||||
|
||||
if((MSS_MAC_10_FDX == this_mac->speed_mode) || (MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_1000_FDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_FULLDPLX;
|
||||
}
|
||||
|
||||
if((MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_100_HDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_SPEED100;
|
||||
}
|
||||
|
||||
if((MSS_MAC_1000_FDX == this_mac->speed_mode) || (MSS_MAC_1000_HDX == this_mac->speed_mode))
|
||||
{
|
||||
temp_reg |= BMCR_SPEED1000;
|
||||
/* Set Master mode */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000);
|
||||
phy_reg |= 0x1800U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, phy_reg);
|
||||
}
|
||||
|
||||
/* Apply static speed/duplex selection */
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMCR, temp_reg);
|
||||
|
||||
/* Full duplex mode or half duplex, multi port device */
|
||||
if((MSS_MAC_10_FDX == this_mac->speed_mode) || (MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_1000_FDX == this_mac->speed_mode))
|
||||
{
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, (uint16_t)(ADVERTISE_1000FULL | 0x0400U ));
|
||||
}
|
||||
else
|
||||
{
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_CTRL1000, (uint16_t)(ADVERTISE_1000HALF | 0x0400U ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_VSC8662_phy_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac)
|
||||
{
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
volatile uint16_t phy_reg;
|
||||
uint16_t autoneg_complete;
|
||||
volatile uint32_t copper_aneg_timeout = 100000U;
|
||||
|
||||
if(MSS_MAC_SPEED_AN == this_mac->speed_mode) /* Only do if allowed */
|
||||
{
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 2U);
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 3U);
|
||||
|
||||
/* Enable auto-negotiation. */
|
||||
phy_reg = 0x1340U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMCR, phy_reg);
|
||||
|
||||
/* Wait for copper auto-negotiation to complete. */
|
||||
do {
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMSR);
|
||||
autoneg_complete = phy_reg & BMSR_AUTO_NEGOTIATION_COMPLETE;
|
||||
--copper_aneg_timeout;
|
||||
} while(((0U == autoneg_complete) && (copper_aneg_timeout != 0u)) || (0xFFFF == phy_reg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void MSS_MAC_VSC8662_mac_autonegotiate(/* mss_mac_instance_t */ const void *v_this_mac)
|
||||
{
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
volatile uint16_t phy_reg;
|
||||
uint16_t autoneg_complete;
|
||||
volatile uint32_t copper_aneg_timeout = 10000U;
|
||||
|
||||
/* Enable auto-negotiation. */
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 27);
|
||||
phy_reg |= 0x1000U;
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 27, phy_reg);
|
||||
|
||||
if(0U == this_mac->is_emac)
|
||||
{
|
||||
volatile uint32_t temp_reg;
|
||||
|
||||
temp_reg = this_mac->mac_base->PCS_CONTROL;
|
||||
this_mac->mac_base->PCS_CONTROL = temp_reg | GEM_RESTART_AUTO_NEG;
|
||||
}
|
||||
|
||||
/* Wait for SGMII auto-negotiation to complete. */
|
||||
do {
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 27);
|
||||
autoneg_complete = phy_reg & 0x0002U;
|
||||
--copper_aneg_timeout;
|
||||
} while(((0U == autoneg_complete) && (copper_aneg_timeout != 0u)) || (0xFFFF == phy_reg));
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
uint8_t MSS_MAC_VSC8662_phy_get_link_status
|
||||
(
|
||||
/* mss_mac_instance_t */ const void *v_this_mac,
|
||||
mss_mac_speed_t * speed,
|
||||
uint8_t * fullduplex
|
||||
)
|
||||
{
|
||||
const mss_mac_instance_t *this_mac = (const mss_mac_instance_t *)v_this_mac;
|
||||
uint16_t phy_reg;
|
||||
uint16_t link_up;
|
||||
uint8_t link_status;
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, MII_BMSR);
|
||||
link_up = phy_reg & BMSR_LSTATUS;
|
||||
|
||||
if(link_up != MSS_MAC_LINK_DOWN)
|
||||
{
|
||||
uint16_t duplex;
|
||||
uint16_t speed_field;
|
||||
|
||||
/* Link is up. */
|
||||
link_status = MSS_MAC_LINK_UP;
|
||||
|
||||
phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1CU); /* Device Auxillary Control and Status */
|
||||
duplex = phy_reg & 0x0020U;
|
||||
speed_field = phy_reg & 0x0018U;
|
||||
|
||||
if(MSS_MAC_HALF_DUPLEX == duplex)
|
||||
{
|
||||
*fullduplex = MSS_MAC_HALF_DUPLEX;
|
||||
}
|
||||
else
|
||||
{
|
||||
*fullduplex = MSS_MAC_FULL_DUPLEX;
|
||||
}
|
||||
|
||||
switch(speed_field >> 3)
|
||||
{
|
||||
case 0U:
|
||||
*speed = MSS_MAC_10MBPS;
|
||||
break;
|
||||
|
||||
case 1U:
|
||||
*speed = MSS_MAC_100MBPS;
|
||||
break;
|
||||
|
||||
case 2U:
|
||||
*speed = MSS_MAC_1000MBPS;
|
||||
break;
|
||||
|
||||
default:
|
||||
link_status = (uint8_t)MSS_MAC_LINK_DOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Link is down. */
|
||||
link_status = (uint8_t)MSS_MAC_LINK_DOWN;
|
||||
}
|
||||
|
||||
return link_status;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
uint16_t VSC8662_reg_0[32];
|
||||
uint16_t VSC8662_reg_1[16];
|
||||
uint16_t VSC8662_reg_16[32];
|
||||
|
||||
void dump_vsc8662_regs(const mss_mac_instance_t * this_mac);
|
||||
void dump_vsc8662_regs(const mss_mac_instance_t * this_mac)
|
||||
{
|
||||
int32_t count;
|
||||
uint16_t page;
|
||||
uint16_t old_page;
|
||||
uint16_t *pdata;
|
||||
volatile psr_t lev;
|
||||
|
||||
for(page = 0U; page <= 0x10U; page++)
|
||||
{
|
||||
if(0U == page)
|
||||
{
|
||||
pdata = VSC8662_reg_0;
|
||||
}
|
||||
else if(1U == page)
|
||||
{
|
||||
pdata = VSC8662_reg_1;
|
||||
}
|
||||
else if(16U == page)
|
||||
{
|
||||
pdata = VSC8662_reg_16;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdata = VSC8662_reg_0;
|
||||
}
|
||||
|
||||
if((0U == page) || (0x10U == page))
|
||||
{
|
||||
for(count = 0; count <= 0x1F; count++)
|
||||
{
|
||||
lev = HAL_disable_interrupts();
|
||||
old_page = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, page);
|
||||
|
||||
pdata[count] = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, (uint8_t)count);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, old_page);
|
||||
HAL_restore_interrupts(lev);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(count = 0x10; count <= 0x1F; count++)
|
||||
{
|
||||
lev = HAL_disable_interrupts();
|
||||
old_page = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, page);
|
||||
|
||||
pdata[count - 0X10] = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, (uint8_t)count);
|
||||
|
||||
MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->phy_addr, 0x1FU, old_page);
|
||||
HAL_restore_interrupts(lev);
|
||||
}
|
||||
}
|
||||
|
||||
if(1U == page)
|
||||
{
|
||||
page = 0x0FU;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #if defined(TARGET_ALOE) */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************** END OF FILE ******************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_sources()
|
||||
zephyr_sources(mss_gpio.c)
|
||||
|
|
@ -0,0 +1,481 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* PolarFire SoC microprocessor subsystem GPIO bare metal driver implementation.
|
||||
*
|
||||
* This driver is based on SmartFusion2 MSS GPIO driver v2.1.102
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
#include "mss_gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Defines.
|
||||
*/
|
||||
#define GPIO_INT_ENABLE_MASK ((uint32_t)0x00000008)
|
||||
#define OUTPUT_BUFFER_ENABLE_MASK ((uint32_t)0x00000004)
|
||||
|
||||
/*These constants define the number of GPIO bits available on each GPIO
|
||||
* hardware block*/
|
||||
#define NB_OF_GPIO_GPIO0 ((uint32_t)14)
|
||||
#define NB_OF_GPIO_GPIO1 ((uint32_t)24)
|
||||
#define NB_OF_GPIO_GPIO2 ((uint32_t)32)
|
||||
|
||||
/*This constant indicates the total number of GPIO interrupt inputs at the PLIC
|
||||
* (includes the direct and non-direct GPIO interrupts)*/
|
||||
#define NB_OF_GPIO_INTR ((uint32_t)41)
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Lookup table of GPIO interrupt number indexed on GPIO ID.
|
||||
* The GPIO interrupts are multiplexed. Total GPIO interrupts are 41.
|
||||
* 41 = (14 from GPIO0 + 24 from GPIO1 + 3 non direct interrupts)
|
||||
* GPIO2 interrupts are not available by default. Setting the corresponding bit
|
||||
* in GPIO_INTERRUPT_FAB_CR(31:0) will enable GPIO2(31:0) corresponding
|
||||
* interrupt on PLIC.
|
||||
*
|
||||
* PLIC GPIO_INTERRUPT_FAB_CR
|
||||
0 1
|
||||
0 GPIO0 bit 0 GPIO2 bit 0
|
||||
1 GPIO0 bit 1 GPIO2 bit 1
|
||||
.
|
||||
.
|
||||
12 GPIO0 bit 12 GPIO2 bit 12
|
||||
13 GPIO0 bit 13 GPIO2 bit 13
|
||||
14 GPIO1 bit 0 GPIO2 bit 14
|
||||
15 GPIO1 bit 1 GPIO2 bit 15
|
||||
.
|
||||
.
|
||||
.
|
||||
30 GPIO1 bit 16 GPIO2 bit 30
|
||||
31 GPIO1 bit 17 GPIO2 bit 31
|
||||
32 GPIO1 bit 18
|
||||
33 GPIO1 bit 19
|
||||
34 GPIO1 bit 20
|
||||
35 GPIO1 bit 21
|
||||
36 GPIO1 bit 22
|
||||
37 GPIO1 bit 23
|
||||
38 Or of all GPIO0 interrupts who do not have a direct connection enabled
|
||||
39 Or of all GPIO1 interrupts who do not have a direct connection enabled
|
||||
40 Or of all GPIO2 interrupts who do not have a direct connection enabled
|
||||
*
|
||||
*/
|
||||
static const PLIC_IRQn_Type g_gpio_irqn_lut[NB_OF_GPIO_INTR] =
|
||||
{
|
||||
GPIO0_BIT0_or_GPIO2_BIT0_PLIC_0,
|
||||
GPIO0_BIT1_or_GPIO2_BIT1_PLIC_1,
|
||||
GPIO0_BIT2_or_GPIO2_BIT2_PLIC_2,
|
||||
GPIO0_BIT3_or_GPIO2_BIT3_PLIC_3,
|
||||
GPIO0_BIT4_or_GPIO2_BIT4_PLIC_4,
|
||||
GPIO0_BIT5_or_GPIO2_BIT5_PLIC_5,
|
||||
GPIO0_BIT6_or_GPIO2_BIT6_PLIC_6,
|
||||
GPIO0_BIT7_or_GPIO2_BIT7_PLIC_7,
|
||||
GPIO0_BIT8_or_GPIO2_BIT8_PLIC_8,
|
||||
GPIO0_BIT9_or_GPIO2_BIT9_PLIC_9,
|
||||
GPIO0_BIT10_or_GPIO2_BIT10_PLIC_10,
|
||||
GPIO0_BIT11_or_GPIO2_BIT11_PLIC_11,
|
||||
GPIO0_BIT12_or_GPIO2_BIT12_PLIC_12,
|
||||
GPIO0_BIT13_or_GPIO2_BIT13_PLIC_13,
|
||||
|
||||
GPIO1_BIT0_or_GPIO2_BIT14_PLIC_14,
|
||||
GPIO1_BIT1_or_GPIO2_BIT15_PLIC_15,
|
||||
GPIO1_BIT2_or_GPIO2_BIT16_PLIC_16,
|
||||
GPIO1_BIT3_or_GPIO2_BIT17_PLIC_17,
|
||||
GPIO1_BIT4_or_GPIO2_BIT18_PLIC_18,
|
||||
GPIO1_BIT5_or_GPIO2_BIT19_PLIC_19,
|
||||
GPIO1_BIT6_or_GPIO2_BIT20_PLIC_20,
|
||||
GPIO1_BIT7_or_GPIO2_BIT21_PLIC_21,
|
||||
GPIO1_BIT8_or_GPIO2_BIT22_PLIC_22,
|
||||
GPIO1_BIT9_or_GPIO2_BIT23_PLIC_23,
|
||||
GPIO1_BIT10_or_GPIO2_BIT24_PLIC_24,
|
||||
GPIO1_BIT11_or_GPIO2_BIT25_PLIC_25,
|
||||
GPIO1_BIT12_or_GPIO2_BIT26_PLIC_26,
|
||||
GPIO1_BIT13_or_GPIO2_BIT27_PLIC_27,
|
||||
GPIO1_BIT14_or_GPIO2_BIT28_PLIC_28,
|
||||
GPIO1_BIT15_or_GPIO2_BIT29_PLIC_29,
|
||||
GPIO1_BIT16_or_GPIO2_BIT30_PLIC_30,
|
||||
GPIO1_BIT17_or_GPIO2_BIT31_PLIC_31,
|
||||
|
||||
GPIO1_BIT18_PLIC_32,
|
||||
GPIO1_BIT19_PLIC_33,
|
||||
GPIO1_BIT20_PLIC_34,
|
||||
GPIO1_BIT21_PLIC_35,
|
||||
GPIO1_BIT22_PLIC_36,
|
||||
GPIO1_BIT23_PLIC_37,
|
||||
|
||||
GPIO0_NON_DIRECT_PLIC,
|
||||
GPIO1_NON_DIRECT_PLIC,
|
||||
GPIO2_NON_DIRECT_PLIC
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Local functions
|
||||
*/
|
||||
static uint8_t gpio_number_validate(GPIO_TypeDef const * gpio, mss_gpio_id_t gpio_idx);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_init
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_GPIO_init
|
||||
(
|
||||
GPIO_TypeDef * gpio
|
||||
)
|
||||
{
|
||||
/* clear all pending interrupts*/
|
||||
gpio->GPIO_IRQ = 0xFFFFFFFFU;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_config
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_config
|
||||
(
|
||||
GPIO_TypeDef * gpio,
|
||||
mss_gpio_id_t port_id,
|
||||
uint32_t config
|
||||
)
|
||||
{
|
||||
if (0U == gpio_number_validate(gpio, port_id))
|
||||
{
|
||||
gpio->GPIO_CFG[port_id] = config;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0); /*LDRA warning*/
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_config_byte
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_config_byte
|
||||
(
|
||||
GPIO_TypeDef * gpio,
|
||||
mss_gpio_byte_num_t byte_num,
|
||||
uint32_t config
|
||||
)
|
||||
{
|
||||
if (((GPIO0_LO == gpio) || (GPIO0_HI == gpio)) &&
|
||||
(byte_num >= MSS_GPIO_BYTE_1))
|
||||
{
|
||||
ASSERT(0);
|
||||
}
|
||||
else if (((GPIO1_LO == gpio) || (GPIO1_HI == gpio)) &&
|
||||
(byte_num > MSS_GPIO_BYTE_2))
|
||||
{
|
||||
ASSERT(0);
|
||||
}
|
||||
else if (((GPIO2_LO == gpio) || (GPIO2_HI == gpio)) &&
|
||||
(byte_num > MSS_GPIO_BYTE_3))
|
||||
{
|
||||
ASSERT(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio->GPIO_CFG_BYTE[byte_num] = config;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_config_all
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_config_all
|
||||
(
|
||||
GPIO_TypeDef * gpio,
|
||||
uint32_t config
|
||||
)
|
||||
{
|
||||
gpio->GPIO_CFG_ALL = config;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_set_output
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_set_output
|
||||
(
|
||||
GPIO_TypeDef * gpio,
|
||||
mss_gpio_id_t port_id,
|
||||
uint8_t value
|
||||
)
|
||||
{
|
||||
uint32_t gpio_setting;
|
||||
|
||||
if (0U == gpio_number_validate(gpio, port_id))
|
||||
{
|
||||
/* Setting the bit in GPIO_SET_BITS (offset 0xA4) sets the corresponding
|
||||
* output port.
|
||||
* Setting the bit in GPIO_CLR_BITS (offset 0xA0) clears the
|
||||
* corresponding output port.*/
|
||||
|
||||
if (value > 0u)
|
||||
{
|
||||
gpio->GPIO_SET_BITS = ((uint32_t)0x01 << port_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio->GPIO_CLR_BITS = ((uint32_t)0x01 << port_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0); /*LDRA warning*/
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_drive_inout
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_drive_inout
|
||||
(
|
||||
GPIO_TypeDef * gpio,
|
||||
mss_gpio_id_t port_id,
|
||||
mss_gpio_inout_state_t inout_state
|
||||
)
|
||||
{
|
||||
uint32_t outputs_state;
|
||||
uint32_t config;
|
||||
|
||||
if (0U == gpio_number_validate(gpio, port_id))
|
||||
{
|
||||
switch (inout_state)
|
||||
{
|
||||
case MSS_GPIO_DRIVE_HIGH:
|
||||
/* Set output high */
|
||||
gpio->GPIO_SET_BITS = ((uint32_t)1 << port_id);
|
||||
|
||||
/* Enable output buffer */
|
||||
config = gpio->GPIO_CFG[port_id];
|
||||
config |= OUTPUT_BUFFER_ENABLE_MASK;
|
||||
gpio->GPIO_CFG[port_id] = config;
|
||||
break;
|
||||
|
||||
case MSS_GPIO_DRIVE_LOW:
|
||||
/* Set output low */
|
||||
gpio->GPIO_CLR_BITS = (uint32_t)1 << port_id;
|
||||
/* Enable output buffer */
|
||||
config = gpio->GPIO_CFG[port_id];
|
||||
config |= OUTPUT_BUFFER_ENABLE_MASK;
|
||||
gpio->GPIO_CFG[port_id] = config;
|
||||
break;
|
||||
|
||||
case MSS_GPIO_HIGH_Z:
|
||||
/* Disable output buffer */
|
||||
config = gpio->GPIO_CFG[port_id];
|
||||
config &= ~OUTPUT_BUFFER_ENABLE_MASK;
|
||||
gpio->GPIO_CFG[port_id] = config;
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0); /*LDRA warning*/
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_enable_irq
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_enable_irq
|
||||
(
|
||||
GPIO_TypeDef * gpio,
|
||||
mss_gpio_id_t port_id
|
||||
)
|
||||
{
|
||||
uint32_t cfg_value;
|
||||
|
||||
if (0U == gpio_number_validate(gpio, port_id))
|
||||
{
|
||||
cfg_value = gpio->GPIO_CFG[(uint8_t)port_id];
|
||||
gpio->GPIO_CFG[(uint8_t)port_id] = (cfg_value | GPIO_INT_ENABLE_MASK);
|
||||
|
||||
if ((GPIO0_LO == gpio) || (GPIO0_HI == gpio))
|
||||
{
|
||||
PLIC_EnableIRQ(g_gpio_irqn_lut[port_id]);
|
||||
}
|
||||
else if ((GPIO1_LO == gpio) || (GPIO1_HI == gpio))
|
||||
{
|
||||
PLIC_EnableIRQ(g_gpio_irqn_lut[port_id +
|
||||
GPIO1_BIT0_or_GPIO2_BIT14_PLIC_14]);
|
||||
}
|
||||
else if ((GPIO2_LO == gpio) || (GPIO2_HI == gpio))
|
||||
{
|
||||
PLIC_EnableIRQ(g_gpio_irqn_lut[port_id]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0); /*LDRA warning*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0); /*LDRA warning*/
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_disable_irq
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
|
||||
void MSS_GPIO_disable_irq
|
||||
(
|
||||
GPIO_TypeDef * gpio,
|
||||
mss_gpio_id_t port_id
|
||||
)
|
||||
{
|
||||
uint32_t cfg_value;
|
||||
|
||||
if (0U == gpio_number_validate(gpio, port_id))
|
||||
{
|
||||
cfg_value = gpio->GPIO_CFG[(uint8_t)port_id];
|
||||
gpio->GPIO_CFG[(uint8_t)port_id] = (cfg_value & (~GPIO_INT_ENABLE_MASK));
|
||||
|
||||
if ((GPIO0_LO == gpio) || (GPIO0_HI == gpio))
|
||||
{
|
||||
PLIC_DisableIRQ(g_gpio_irqn_lut[port_id]);
|
||||
}
|
||||
else if ((GPIO1_LO == gpio) || (GPIO1_HI == gpio))
|
||||
{
|
||||
PLIC_DisableIRQ(g_gpio_irqn_lut[port_id +
|
||||
GPIO1_BIT0_or_GPIO2_BIT14_PLIC_14]);
|
||||
}
|
||||
else if ((GPIO2_LO == gpio) || (GPIO2_HI == gpio))
|
||||
{
|
||||
PLIC_DisableIRQ(GPIO2_NON_DIRECT_PLIC);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0); /*LDRA warning*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0); /*LDRA warning*/
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_enable_nondirect_irq
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_GPIO_enable_nondirect_irq
|
||||
(
|
||||
GPIO_TypeDef const * gpio
|
||||
)
|
||||
{
|
||||
if ((GPIO0_LO == gpio) || (GPIO0_HI == gpio))
|
||||
{
|
||||
PLIC_EnableIRQ(GPIO0_NON_DIRECT_PLIC);
|
||||
}
|
||||
else if ((GPIO1_LO == gpio) || (GPIO1_HI == gpio))
|
||||
{
|
||||
PLIC_EnableIRQ(GPIO1_NON_DIRECT_PLIC);
|
||||
}
|
||||
else if ((GPIO2_LO == gpio) || (GPIO2_HI == gpio))
|
||||
{
|
||||
PLIC_EnableIRQ(GPIO2_NON_DIRECT_PLIC);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0); /*LDRA warning*/
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_disable_nondirect_irq
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_GPIO_disable_nondirect_irq
|
||||
(
|
||||
GPIO_TypeDef const * gpio
|
||||
)
|
||||
{
|
||||
if ((GPIO0_LO == gpio) || (GPIO0_HI == gpio))
|
||||
{
|
||||
PLIC_DisableIRQ(GPIO0_NON_DIRECT_PLIC);
|
||||
}
|
||||
else if ((GPIO1_LO == gpio) || (GPIO1_HI == gpio))
|
||||
{
|
||||
PLIC_DisableIRQ(GPIO1_NON_DIRECT_PLIC);
|
||||
}
|
||||
else if ((GPIO2_LO == gpio) || (GPIO2_HI == gpio))
|
||||
{
|
||||
PLIC_DisableIRQ(GPIO2_NON_DIRECT_PLIC);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0); /*LDRA warning*/
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_clear_irq
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_clear_irq
|
||||
(
|
||||
GPIO_TypeDef * gpio,
|
||||
mss_gpio_id_t port_id
|
||||
)
|
||||
{
|
||||
if (0U == gpio_number_validate(gpio, port_id))
|
||||
{
|
||||
gpio->GPIO_IRQ = ((uint32_t)1) << port_id;
|
||||
__asm("fence");
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0); /*LDRA warning*/
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t gpio_number_validate(GPIO_TypeDef const * gpio, mss_gpio_id_t gpio_idx)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
if (((GPIO0_LO == gpio) || (GPIO0_HI == gpio)) &&
|
||||
(gpio_idx >= NB_OF_GPIO_GPIO0))
|
||||
{
|
||||
ret = 1u;
|
||||
}
|
||||
else if (((GPIO1_LO == gpio) || (GPIO1_HI == gpio)) &&
|
||||
(gpio_idx >= NB_OF_GPIO_GPIO1))
|
||||
{
|
||||
ret = 1u;
|
||||
}
|
||||
else if (((GPIO2_LO == gpio) || (GPIO2_HI == gpio)) &&
|
||||
(gpio_idx >= NB_OF_GPIO_GPIO2))
|
||||
{
|
||||
ret = 1u;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0u;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,67 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Register bit offsets and masks definitions for PolarFire SoC Microprocessor
|
||||
* Subsystem I2C bare metal software driver.
|
||||
*
|
||||
*/
|
||||
#ifndef MSS_I2C_REGS_H_
|
||||
#define MSS_I2C_REGS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
Register Bit definitions
|
||||
*/
|
||||
#define CR0 (uint8_t)0u
|
||||
#define CR1 (uint8_t)1u
|
||||
#define AA (uint8_t)2u
|
||||
#define SI (uint8_t)3u
|
||||
#define STO (uint8_t)4u
|
||||
#define STA (uint8_t)5u
|
||||
#define ENS1 (uint8_t)6u
|
||||
#define CR2 (uint8_t)7u
|
||||
|
||||
#define CR0_MASK (uint8_t)(0x01)
|
||||
#define CR1_MASK (uint8_t)(0x02)
|
||||
#define AA_MASK (uint8_t)(0x04)
|
||||
#define SI_MASK (uint8_t)(0x08)
|
||||
#define STO_MASK (uint8_t)(0x10)
|
||||
#define STA_MASK (uint8_t)(0x20)
|
||||
|
||||
#define ENS1_MASK (uint8_t)(0x40)
|
||||
#define CR2_MASK (uint8_t)(0x80)
|
||||
#define DATA_DIR (uint8_t)0u
|
||||
#define DATA_DIR_MASK (uint8_t)(0x01)
|
||||
|
||||
#define ADDR_GC (uint8_t)0u
|
||||
|
||||
#define ADDR_GC_MASK (uint8_t)0x01
|
||||
|
||||
#define SMBALERT_IE (uint8_t)0u
|
||||
#define SMBSUS_IE (uint8_t)1u
|
||||
#define SMB_IPMI_EN (uint8_t)2u
|
||||
#define SMBALERT_NI (uint8_t)3u
|
||||
#define SMBALERT_NO (uint8_t)4u
|
||||
#define SMBSUS_NI (uint8_t)5u
|
||||
#define SMBSUS_NO (uint8_t)6u
|
||||
#define SMBUS_RESET (uint8_t)7u
|
||||
|
||||
#define SMBALERT_IE_MASK (uint8_t)(0x01)
|
||||
#define SMBSUS_IE_MASK (uint8_t)(0x02)
|
||||
#define SMB_IPMI_EN_MASK (0x01 << SMB_IPMI_EN)
|
||||
#define SMBALERT_NI_MASK (0x01 << SMBALERT_NI)
|
||||
#define SMBALERT_NO_MASK (uint8_t)(0x10)
|
||||
#define SMBSUS_NI_MASK (0x01 << SMBSUS_NI)
|
||||
#define SMBSUS_NO_MASK (uint8_t)(0x40)
|
||||
#define SMBUS_RESET_MASK (uint8_t)(0x80)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_I2C_REGS_H_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,365 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* PolarFire SoC MSS eMMC SD Interface Level Driver.
|
||||
*
|
||||
* This eMMC/SD Interface driver provides functions for transferring
|
||||
* configuration and programming commands to the eMMC/SD device. Functions
|
||||
* contained within the eMMC/SD interface driver are accessed through the
|
||||
* mss_mmc_if.h header file.
|
||||
*
|
||||
*/
|
||||
#include "mss_mmc_if.h"
|
||||
#include "mss_mmc_regs.h"
|
||||
#include "mss_mmc_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MMC_CLEAR 0u
|
||||
#define MMC_SET 1u
|
||||
#define SHIFT_16BIT 16u
|
||||
#define DELAY_COUNT 0xFFFFu
|
||||
|
||||
/***************************************************************************//**
|
||||
* Local Function Prototypes
|
||||
*/
|
||||
static cif_response_t response_1_parser(void);
|
||||
static uint32_t process_request_checkresptype(uint8_t responsetype);
|
||||
static cif_response_t cq_execute_task(uint8_t task_id);
|
||||
/***************************************************************************//**
|
||||
* cif_send_cmd()
|
||||
* See ".h" for details of how to use this function.
|
||||
*/
|
||||
cif_response_t cif_send_cmd
|
||||
(
|
||||
uint32_t cmd_arg,
|
||||
uint32_t cmd_type,
|
||||
uint8_t resp_type
|
||||
)
|
||||
{
|
||||
uint32_t trans_status_isr;
|
||||
cif_response_t ret_status = TRANSFER_IF_FAIL;
|
||||
|
||||
/* clear all status interrupts except:
|
||||
* current limit error, card interrupt, card removal, card insertion */
|
||||
MMC->SRS12 = ~(SRS12_CURRENT_LIMIT_ERROR
|
||||
| SRS12_CARD_INTERRUPT
|
||||
| SRS12_CARD_REMOVAL
|
||||
| SRS12_CARD_INSERTION);
|
||||
|
||||
/* Transfer the Command to the MMC device */
|
||||
send_mmc_cmd(cmd_arg, cmd_type, resp_type, CHECK_IF_CMD_SENT_POLL);
|
||||
|
||||
/* No responses for CMD 0,4,15 */
|
||||
if ((MMC_CMD_0_GO_IDLE_STATE != cmd_type) && (MMC_CMD_4_SET_DSR != cmd_type)
|
||||
&& (MMC_CMD_15_GOTO_INACTIVE_STATE != cmd_type))
|
||||
{
|
||||
trans_status_isr = MMC->SRS12;
|
||||
|
||||
if (SRS12_COMMAND_COMPLETE == (trans_status_isr & SRS12_COMMAND_COMPLETE))
|
||||
{
|
||||
/* If the response is an R1/B response */
|
||||
if ((MSS_MMC_RESPONSE_R1 == resp_type) || (MSS_MMC_RESPONSE_R1B == resp_type))
|
||||
{
|
||||
ret_status = response_1_parser();
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_status = TRANSFER_IF_SUCCESS;
|
||||
}
|
||||
}
|
||||
else if (SRS12_ERROR_INTERRUPT == (SRS12_ERROR_INTERRUPT & trans_status_isr))
|
||||
{
|
||||
ret_status = TRANSFER_IF_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_status = TRANSFER_IF_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_status = TRANSFER_IF_SUCCESS;
|
||||
}
|
||||
/* clear flags for the next time */
|
||||
MMC->SRS12 = ~(SRS12_CURRENT_LIMIT_ERROR
|
||||
| SRS12_CARD_INTERRUPT
|
||||
| SRS12_CARD_REMOVAL
|
||||
| SRS12_CARD_INSERTION);
|
||||
|
||||
return(ret_status);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* The send_mmc_cmd() function transfers the eMMC/SD command and argument to the
|
||||
* eMMC/SD device and waits until the core indicates that the command has been
|
||||
* transferred successfully.
|
||||
*/
|
||||
void send_mmc_cmd
|
||||
(
|
||||
uint32_t cmd_arg,
|
||||
uint32_t cmd_type,
|
||||
uint8_t resp_type,
|
||||
cmd_response_check_options cmd_option
|
||||
)
|
||||
{
|
||||
uint32_t command_information;
|
||||
uint32_t srs9, trans_status_isr;
|
||||
|
||||
/* check if command line is not busy */
|
||||
do
|
||||
{
|
||||
srs9 = MMC->SRS09;
|
||||
}while ((srs9 & SRS9_CMD_INHIBIT_CMD) != NO_CMD_INHIBIT);
|
||||
|
||||
command_information = process_request_checkresptype(resp_type);
|
||||
|
||||
MMC->SRS02 = cmd_arg;
|
||||
MMC->SRS03 = (uint32_t)((cmd_type << CMD_SHIFT) | command_information);
|
||||
|
||||
switch (cmd_option)
|
||||
{
|
||||
/* only need to wait around if expecting no response */
|
||||
case CHECK_IF_CMD_SENT_POLL:
|
||||
do
|
||||
{
|
||||
trans_status_isr = MMC->SRS12;
|
||||
}while (((SRS12_COMMAND_COMPLETE | SRS12_ERROR_INTERRUPT) & trans_status_isr) == MMC_CLEAR);
|
||||
break;
|
||||
case CHECK_IF_CMD_SENT_INT:
|
||||
break;
|
||||
case CHECK_IF_CMD_SENT_NO: /* use when expecting a response */
|
||||
/* No check- will be checked when response received */
|
||||
break;
|
||||
default:
|
||||
/* nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* The response_1_parser() returns the contents of the Card Status Register.
|
||||
* This function checks that none of the error fields are set within the CSR
|
||||
* and the status of the READY_FOR_DATA flag (Bit 8).
|
||||
*/
|
||||
static cif_response_t response_1_parser(void)
|
||||
{
|
||||
cif_response_t ret_status = TRANSFER_IF_FAIL;
|
||||
uint32_t response;
|
||||
|
||||
response = MMC->SRS04;
|
||||
if (MMC_CLEAR == (CARD_STATUS_ALL_ERRORS_MASK & response)) /* no error */
|
||||
{
|
||||
if ((CARD_STATUS_READY_FOR_DATA & response) != MMC_CLEAR)
|
||||
{
|
||||
ret_status = TRANSFER_IF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_status = DEVICE_BUSY;
|
||||
}
|
||||
}
|
||||
return(ret_status);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static uint32_t process_request_checkresptype(uint8_t responsetype)
|
||||
{
|
||||
uint32_t command_information;
|
||||
|
||||
/* check response type */
|
||||
switch (responsetype) {
|
||||
default:
|
||||
case MSS_MMC_RESPONSE_NO_RESP:
|
||||
command_information = (uint32_t)SRS3_NO_RESPONSE;
|
||||
break;
|
||||
case MSS_MMC_RESPONSE_R2:
|
||||
command_information = (uint32_t)(SRS3_RESP_LENGTH_136
|
||||
| SRS3_CRC_CHECK_EN);
|
||||
break;
|
||||
case MSS_MMC_RESPONSE_R3:
|
||||
case MSS_MMC_RESPONSE_R4:
|
||||
command_information = (uint32_t)SRS3_RESP_LENGTH_48;
|
||||
break;
|
||||
case MSS_MMC_RESPONSE_R1:
|
||||
case MSS_MMC_RESPONSE_R5:
|
||||
case MSS_MMC_RESPONSE_R6:
|
||||
case MSS_MMC_RESPONSE_R7:
|
||||
command_information = (uint32_t)(SRS3_RESP_LENGTH_48
|
||||
| SRS3_CRC_CHECK_EN
|
||||
| SRS3_INDEX_CHECK_EN);
|
||||
break;
|
||||
case MSS_MMC_RESPONSE_R1B:
|
||||
case MSS_MMC_RESPONSE_R5B:
|
||||
command_information = (uint32_t)(SRS3_RESP_LENGTH_48B
|
||||
| SRS3_CRC_CHECK_EN
|
||||
| SRS3_INDEX_CHECK_EN);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return (command_information);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
cif_response_t cif_send_cq_direct_command
|
||||
(
|
||||
uint8_t *desc_base_addr,
|
||||
uint32_t cmd_arg,
|
||||
uint32_t cmd_type,
|
||||
uint8_t resp_type,
|
||||
uint8_t task_id
|
||||
)
|
||||
{
|
||||
|
||||
uint32_t *dcmdTaskDesc;
|
||||
uint32_t flags;
|
||||
uint32_t desc_offset;
|
||||
uint32_t reg;
|
||||
uint32_t cmd_response;
|
||||
cif_response_t ret_status = TRANSFER_IF_FAIL;
|
||||
|
||||
/* Enable direct command */
|
||||
reg = MMC->CQRS02;
|
||||
reg |= (uint32_t)CQRS02_DIRECT_CMD_ENABLE;
|
||||
MMC->CQRS02 = reg;
|
||||
|
||||
desc_offset = CQ_HOST_NUMBER_OF_TASKS * task_id;
|
||||
|
||||
dcmdTaskDesc = (uint32_t *)(desc_base_addr + desc_offset);
|
||||
|
||||
/* first prepare general task flags */
|
||||
flags = (uint32_t)(CQ_DESC_VALID | CQ_DESC_END | CQ_DESC_ACT_TASK | CQ_DESC_INT);
|
||||
|
||||
/* now prepare direct command specific flags */
|
||||
flags |= ((cmd_type & 0x3FU) << SHIFT_16BIT);
|
||||
|
||||
switch (resp_type)
|
||||
{
|
||||
case MSS_MMC_RESPONSE_NO_RESP:
|
||||
flags |= (uint32_t)CQ_DESC_DCMD_RESP_TYPE_NO_RESP;
|
||||
break;
|
||||
case MSS_MMC_RESPONSE_R1:
|
||||
case MSS_MMC_RESPONSE_R4:
|
||||
case MSS_MMC_RESPONSE_R5:
|
||||
flags |= (uint32_t)CQ_DESC_DCMD_RESP_TYPE_R1_R4_R5;
|
||||
break;
|
||||
case MSS_MMC_RESPONSE_R1B:
|
||||
flags |= (uint32_t)CQ_DESC_DCMD_RESP_TYPE_R1B;
|
||||
break;
|
||||
default:
|
||||
/* nothing */
|
||||
break;
|
||||
}
|
||||
|
||||
flags |= (uint32_t)CQ_DESC_DCMD_CMD_TIMING;
|
||||
|
||||
dcmdTaskDesc[0] = flags;
|
||||
dcmdTaskDesc[1] = cmd_arg << SHIFT_16BIT;
|
||||
dcmdTaskDesc[2] = MMC_CLEAR;
|
||||
dcmdTaskDesc[3] = MMC_CLEAR;
|
||||
|
||||
dcmdTaskDesc[4] = (uint32_t)(CQ_DESC_VALID | CQ_DESC_END | CQ_DESC_ACT_NOP);
|
||||
dcmdTaskDesc[5] = MMC_CLEAR;
|
||||
dcmdTaskDesc[6] = MMC_CLEAR;
|
||||
dcmdTaskDesc[7] = MMC_CLEAR;
|
||||
|
||||
ret_status = cq_execute_task(task_id);
|
||||
|
||||
cmd_response = MMC->CQRS18;
|
||||
|
||||
reg = MMC->CQRS02;
|
||||
reg &= ~(uint32_t)CQRS02_DIRECT_CMD_ENABLE;
|
||||
MMC->CQRS02 = reg;
|
||||
|
||||
if (TRANSFER_IF_SUCCESS == ret_status)
|
||||
{
|
||||
if ((CARD_STATUS_ALL_ERRORS_MASK & cmd_response) == MMC_CLEAR) /* no error */
|
||||
{
|
||||
if ((CARD_STATUS_READY_FOR_DATA & cmd_response) != MMC_CLEAR)
|
||||
{
|
||||
ret_status = TRANSFER_IF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_status = DEVICE_BUSY;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret_status;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static cif_response_t cq_execute_task(uint8_t task_id)
|
||||
{
|
||||
|
||||
cif_response_t ret_status = TRANSFER_IF_FAIL;
|
||||
uint32_t reg;
|
||||
uint32_t trans_status_isr;
|
||||
uint32_t cmd_response;
|
||||
uint32_t value = DELAY_COUNT;
|
||||
|
||||
/* Set doorbell to start processing descriptors by controller */
|
||||
reg = MMC_SET << task_id;
|
||||
MMC->CQRS10 = reg;
|
||||
|
||||
while (value--);
|
||||
|
||||
do
|
||||
{
|
||||
trans_status_isr = MMC->SRS12;
|
||||
}while (((SRS12_ERROR_INTERRUPT | SRS12_CMD_QUEUING_INT) & trans_status_isr) == MMC_CLEAR);
|
||||
|
||||
if ((trans_status_isr & (SRS12_ERROR_INTERRUPT | SRS12_CMD_QUEUING_INT)) != MMC_CLEAR)
|
||||
{
|
||||
trans_status_isr = MMC->SRS12;
|
||||
MMC->SRS12 = trans_status_isr;
|
||||
|
||||
if ((trans_status_isr & SRS12_ERROR_INTERRUPT) != MMC_CLEAR)
|
||||
{
|
||||
ret_status = TRANSFER_IF_FAIL;
|
||||
}
|
||||
if ((trans_status_isr & SRS12_CMD_QUEUING_INT) != MMC_CLEAR)
|
||||
{
|
||||
reg = MMC->CQRS04;
|
||||
MMC->CQRS04 = reg;
|
||||
|
||||
if ((reg & CQRS04_RESP_ERR_INT) != MMC_CLEAR)
|
||||
{
|
||||
ret_status = TRANSFER_IF_FAIL;
|
||||
}
|
||||
|
||||
if ((reg & CQRS04_TASK_COMPLETE_INT) != MMC_CLEAR)
|
||||
{
|
||||
reg = MMC->CQRS11;
|
||||
/* clear all caught notifications */
|
||||
MMC->CQRS11 = reg;
|
||||
if (task_id == CQ_DCMD_TASK_ID)
|
||||
{
|
||||
if ((reg & (MMC_SET << task_id)) != MMC_CLEAR)
|
||||
{
|
||||
cmd_response = MMC->CQRS18;
|
||||
ret_status = TRANSFER_IF_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_status = TRANSFER_IF_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_status = TRANSFER_IF_FAIL;
|
||||
}
|
||||
return ret_status;
|
||||
}
|
||||
/******************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,161 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* PolarFire SoC MSS eMMC SD Interface Level Header File.
|
||||
*
|
||||
* This eMMC SD Interface header file provides access to functions which are
|
||||
* used to configure and program the eMMC/SD device to allow data transfers
|
||||
* to be performed with the eMMC/SD Host.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MSS_MMC_IF_H
|
||||
#define __MSS_MMC_IF_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Macro Definitions
|
||||
*/
|
||||
|
||||
#define CMD_SHIFT 24u
|
||||
#define NO_CMD_INHIBIT 0u
|
||||
|
||||
/***************************************************************************//**
|
||||
The cif_response type is used to specify the status of the eMMC/SD command
|
||||
transfer to the eMMC/SD device. A value of this type is returned by the
|
||||
cif_send_cmd() function.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
TRANSFER_IF_FAIL = 0u,
|
||||
TRANSFER_IF_SUCCESS = 1u,
|
||||
DEVICE_BUSY = 2u,
|
||||
} cif_response_t;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHECK_IF_CMD_SENT_POLL = 0u,
|
||||
CHECK_IF_CMD_SENT_INT = 1u,
|
||||
CHECK_IF_CMD_SENT_NO = 2u
|
||||
} cmd_response_check_options;
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
|
||||
The cif_send_cmd() function handles the interface level command and response
|
||||
data for communicating with the eMMC/SD device. This function issues
|
||||
configuration and control commands to the device, waits on the status register
|
||||
to update indicating that there was a response received (were expected) and
|
||||
parses the response to determine the successfulness of the transfer.
|
||||
|
||||
@param cmd_arg
|
||||
The cmd_arg parameter specifies the eMMC/SD argument to be passed to the
|
||||
eMMC/SD device.
|
||||
|
||||
@param cmd_type
|
||||
The cmd_type parameter specifies the eMMC/SD Command type to be passed to the
|
||||
eMMC/SD device.
|
||||
|
||||
@param resp_type
|
||||
The resp_type parameter specifies the eMMC/SD response type to be received from
|
||||
eMMC/SD device.
|
||||
|
||||
@return
|
||||
This function returns a value of type cif_response_t representing the
|
||||
successfulness of the transfer. If this return value indicates that the
|
||||
eMMC/SD device is busy, subsequent actions must be taken to ensure that a
|
||||
command is not issued until the device returns to idle.
|
||||
|
||||
Example:
|
||||
@code
|
||||
#define MMC_DW_CSD 0x03B70300u
|
||||
#define MMC_CMD_SWITCH 6u
|
||||
cif_response_t response_status;
|
||||
|
||||
response_status = cif_send_cmd(MMC_DW_CSD, MMC_CMD_SWITCH, MMC_RESPONSE_R1B);
|
||||
|
||||
while(DEVICE_BUSY == response_status)
|
||||
{
|
||||
response_status = cif_send_cmd(RCA_VALUE,
|
||||
MMC_CMD_13_SEND_STATUS,
|
||||
MMC_RESPONSE_R1);
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
cif_response_t cif_send_cmd
|
||||
(
|
||||
uint32_t cmd_arg,
|
||||
uint32_t cmd_type,
|
||||
uint8_t resp_type
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
|
||||
The send_mmc_cmd() function handles the interface level command and response
|
||||
data for communicating with the eMMC/SD device. This function issues
|
||||
configuration and control commands to the device, waits on the status register
|
||||
to update indicating that there was a response received (were expected) and
|
||||
parses the response to determine the successfulness of the transfer.
|
||||
|
||||
@param cmd_arg
|
||||
The cmd_arg parameter specifies the eMMC/SD argument to be passed to the
|
||||
eMMC/SD device.
|
||||
|
||||
@param cmd_type
|
||||
The cmd_type parameter specifies the eMMC/SD Command type to be passed to the
|
||||
eMMC/SD device.
|
||||
|
||||
@param resp_type
|
||||
The resp_type parameter specifies the eMMC/SD response type to be received from
|
||||
eMMC/SD device.
|
||||
|
||||
@param cmd_option
|
||||
The cmd_option parameter specifies if the function checks if eMMC/SD has sent
|
||||
the command or not before returning. There is no need to check if you are
|
||||
expecting a response, just check for the response.
|
||||
|
||||
@return
|
||||
This function returns a value of type cif_response_t representing the
|
||||
successfulness of the transfer. If this return value indicates that the
|
||||
eMMC/SD device is busy, subsequent actions must be taken to ensure that a
|
||||
command is not issued until the device returns to idle.
|
||||
|
||||
Example:
|
||||
@code
|
||||
|
||||
send_mmc_cmd(RCA_VALUE, MMC_CMD_13_SEND_STATUS, MMC_RESPONSE_R1, CHECK_IF_CMD_SENT_NO);
|
||||
@endcode
|
||||
*/
|
||||
void send_mmc_cmd
|
||||
(
|
||||
uint32_t cmd_arg,
|
||||
uint32_t cmd_type,
|
||||
uint8_t resp_type,
|
||||
cmd_response_check_options cmd_option
|
||||
);
|
||||
/******************************************************************************/
|
||||
cif_response_t cif_send_cq_direct_command
|
||||
(
|
||||
uint8_t *desc_base_addr,
|
||||
uint32_t cmd_arg,
|
||||
uint32_t cmd_type,
|
||||
uint8_t resp_type,
|
||||
uint8_t task_id
|
||||
);
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MSS_MMC_IF_H */
|
|
@ -0,0 +1,610 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* PolarFire SoC MSS eMMC SD driver API's for internal use cases.
|
||||
*
|
||||
*/
|
||||
/*=========================================================================*//**
|
||||
Note: The MSS_MMC_pause_sdma_write_hpi(), MSS_MMC_resume_sdma_write_hpi(),
|
||||
MSS_MMC_packed_read(), MSS_MMC_packed_write(), MSS_MMC_cq_single_task_write(),
|
||||
MSS_MMC_cq_single_task_read()functions provided purely for SVG use cases.
|
||||
|
||||
--------------------------------
|
||||
High Priority Interrupt
|
||||
--------------------------------
|
||||
The following functions are used for eMMC high priority interrupt operation:
|
||||
- MSS_MMC_pause_sdma_write_hpi()
|
||||
- MSS_MMC_resume_sdma_write_hpi()
|
||||
|
||||
To stop ongoing multiple block write transfers to the eMMC device using the
|
||||
high priority interrupt, a call is made to the MSS_MMC_pause_sdma_write_hpi()
|
||||
function.
|
||||
|
||||
To resume previously interrupted multiple block transfer of eMMC device,
|
||||
a call is made to the MSS_MMC_resume_sdma_write_hpi() function.
|
||||
|
||||
--------------------------------
|
||||
Packed Commands
|
||||
--------------------------------
|
||||
The following functions are used for eMMC packed command read and write:
|
||||
- MSS_MMC_packed_read()
|
||||
- MSS_MMC_packed_write()
|
||||
|
||||
To read several multiple blocks of data stored within the eMMC device using
|
||||
the packed group of read commands, a call is made to the MSS_MMC_packed_read()
|
||||
function, specifying the base address of the buffer holding the data of the
|
||||
packed command header block and the base address of buffer where the data
|
||||
read from the eMMC device will be stored.
|
||||
|
||||
To write several multiple blocks of data to the eMMC device using the packed
|
||||
group of write commands, a call is made to the MSS_MMC_packed_write()
|
||||
function, specifying the base address of the buffer holding the data of the
|
||||
packed command header block and the base address of buffer containing the
|
||||
data blocks to be stored into the eMMC device.
|
||||
|
||||
--------------------------------
|
||||
Command Queue
|
||||
--------------------------------
|
||||
The following functions are used for eMMC command queue single task operation:
|
||||
- MSS_MMC_cq_single_task_write()
|
||||
- MSS_MMC_cq_single_task_read()
|
||||
|
||||
To write a single block or multiple blocks of data to the eMMC device using
|
||||
a command queue, a call is made to the MSS_MMC_cq_single_task_write()
|
||||
function. This function supports a single task only.
|
||||
|
||||
To read a single block or multiple blocks of data stored within the eMMC
|
||||
device using a command queue, a call is made to the
|
||||
MSS_MMC_cq_single_task_read() function. This function supports a single task
|
||||
only.
|
||||
|
||||
*//*=========================================================================*/
|
||||
#ifndef __MSS_MMC_INTERNAL_API_H
|
||||
#define __MSS_MMC_INTERNAL_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_MMC_pause_sdma_write_hpi() function is used to pause the ongoing SDMA
|
||||
write transfer using the eMMC high priority interrupt (HPI).
|
||||
|
||||
Note: This MSS_MMC_pause_sdma_write_hpi()function has parameters provided
|
||||
purely for svg use case. if this function in production release then we
|
||||
should remove the need for parameters.
|
||||
|
||||
@param src
|
||||
This parameter is a pointer to a buffer containing actual the data to be
|
||||
stored in the eMMC device. The src parameter must be identical to the src
|
||||
parameter of the MSS_MMC_sdma_write() function.
|
||||
|
||||
@param dest
|
||||
This parameter specifies the sector address in the eMMC device where the block
|
||||
is to be stored. The dest parameter must be identical to the dest parameter of
|
||||
the MSS_MMC_sdma_write() function.
|
||||
|
||||
@param size
|
||||
The parameter size specifies the size in bytes of the requested transfer.
|
||||
The size parameter must be identical to the size parameter of the
|
||||
MSS_MMC_sdma_write() function.
|
||||
|
||||
@return
|
||||
This function returns a value of type mss_mmc_status_t which specifies the
|
||||
transfer status of the operation.
|
||||
|
||||
Example:
|
||||
The following example shows how to initialize the device and perform an HPI
|
||||
|
||||
@code
|
||||
|
||||
#define SECT_1 0x01u
|
||||
#define BUFFER_SIZE 4096u
|
||||
|
||||
mss_mmc_cfg_t g_mmc0;
|
||||
mss_mmc_status_t ret_status;
|
||||
uint8_t data_buffer[BUFFER_SIZE];
|
||||
uint32_t loop_count;
|
||||
|
||||
g_mmc0.clk_rate = MSS_MMC_CLOCK_25MHZ;
|
||||
g_mmc0.card_type = MSS_MMC_CARD_TYPE_MMC;
|
||||
g_mmc0.data_bus_width = MSS_MMC_DATA_WIDTH_4BIT;
|
||||
g_mmc0.bus_speed_mode = MSS_MMC_MODE_LEGACY;
|
||||
g_mmc0.bus_voltage = MSS_MMC_3_3V_BUS_VOLTAGE;
|
||||
|
||||
for (loop_count = 0; loop_count < (BUFFER_SIZE); loop_count++)
|
||||
{
|
||||
data_buffer[loop_count] = 0x45 + loop_count;
|
||||
}
|
||||
|
||||
ret_status = MSS_MMC_init(&g_mmc0);
|
||||
if (MSS_MMC_INIT_SUCCESS == ret_status)
|
||||
{
|
||||
ret_status = MSS_MMC_sdma_write(data_buffer, SECT_1, BUFFER_SIZE);
|
||||
if(ret_status == MSS_MMC_TRANSFER_IN_PROGRESS)
|
||||
{
|
||||
ret_status = MSS_MMC_pause_sdma_write_hpi(data_buffer, SECT_1,
|
||||
BUFFER_SIZE);
|
||||
if(ret_status == MSS_MMC_TRANSFER_SUCCESS)
|
||||
{
|
||||
//..
|
||||
}
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
mss_mmc_status_t
|
||||
MSS_MMC_pause_sdma_write_hpi
|
||||
(
|
||||
const uint8_t *src,
|
||||
uint32_t dest,
|
||||
uint32_t size
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_MMC_resume_sdma_write_hpi() function is used to resume writing the
|
||||
remaining blocks to the target device which was previously interrupted by
|
||||
a call to MSS_MMC_pause_sdma_write_hpi().
|
||||
|
||||
@param
|
||||
This function has no parameters.
|
||||
|
||||
@return
|
||||
This function returns a value of type mss_mmc_status_t which specifies the
|
||||
transfer status of the operation.
|
||||
|
||||
Example:
|
||||
The following example shows how to initialize the device and perform a HPI
|
||||
interrupt and resume remaining block operation.
|
||||
|
||||
@code
|
||||
|
||||
#define SECT_1 0x01u
|
||||
#define BUFFER_SIZE 4096u
|
||||
|
||||
mss_mmc_cfg_t g_mmc0;
|
||||
mss_mmc_status_t ret_status;
|
||||
uint8_t data_buffer[BUFFER_SIZE];
|
||||
uint32_t loop_count;
|
||||
|
||||
g_mmc0.clk_rate = MSS_MMC_CLOCK_25MHZ;
|
||||
g_mmc0.card_type = MSS_MMC_CARD_TYPE_MMC;
|
||||
g_mmc0.data_bus_width = MSS_MMC_DATA_WIDTH_4BIT;
|
||||
g_mmc0.bus_speed_mode = MSS_MMC_MODE_LEGACY;
|
||||
g_mmc0.bus_voltage = MSS_MMC_3_3V_BUS_VOLTAGE;
|
||||
|
||||
for (loop_count = 0; loop_count < (BUFFER_SIZE); loop_count++)
|
||||
{
|
||||
data_buffer[loop_count] = 0x45 + loop_count;
|
||||
}
|
||||
|
||||
ret_status = MSS_MMC_init(&g_mmc0);
|
||||
if (MSS_MMC_INIT_SUCCESS == ret_status)
|
||||
{
|
||||
ret_status = MSS_MMC_sdma_write(data_buffer, SECT_1, BUFFER_SIZE);
|
||||
if(ret_status == MSS_MMC_TRANSFER_IN_PROGRESS)
|
||||
{
|
||||
ret_status = MSS_MMC_pause_sdma_write_hpi(data_buffer, SECT_1,
|
||||
BUFFER_SIZE);
|
||||
if(ret_status == MSS_MMC_TRANSFER_SUCCESS)
|
||||
{
|
||||
ret_status = MSS_MMC_resume_sdma_write_hpi();
|
||||
if(ret_status == MSS_MMC_TRANSFER_IN_PROGRESS)
|
||||
{
|
||||
do
|
||||
{
|
||||
ret_status = MSS_MMC_get_transfer_status();
|
||||
}while(ret_status == MSS_MMC_TRANSFER_IN_PROGRESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
mss_mmc_status_t MSS_MMC_resume_sdma_write_hpi(void);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_MMC_packed_write() function is used to transmit a packed group of data
|
||||
from the host to the eMMC device. The write commands can be packed in a group
|
||||
of commands (all write) that transfer the data for all commands in the group
|
||||
in one transfer on the bus.
|
||||
Note : This function is a non-blocking function and returns immediately after
|
||||
initiating the write transfer.
|
||||
|
||||
@param src
|
||||
This parameter is a pointer to a buffer containing the data blocks to be
|
||||
stored in the eMMC device. The first block containing the packed-command
|
||||
header and all data sectors of the individual packed commands are appended
|
||||
together after the header.
|
||||
|
||||
@param dest
|
||||
Specifies the sector address in the eMMC device where the block is to be
|
||||
stored. The dest shall be the same address that is specified by the first
|
||||
individual write command in the packed group.
|
||||
|
||||
@param size
|
||||
Specifies the size in bytes of the requested transfer. The value of size must
|
||||
be a multiple of 512. The size parameter shall be the sum of all block counts
|
||||
of the individual writes plus one for the header.
|
||||
|
||||
@return
|
||||
This function returns a value of type mss_mmc_status_t which specifies the
|
||||
transfer status of the operation.
|
||||
|
||||
Example:
|
||||
This example shows how to initialize the device and perform a packed write
|
||||
transfer.
|
||||
@code
|
||||
|
||||
#define SECT_9 0x09u
|
||||
#define BUFFER_SIZE 4096u
|
||||
|
||||
mss_mmc_cfg_t g_mmc0;
|
||||
mss_mmc_status_t ret_status;
|
||||
uint8_t data_buffer[BUFFER_SIZE];
|
||||
uint32_t loop_count;
|
||||
uint8_t packed_write[512];
|
||||
|
||||
g_mmc0.clk_rate = MSS_MMC_CLOCK_25MHZ;
|
||||
g_mmc0.card_type = MSS_MMC_CARD_TYPE_MMC;
|
||||
g_mmc0.data_bus_width = MSS_MMC_DATA_WIDTH_4BIT;
|
||||
g_mmc0.bus_speed_mode = MSS_MMC_MODE_LEGACY;
|
||||
g_mmc0.bus_voltage = MSS_MMC_3_3V_BUS_VOLTAGE;
|
||||
|
||||
packed_write[0] = 0x01; // version
|
||||
packed_write[1] = 0x02; // 0x2 - write
|
||||
packed_write[2] = 0x02; // no of entries
|
||||
packed_write[3] = 0x00;
|
||||
packed_write[4] = 0x00;
|
||||
packed_write[5] = 0x00;
|
||||
packed_write[6] = 0x00;
|
||||
packed_write[7] = 0x00;
|
||||
packed_write[8] = 0x04; // CMD23 arg1 - 4 blocks
|
||||
packed_write[9] = 0x00;
|
||||
packed_write[10] = 0x00;
|
||||
packed_write[11] = 0x00;
|
||||
packed_write[12] = 0x09; // CMD25 arg1 - sector no 9
|
||||
packed_write[13] = 0x00;
|
||||
packed_write[14] = 0x00;
|
||||
packed_write[15] = 0x00;
|
||||
packed_write[16] = 0x04; // CMD23 arg2 - 4-blocks
|
||||
packed_write[17] = 0x00;
|
||||
packed_write[18] = 0x00;
|
||||
packed_write[19] = 0x00;
|
||||
packed_write[20] = 0x29; // CMD25 agr2 - sector no 0x29
|
||||
packed_write[21] = 0x00;
|
||||
packed_write[22] = 0x00;
|
||||
packed_write[23] = 0x00;
|
||||
|
||||
for (loop_count = 24; loop_count < 512; loop_count++)
|
||||
{
|
||||
packed_write[loop_count] = 0;
|
||||
}
|
||||
for (loop_count = 0; loop_count < (BUFFER_SIZE); loop_count++)
|
||||
{
|
||||
data_buffer[loop_count] = 0x45 + loop_count;
|
||||
}
|
||||
// packed header block
|
||||
for (loop_count = 0; loop_count < 512; loop_count++)
|
||||
{
|
||||
data_buffer[loop_count] = packed_write[loop_count];
|
||||
}
|
||||
resp_reg = MMC_init(&g_mmc0);
|
||||
if (MSS_MMC_INIT_SUCCESS == ret_status)
|
||||
{
|
||||
ret_status = MSS_MMC_packed_write(data_buffer, SECT_9, BUFFER_SIZE);
|
||||
if (ret_status == MSS_MMC_TRANSFER_IN_PROGRESS)
|
||||
{
|
||||
do
|
||||
{
|
||||
ret_status = MSS_MMC_get_transfer_status();
|
||||
}while (ret_status == MSS_MMC_TRANSFER_IN_PROGRESS)
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
mss_mmc_status_t
|
||||
MSS_MMC_packed_write
|
||||
(
|
||||
const uint8_t *src,
|
||||
uint32_t dest,
|
||||
uint32_t size
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_MMC_packed_read() function is used to read several multiple block of
|
||||
data from the device to the host using packed group. The read commands can be
|
||||
packed in group of commands (all read) that transfer the data for all commands
|
||||
in the group in one transfer on the bus.
|
||||
Note : This function is a non-blocking function and returns immediately after
|
||||
initiating the block transfer.
|
||||
|
||||
@param src
|
||||
Specifies the sector address in the eMMC device where the block is to be read.
|
||||
The src shall be the same address that is specified by the first individual
|
||||
read command in the packed group.
|
||||
|
||||
@param dest
|
||||
This parameter is a pointer to a buffer where the data read from the eMMC
|
||||
device will be stored. The buffer to which this parameter points should be
|
||||
declared with a minimum size of 512 bytes.
|
||||
|
||||
@param packed_header
|
||||
This parameter is a pointer to a buffer containing the packed-command header
|
||||
block.
|
||||
|
||||
@param size
|
||||
Specifies the size in bytes of the requested transfer. The value of size must
|
||||
be a multiple of 512. The size parameter shall be the sum of all block counts
|
||||
of the individual read.
|
||||
|
||||
@return
|
||||
This function returns a value of type mss_mmc_status_t which specifies the
|
||||
transfer status of the operation.
|
||||
|
||||
Example:
|
||||
This example shows how to initialize the device and perform a packed read
|
||||
transfer.
|
||||
|
||||
@code
|
||||
|
||||
#define SECT_9 0x09u
|
||||
#define BUFFER_SIZE 4096u
|
||||
|
||||
mss_mmc_cfg_t g_mmc0;
|
||||
mss_mmc_status_t ret_status;
|
||||
uint8_t data_buffer[BUFFER_SIZE];
|
||||
uint32_t loop_count;
|
||||
uint8_t packed_read[512];
|
||||
|
||||
g_mmc0.clk_rate = MSS_MMC_CLOCK_25MHZ;
|
||||
g_mmc0.card_type = MSS_MMC_CARD_TYPE_MMC;
|
||||
g_mmc0.data_bus_width = MSS_MMC_DATA_WIDTH_4BIT;
|
||||
g_mmc0.bus_speed_mode = MSS_MMC_MODE_LEGACY;
|
||||
g_mmc0.bus_voltage = MSS_MMC_3_3V_BUS_VOLTAGE;
|
||||
|
||||
packed_read[0] = 0x01; // version
|
||||
packed_read[1] = 0x02; // 0x1 - read
|
||||
packed_read[2] = 0x02; // no of entries
|
||||
packed_read[3] = 0x00;
|
||||
packed_read[4] = 0x00;
|
||||
packed_read[5] = 0x00;
|
||||
packed_read[6] = 0x00;
|
||||
packed_read[7] = 0x00;
|
||||
packed_read[8] = 0x04; // CMD23 arg1 - 4 blocks
|
||||
packed_read[9] = 0x00;
|
||||
packed_read[10] = 0x00;
|
||||
packed_read[11] = 0x00;
|
||||
packed_read[12] = 0x09; // CMD18 arg1 - sector no 9
|
||||
packed_read[13] = 0x00;
|
||||
packed_read[14] = 0x00;
|
||||
packed_read[15] = 0x00;
|
||||
packed_read[16] = 0x04; // CMD23 arg2 - 4-blocks
|
||||
packed_read[17] = 0x00;
|
||||
packed_read[18] = 0x00;
|
||||
packed_read[19] = 0x00;
|
||||
packed_read[20] = 0x29; // CMD18 agr2 - sector no 0x29
|
||||
packed_read[21] = 0x00;
|
||||
packed_read[22] = 0x00;
|
||||
packed_read[23] = 0x00;
|
||||
for(loop_count = 24; loop_count < 512; loop_count++)
|
||||
{
|
||||
packed_read[loop_count] = 0;
|
||||
}
|
||||
for(loop_count = 0; loop_count < (BUFFER_SIZE); loop_count++)
|
||||
{
|
||||
data_buffer[loop_count] = = 0x00;
|
||||
}
|
||||
resp_reg = MMC_init(&g_mmc0);
|
||||
if (MSS_MMC_INIT_SUCCESS == ret_status)
|
||||
{
|
||||
ret_status = MSS_MMC_packed_read(SECT_9, data_buffer,
|
||||
(uint32 *)packed_read, BUFFER_SIZE);
|
||||
if (ret_status == MSS_MMC_TRANSFER_IN_PROGRESS)
|
||||
{
|
||||
do
|
||||
{
|
||||
ret_status = MSS_MMC_get_transfer_status();
|
||||
}while (ret_status == MSS_MMC_TRANSFER_IN_PROGRESS)
|
||||
}
|
||||
}
|
||||
|
||||
@endcode
|
||||
*/
|
||||
mss_mmc_status_t
|
||||
MSS_MMC_packed_read
|
||||
(
|
||||
uint32_t src,
|
||||
uint8_t *dest,
|
||||
uint32_t *packed_header,
|
||||
uint32_t size
|
||||
);
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_MMC_cq_single_task_write() function is used to transmit a single block
|
||||
or multiple blocks of data from the host controller to the eMMC device using
|
||||
command queue with single task based on the data size. The size of the block
|
||||
of data transferred by this function must be set to 512 bytes or a multiple of
|
||||
512 bytes. The 512 bytes is the standard sector size for all eMMC
|
||||
devices with a capacity of greater than 2 GB.
|
||||
|
||||
Note: A call to MSS_MMC_cq_single_task_write() while a transfer is in
|
||||
progress will not initiate a new transfer. Use the MSS_MMC_get_transfer_status()
|
||||
function or a completion handler registered by the MSS_MMC_set_handler()
|
||||
function to check the status of the current transfer before calling the
|
||||
MSS_MMC_cq_single_task_write() function again.
|
||||
|
||||
Note: This function is a non-blocking function and returns immediately after
|
||||
initiating the write transfer.
|
||||
|
||||
Note: This MSS_MMC_cq_single_task_write() and MSS_MMC_cq_single_task_read()
|
||||
functions are provided purely for svg use case. For production release we
|
||||
will remove.
|
||||
|
||||
@param src
|
||||
This parameter is a pointer to a buffer containing the data to be stored
|
||||
in the eMMC device. The buffer to which this parameter points must be
|
||||
declared with a minimum size of 512 bytes.
|
||||
|
||||
@param dest
|
||||
Specifies the sector address in the eMMC device where the data is
|
||||
to be stored.
|
||||
Note: For eMMC devices of greater than 2 GB in size, this address refers to a
|
||||
512 byte sector.
|
||||
|
||||
@param task_id
|
||||
Specifies the eMMC command queue task id number 0 to 31
|
||||
|
||||
@param size
|
||||
Specifies the size in bytes of the requested transfer. The value of size must
|
||||
be a multiple of 512 but not greater than (32MB - 512).
|
||||
|
||||
@return
|
||||
This function returns a value of type mss_mmc_status_t which specifies the
|
||||
transfer status of the operation.
|
||||
|
||||
Example:
|
||||
The following example shows how to initialize the device and perform a multi
|
||||
block transfer..
|
||||
@code
|
||||
|
||||
#define SECT_1 0x01u
|
||||
#define BUFFER_SIZE 4096u
|
||||
#define TASK_ID 0x01
|
||||
|
||||
mss_mmc_cfg_t g_mmc0;
|
||||
mss_mmc_status_t ret_status;
|
||||
uint8_t data_buffer[BUFFER_SIZE];
|
||||
uint32_t loop_count;
|
||||
|
||||
g_mmc0.clk_rate = MSS_MMC_CLOCK_25MHZ;
|
||||
g_mmc0.card_type = MSS_MMC_CARD_TYPE_MMC;
|
||||
g_mmc0.data_bus_width = MSS_MMC_DATA_WIDTH_4BIT;
|
||||
g_mmc0.bus_speed_mode = MSS_MMC_MODE_LEGACY;
|
||||
g_mmc0.bus_voltage = MSS_MMC_3_3V_BUS_VOLTAGE;
|
||||
|
||||
for (loop_count = 0; loop_count < (BUFFER_SIZE); loop_count++)
|
||||
{
|
||||
data_buffer[loop_count] = 0x45 + loop_count;
|
||||
}
|
||||
|
||||
ret_status = MSS_MMC_init(&g_mmc0);
|
||||
if (MSS_MMC_INIT_SUCCESS == ret_status)
|
||||
{
|
||||
ret_status = MSS_MMC_cq_init();
|
||||
if ( MSS_MMC_INIT_SUCCESS == ret_status)
|
||||
{
|
||||
ret_status = MSS_MMC_cq_single_task_write(data_buffer, SECT_1,
|
||||
TASK_ID, BUFFER_SIZE);
|
||||
do
|
||||
{
|
||||
ret_status = MSS_MMC_get_transfer_status();
|
||||
}while (ret_status == MSS_MMC_TRANSFER_IN_PROGRESS)
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
mss_mmc_status_t
|
||||
MSS_MMC_cq_single_task_write
|
||||
(
|
||||
const uint8_t *src,
|
||||
uint32_t dest,
|
||||
uint8_t task_id,
|
||||
uint32_t size
|
||||
);
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_MMC_cq_single_task_read() function is used to read a single or
|
||||
multiple blocks of data from the eMMC device to the host controller using
|
||||
command queue with single task based on the data size. The size of the block
|
||||
of data read by this function must be set to 512 bytes or a multiple of
|
||||
512 bytes. The 512 bytes is the standard sector size for all eMMC devices
|
||||
with a capacity of greater than 2 GB.
|
||||
|
||||
Note: A call to MSS_MMC_cq_single_task_read() while a transfer is in progress
|
||||
will not initiate a new transfer. Use the MSS_MMC_get_transfer_status()
|
||||
function or a completion handler registered by the MSS_MMC_set_handler()
|
||||
function to check the status of the current transfer before calling the
|
||||
MSS_MMC_cq_single_task_read() function again.
|
||||
|
||||
Note: This function is a non-blocking function and returns immediately after
|
||||
initiating the write transfer.
|
||||
|
||||
@param src
|
||||
Specifies the sector address in the eMMC device from where the data is
|
||||
to be read.
|
||||
Note: For eMMC devices of greater than 2 GB in size, this address refers
|
||||
to a 512-byte sector.
|
||||
|
||||
@param dest
|
||||
This parameter is a pointer to a buffer where the data to read from the eMMC
|
||||
device will be stored. The buffer to which this parameter points must be
|
||||
declared with a minimum size of 512 bytes.
|
||||
|
||||
@param task_id
|
||||
Specifies the eMMC command queue task id number 0 to 31
|
||||
|
||||
@param size
|
||||
Specifies the size in bytes of the requested transfer. The value of size must
|
||||
be a multiple of 512 but not greater than (32MB - 512).
|
||||
|
||||
@return
|
||||
This function returns a value of type mss_mmc_status_t which specifies the
|
||||
transfer status of the operation.
|
||||
|
||||
Example:
|
||||
The following example shows how to initialize the device and perform a multi
|
||||
block transfer.
|
||||
|
||||
@code
|
||||
|
||||
#define SECT_1 0x01u
|
||||
#define BUFFER_SIZE 4096u
|
||||
#define TASK_ID 0x02
|
||||
|
||||
mss_mmc_cfg_t g_mmc0;
|
||||
mss_mmc_status_t ret_status;
|
||||
uint8_t data_buffer[BUFFER_SIZE];
|
||||
uint32_t loop_count;
|
||||
|
||||
g_mmc0.clk_rate = MSS_MMC_CLOCK_25MHZ;
|
||||
g_mmc0.card_type = MSS_MMC_CARD_TYPE_MMC;
|
||||
g_mmc0.data_bus_width = MSS_MMC_DATA_WIDTH_4BIT;
|
||||
g_mmc0.bus_speed_mode = MSS_MMC_MODE_LEGACY;
|
||||
g_mmc0.bus_voltage = MSS_MMC_3_3V_BUS_VOLTAGE;
|
||||
|
||||
for (loop_count = 0; loop_count < (BUFFER_SIZE); loop_count++)
|
||||
{
|
||||
data_buffer[loop_count] = 0x45 + loop_count;
|
||||
}
|
||||
|
||||
ret_status = MSS_MMC_init(&g_mmc0);
|
||||
if (MSS_MMC_INIT_SUCCESS == ret_status)
|
||||
{
|
||||
ret_status = MSS_MMC_cq_init();
|
||||
if (MSS_MMC_INIT_SUCCESS == ret_status)
|
||||
{
|
||||
ret_status = MSS_MMC_cq_single_task_read(SECT_1, data_buffer,
|
||||
TASK_ID, BUFFER_SIZE);
|
||||
do
|
||||
{
|
||||
ret_status = MSS_MMC_get_transfer_status();
|
||||
}while (ret_status == MSS_MMC_TRANSFER_IN_PROGRESS)
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
mss_mmc_status_t
|
||||
MSS_MMC_cq_single_task_read
|
||||
(
|
||||
uint32_t src,
|
||||
uint8_t *dest,
|
||||
uint8_t task_id,
|
||||
uint32_t size
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MSS_MMC_INTERNAL_API_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,242 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* PolarFire SoC MSS eMMC SD driver data structures.
|
||||
*
|
||||
* This eMMC Interface header file provides a subset of definitions from the eMMC
|
||||
* protocol JESD84-B51
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MSS_MMC_TYPE_H
|
||||
#define __MSS_MMC_TYPE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Macro Definitions
|
||||
*/
|
||||
|
||||
/* MMC/SD/SDIO commands */
|
||||
|
||||
#define MMC_CMD_15_GOTO_INACTIVE_STATE 15u /* No Rsp */
|
||||
#define MMC_CMD_4_SET_DSR 4u /* No Rsp */
|
||||
#define MMC_CMD_0_GO_IDLE_STATE 0u /* No Rsp */
|
||||
#define MMC_CMD_6_SWITCH 6u /* R1b Rsp */
|
||||
#define MMC_CMD_7_SELECT_DESELECT_CARD 7u /* R1/R1b Rsp */
|
||||
|
||||
#define MMC_CMD_3_SET_RELATIVE_ADDR 3u /* R1 Rsp */
|
||||
#define MMC_CMD_17_READ_SINGLE_BLOCK 17u /* R1 Rsp */
|
||||
#define MMC_CMD_18_READ_MULTIPLE_BLOCK 18u /* R1 Rsp */
|
||||
#define MMC_CMD_24_WRITE_SINGLE_BLOCK 24u /* R1 Rsp */
|
||||
#define MMC_CMD_23_SET_BLOCK_COUNT 23u /* R1 Rsp */
|
||||
#define MMC_CMD_25_WRITE_MULTI_BLOCK 25u /* R1 Rsp */
|
||||
#define MMC_CMD_13_SEND_STATUS 13u /* R1 Rsp */
|
||||
#define MMC_CMD_12_STOP_TRANSMISSION 12u /* R1/R1b Rsp */
|
||||
#define MMC_CMD_8_SEND_EXT_CSD 8u /* R1 Rsp */
|
||||
#define MMC_CMD_21_SEND_TUNE_BLK 21u /* R1 Rsp */
|
||||
|
||||
#define MMC_CMD_14_BUSTEST_R 14u /* R1 Rsp */
|
||||
#define MMC_CMD_19_BUSTEST_W 19u /* R1 Rsp */
|
||||
|
||||
#define MMC_CMD_2_ALL_SEND_CID 2u /* R2 Rsp */
|
||||
#define MMC_CMD_9_SEND_CSD 9u /* R2 Rsp */
|
||||
#define MMC_CMD_10_SEND_CID 10u /* R2 Rsp */
|
||||
#define MMC_CMD_1_SEND_OP_COND 1u /* R3 Rsp */
|
||||
#define MMC_CMD_39_FAST_IO 39u /* R4 Rsp */
|
||||
#define MMC_CMD_40_GO_IRQ_STATE 40u /* R5 Rsp */
|
||||
|
||||
#define SD_CMD_8_SEND_IF_COND 8u /* R7 Rsp */
|
||||
#define SD_ACMD_41_SEND_OP_COND 41u /* R3 Rsp */
|
||||
#define SD_ACMD_42_SET_CLR_CARD_DETECT 42u /* R1 Rsp */
|
||||
|
||||
#define SD_CMD_11_VOLAGE_SWITCH 11u /* R1 Rsp */
|
||||
#define SD_CMD_19_SEND_TUNING_BLK 19u /* R1 Rsp */
|
||||
#define SD_CMD_55 55u
|
||||
|
||||
#define SD_CMD_5 5u /* R4 Rsp */
|
||||
#define SD_ACMD_6 6u /* R1 Rsp */
|
||||
#define SD_ACMD_51 51u /* R1 Rsp */
|
||||
#define SD_CMD_6 6u /* R1 Rsp */
|
||||
#define SD_CMD_16 16u /* R1 Rsp */
|
||||
|
||||
#define SDIO_CMD_52_IO_RW_DIRECT 52u /*R5 Rsp */
|
||||
#define SDIO_CMD_53_IO_RW_EXTENDED 53u /*R5 Rsp */
|
||||
|
||||
/* eMMC/SD Response Type */
|
||||
typedef enum
|
||||
{
|
||||
MSS_MMC_RESPONSE_NO_RESP = 0u,
|
||||
MSS_MMC_RESPONSE_R1 = 1u,
|
||||
MSS_MMC_RESPONSE_R1B = 2u,
|
||||
MSS_MMC_RESPONSE_R2 = 3u,
|
||||
MSS_MMC_RESPONSE_R3 = 4u,
|
||||
MSS_MMC_RESPONSE_R4 = 5u,
|
||||
MSS_MMC_RESPONSE_R5 = 6u,
|
||||
MSS_MMC_RESPONSE_R5B = 7u,
|
||||
MSS_MMC_RESPONSE_R6 = 8u,
|
||||
MSS_MMC_RESPONSE_R7 = 9u,
|
||||
MSS_MMC_RESPONSE_R1A = 10u
|
||||
} MSS_MMC_response_type;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* access mode - SDR12 default (CLK: max 25MHz, DT: max 12MB/s) */
|
||||
MSS_MMC_ACCESS_MODE_SDR12 = 0u,
|
||||
/* access mode - SDR15 default (CLK: max 50MHz, DT: max 25MB/s) */
|
||||
MSS_MMC_ACCESS_MODE_SDR25 = 1u,
|
||||
/* access mode - SDR50 default (CLK: max 100MHz, DT: max 50MB/s) */
|
||||
MSS_MMC_ACCESS_MODE_SDR50 = 2u,
|
||||
/* access mode - SDR104 default (CLK: max 208MHz, DT: max 104MB/s) */
|
||||
MSS_MMC_ACCESS_MODE_SDR104 = 3u,
|
||||
/* access mode - DDR50 default (CLK: max 50MHz, DT: max 50MB/s) */
|
||||
MSS_MMC_ACCESS_MODE_DDR50 = 4u,
|
||||
/* access mode - ultra high speed II mode */
|
||||
MSS_MMC_ACCESS_MODE_UHSII = 5u,
|
||||
/* MMC access mode - legacy mode (CLK: max 26MHz, DT: max 26MB/s) */
|
||||
MSS_MMC_ACCESS_MODE_MMC_LEGACY = 6u,
|
||||
/* MMC access mode - high speed SDR mode (CLK: max 26MHz, DT: max 26MB/s) */
|
||||
MSS_MMC_ACCESS_MODE_HS_SDR = 7u,
|
||||
/* MMC access mode - high speed DDR mode (CLK: max 52MHz, DT: max 104MB/s) */
|
||||
MSS_MMC_ACCESS_MODE_HS_DDR = 8u,
|
||||
/* MMC access mode - HS200 mode (CLK: max 200MHz, DT: max 200MB/s) */
|
||||
MSS_MMC_ACCESS_MODE_HS_200 = 9u,
|
||||
/* MMC access mode - HS400 mode (CLK: max 200MHz, DT: max 400MB/s) */
|
||||
MSS_MMC_ACCESS_MODE_HS_400 = 10u,
|
||||
/* MMC access mode - HS400 using Enhanced Strobe (CLK: max 200MHz, DT: max 400MB/s) */
|
||||
MSS_MMC_ACCESS_MODE_HS_400_ES = 11u,
|
||||
} MSS_MMC_speed_mode;
|
||||
|
||||
/* PHY configuration delay type */
|
||||
typedef enum
|
||||
{
|
||||
/* delay in the input path for High Speed work mode */
|
||||
MSS_MMC_PHY_DELAY_INPUT_HIGH_SPEED = 0u,
|
||||
/* delay in the input path for Default Speed work mode */
|
||||
MSS_MMC_PHY_DELAY_INPUT_DEFAULT_SPEED = 1u,
|
||||
/* delay in the input path for SDR12 work mode */
|
||||
MSS_MMC_PHY_DELAY_INPUT_SDR12 = 2u,
|
||||
/* delay in the input path for SDR25 work mode */
|
||||
MSS_MMC_PHY_DELAY_INPUT_SDR25 = 3u,
|
||||
/* delay in the input path for SDR50 work mode */
|
||||
MSS_MMC_PHY_DELAY_INPUT_SDR50 = 4u,
|
||||
/* delay in the input path for DDR50 work mode */
|
||||
MSS_MMC_PHY_DELAY_INPUT_DDR50 = 5u,
|
||||
/* delay in the input path for eMMC legacy work mode */
|
||||
MSS_MMC_PHY_DELAY_INPUT_MMC_LEGACY = 6u,
|
||||
/* delay in the input path for eMMC SDR work mode */
|
||||
MSS_MMC_PHY_DELAY_INPUT_MMC_SDR = 7u,
|
||||
/* delay in the input path for eMMC DDR work mode */
|
||||
MSS_MMC_PHY_DELAY_INPUT_MMC_DDR = 8u,
|
||||
/* Value of the delay introduced on the sdclk output for all modes except
|
||||
* HS200, HS400 and HS400_ES
|
||||
*/
|
||||
MSS_MMC_PHY_DELAY_DLL_SDCLK = 11u,
|
||||
/* Value of the delay introduced on the sdclk output for HS200, HS400 and
|
||||
* HS400_ES speed mode
|
||||
*/
|
||||
MSS_MMC_PHY_DELAY_DLL_HS_SDCLK = 12u,
|
||||
/* Value of the delay introduced on the dat_strobe input used in
|
||||
* HS400 / HS400_ES speed mode.
|
||||
*/
|
||||
MSS_MMC_PHY_DELAY_DLL_DAT_STROBE = 13u,
|
||||
} MSS_MMC_phydelay;
|
||||
|
||||
/**********************************************************************
|
||||
* Enumerations
|
||||
**********************************************************************/
|
||||
/* CCCR card control registers definitions */
|
||||
typedef enum
|
||||
{
|
||||
/* CCCR version number and SDIO specification version number register */
|
||||
MSS_MMC_CCCR_SDIO_REV = 0u,
|
||||
/* SD version number register */
|
||||
MSS_MMC_CCCR_SD_SPEC_REV = 1u,
|
||||
/* IO enable function register */
|
||||
MSS_MMC_CCCR_IO_ENABLE = 2u,
|
||||
/* IO ready function register */
|
||||
MSS_MMC_CCCR_IO_READY = 3u,
|
||||
/* interrupt enable register */
|
||||
MSS_MMC_CCCR_INT_ENABLE = 4u,
|
||||
/* interrupt pending register */
|
||||
MSS_MMC_CCCR_INT_PENDING = 5u,
|
||||
/* IO Abort register. It used to stop a function transfer. */
|
||||
MSS_MMC_CCCR_ABORT = 6u,
|
||||
/* Bus interface control register */
|
||||
MSS_MMC_CCCR_BUS_CONTROL = 7u,
|
||||
/* Card capability register */
|
||||
MSS_MMC_CCCR_CARD_CAPABILITY = 8u,
|
||||
/* Pointer to card's common Card Information Structure (CIS) */
|
||||
MSS_MMC_CCCR_CIS_POINTER = 9u,
|
||||
/* Bus suspend register */
|
||||
MSS_MMC_CCCR_BUS_SUSPENDED = 12u,
|
||||
/* Function select register */
|
||||
MSS_MMC_CCCR_FUNCTION_SELECT = 13u,
|
||||
/* Exec flags register. The bits of this register are used by the host to
|
||||
* determine the current execution status of all functions (1-7) and memory (0).
|
||||
*/
|
||||
MSS_MMC_CCCR_EXEC_FLAGS = 14u,
|
||||
/* Ready flags register. The bits of this register tell the host the read
|
||||
* or write busy status for functions (1-7) and memory (0).
|
||||
*/
|
||||
MSS_MMC_CCCR_READY_FLAGS = 15u,
|
||||
/* I/O block size for Function 0 */
|
||||
MSS_MMC_CCCR_FN0_BLOCK_SIZE = 16u,
|
||||
/* Power control register */
|
||||
MSS_MMC_CCCR_POWER_CONTROL = 18u,
|
||||
/* Bus speed select */
|
||||
MSS_MMC_CCCR_HIGH_SPEED = 19u,
|
||||
/* UHS-I support info */
|
||||
MSS_MMC_CCCR_UHSI_SUPPORT = 20u,
|
||||
/* Driver Strength */
|
||||
MSS_MMC_CCCR_DRIVER_STRENGTH = 21u,
|
||||
/* Interrupt extension */
|
||||
MSS_MMC_CCCR_INT_EXT = 22u,
|
||||
} MSS_MMC_cccr_reg_addr;
|
||||
|
||||
/* FBR card control registers definitions */
|
||||
typedef enum
|
||||
{
|
||||
MSS_MMC_FBR_STD_SDIO_FN = 0u,
|
||||
MSS_MMC_FBR_EXT_SDIO_FN = 1u,
|
||||
MSS_MMC_FBR_POWER_SEL = 2u,
|
||||
MSS_MMC_FBR_ADDR_CIS = 9u,
|
||||
MSS_MMC_FBR_ADDR_CSA = 12u,
|
||||
MSS_MMC_FBR_DATA_CSA = 15u,
|
||||
MSS_MMC_FBR_BLOCK_SIZE = 16u,
|
||||
} MSS_MMC_fbr_reg_addr;
|
||||
|
||||
/* Tuple names definitions of SDIO card */
|
||||
typedef enum
|
||||
{
|
||||
/* NULL tuple */
|
||||
MSS_MMC_TUPLE_CISTPL_NULL = 0u,
|
||||
/* Checksum control */
|
||||
MSS_MMC_TUPLE_CISTPL_CHECKSUM = 16u,
|
||||
/* Level 1 version/product information */
|
||||
MSS_MMC_TUPLE_CISTPL_VERS_1 = 21u,
|
||||
/* Alternate language string tuple */
|
||||
MSS_MMC_TUPLE_CISTPL_ALTSTR = 22u,
|
||||
/* Manufacturer identification string tuple */
|
||||
MSS_MMC_TUPLE_CISTPL_MANFID = 32u,
|
||||
/* Function identification tuple */
|
||||
MSS_MMC_TUPLE_CISTPL_FUNCID = 33u,
|
||||
/* Additional information for functions built to support application
|
||||
* specifications for standard SDIO functions.
|
||||
*/
|
||||
MSS_MMC_TUPLE_CISTPL_SDIO_STD = 145u,
|
||||
/* Reserved for future use with SDIO devices */
|
||||
MSS_MMC_TUPLE_CISTPL_SDIO_EXT = 146u,
|
||||
/* The End-of-chain Tuple */
|
||||
MSS_MMC_TUPLE_CISTPL_END = 255u,
|
||||
} MSS_MMC_tuple_code;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MSS_MMC_TYPE_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,133 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Register bit offsets and masks definitions for PolarFire SoC MSS MMUART
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MSS_UART_REGS_H_
|
||||
#define MSS_UART_REGS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
Register Bit definitions
|
||||
*/
|
||||
|
||||
/* Line Control register bit definitions */
|
||||
#define SB 6u /* Set break */
|
||||
#define DLAB 7u /* Divisor latch access bit */
|
||||
|
||||
/* Line Control register bit masks */
|
||||
#define SB_MASK (0x01u << SB) /* Set break */
|
||||
#define DLAB_MASK (0x01u << DLAB) /* Divisor latch access bit */
|
||||
|
||||
/* FIFO Control register bit definitions */
|
||||
#define RXRDY_TXRDYN_EN 0u /* Enable TXRDY and RXRDY signals */
|
||||
#define CLEAR_RX_FIFO 1u /* Clear receiver FIFO */
|
||||
#define CLEAR_TX_FIFO 2u /* Clear transmitter FIFO */
|
||||
#define RDYMODE 3u /* Mode 0 or Mode 1 for TXRDY and RXRDY */
|
||||
|
||||
/* FIFO Control register bit MASKS */
|
||||
#define RXRDY_TXRDYN_EN_MASK (0x01u << 0u) /* Enable TXRDY and RXRDY signals */
|
||||
#define CLEAR_RX_FIFO_MASK (0x01u << 1u) /* Clear receiver FIFO */
|
||||
#define CLEAR_TX_FIFO_MASK (0x01u << 2u) /* Clear transmitter FIFO */
|
||||
#define RDYMODE_MASK (0x01u << 3u) /* Mode 0 or Mode 1 for TXRDY and RXRDY */
|
||||
|
||||
/* Modem Control register bit definitions */
|
||||
#define LOOP 4u /* Local loopback */
|
||||
#define RLOOP 5u /* Remote loopback */
|
||||
#define ECHO 6u /* Automatic echo */
|
||||
|
||||
/* Modem Control register bit MASKS */
|
||||
#define LOOP_MASK (0x01u << 4u) /* Local loopback */
|
||||
#define RLOOP_MASK (0x01u << 5u) /* Remote loopback & Automatic echo*/
|
||||
#define ECHO_MASK (0x01u << 6u) /* Automatic echo */
|
||||
|
||||
/* Line Status register bit definitions */
|
||||
#define DR 0u /* Data ready */
|
||||
#define THRE 5u /* Transmitter holding register empty */
|
||||
#define TEMT 6u /* Transmitter empty */
|
||||
|
||||
/* Line Status register bit MASKS */
|
||||
#define DR_MASK (0x01u << 0u) /* Data ready */
|
||||
#define THRE_MASK (0x01u << 5u) /* Transmitter holding register empty */
|
||||
#define TEMT_MASK (0x01u << 6u) /* Transmitter empty */
|
||||
|
||||
/* Interrupt Enable register bit definitions */
|
||||
#define ERBFI 0u /* Enable receiver buffer full interrupt */
|
||||
#define ETBEI 1u /* Enable transmitter buffer empty interrupt */
|
||||
#define ELSI 2u /* Enable line status interrupt */
|
||||
#define EDSSI 3u /* Enable modem status interrupt */
|
||||
|
||||
/* Interrupt Enable register bit MASKS */
|
||||
#define ERBFI_MASK (0x01u << 0u) /* Enable receiver buffer full interrupt */
|
||||
#define ETBEI_MASK (0x01u << 1u) /* Enable transmitter buffer empty interrupt */
|
||||
#define ELSI_MASK (0x01u << 2u) /* Enable line status interrupt */
|
||||
#define EDSSI_MASK (0x01u << 3u) /* Enable modem status interrupt */
|
||||
|
||||
/* Multimode register 0 bit definitions */
|
||||
#define ELIN 3u /* Enable LIN header detection */
|
||||
#define ETTG 5u /* Enable transmitter time guard */
|
||||
#define ERTO 6u /* Enable receiver time-out */
|
||||
#define EFBR 7u /* Enable fractional baud rate mode */
|
||||
|
||||
/* Multimode register 0 bit MASKS */
|
||||
#define ELIN_MASK (0x01u << 3u) /* Enable LIN header detection */
|
||||
#define ETTG_MASK (0x01u << 5u) /* Enable transmitter time guard */
|
||||
#define ERTO_MASK (0x01u << 6u) /* Enable receiver time-out */
|
||||
#define EFBR_MASK (0x01u << 7u) /* Enable fractional baud rate mode */
|
||||
|
||||
/* Multimode register 1 bit definitions */
|
||||
#define E_MSB_RX 0u /* MSB / LSB first for receiver */
|
||||
#define E_MSB_TX 1u /* MSB / LSB first for transmitter */
|
||||
#define EIRD 2u /* Enable IrDA modem */
|
||||
#define EIRX 3u /* Input polarity for IrDA modem */
|
||||
#define EITX 4u /* Output polarity for IrDA modem */
|
||||
#define EITP 5u /* Output pulse width for IrDA modem */
|
||||
|
||||
/* Multimode register 1 bit MASKS */
|
||||
#define E_MSB_RX_MASK (0x01u << 0u) /* MSB / LSB first for receiver */
|
||||
#define E_MSB_TX_MASK (0x01u << 1u) /* MSB / LSB first for transmitter */
|
||||
#define EIRD_MASK (0x01u << 2u) /* Enable IrDA modem */
|
||||
#define EIRX_MASK (0x01u << 3u) /* Input polarity for IrDA modem */
|
||||
#define EITX_MASK (0x01u << 4u) /* Output polarity for IrDA modem */
|
||||
#define EITP_MASK (0x01u << 5u) /* Output pulse width for IrDA modem */
|
||||
|
||||
/* Multimode register 2 bit definitions */
|
||||
#define EERR 0u /* Enable ERR / NACK during stop time */
|
||||
#define EAFM 1u /* Enable 9-bit address flag mode */
|
||||
#define EAFC 2u /* Enable address flag clear */
|
||||
#define ESWM 3u /* Enable single wire half-duplex mode */
|
||||
|
||||
/* Multimode register 2 bit MASKS */
|
||||
#define EERR_MASK (0x01u << 0u) /* Enable ERR / NACK during stop time */
|
||||
#define EAFM_MASK (0x01u << 1u) /* Enable 9-bit address flag mode */
|
||||
#define EAFC_MASK (0x01u << 2u) /* Enable address flag clear */
|
||||
#define ESWM_MASK (0x01u << 3u) /* Enable single wire half-duplex mode */
|
||||
|
||||
/* Multimode Interrupt Enable register and
|
||||
Multimode Interrupt Identification register definitions */
|
||||
#define ERTOI 0u /* Enable receiver timeout interrupt */
|
||||
#define ENACKI 1u /* Enable NACK / ERR interrupt */
|
||||
#define EPID_PEI 2u /* Enable PID parity error interrupt */
|
||||
#define ELINBI 3u /* Enable LIN break interrupt */
|
||||
#define ELINSI 4u /* Enable LIN sync detection interrupt */
|
||||
|
||||
/* Multimode Interrupt Enable register and
|
||||
Multimode Interrupt Identification register MASKS */
|
||||
#define ERTOI_MASK (0x01u << 0u) /* Enable receiver timeout interrupt */
|
||||
#define ENACKI_MASK (0x01u << 1u) /* Enable NACK / ERR interrupt */
|
||||
#define EPID_PEI_MASK (0x01u << 2u) /* Enable PID parity error interrupt */
|
||||
#define ELINBI_MASK (0x01u << 3u) /* Enable LIN break interrupt */
|
||||
#define ELINSI_MASK (0x01u << 4u) /* Enable LIN sync detection interrupt */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_UART_REGS_H_ */
|
|
@ -0,0 +1,509 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* PoalrFire SoC Microprocessor Subsystem PDMA bare metal driver implementation.
|
||||
*/
|
||||
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
#include "mss_pdma.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* MACRO to set the correct channel memory offset for the memory mapped
|
||||
* configuration register.
|
||||
*/
|
||||
#define MSS_PDMA_REG_OFFSET(x) \
|
||||
(uint64_t)(PDMA_REG_BASE + (PDMA_CHL_REG_OFFSET * (x)))
|
||||
|
||||
/* Default is maximum transaction size for both write_size and read_size. */
|
||||
uint8_t g_channel_nextcfg_wsize[MSS_PDMA_lAST_CHANNEL] =
|
||||
{ 0x0Fu, 0x0Fu, 0x0Fu, 0x0Fu };
|
||||
uint8_t g_channel_nextcfg_rsize[MSS_PDMA_lAST_CHANNEL] =
|
||||
{ 0x0Fu, 0x0Fu, 0x0Fu, 0x0Fu };
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_PDMA_init()
|
||||
* See pse_pdma.h for description of this function.
|
||||
*/
|
||||
void
|
||||
MSS_PDMA_init
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_PDMA_setup_transfer()
|
||||
* See pse_pdma.h for description of this function.
|
||||
*/
|
||||
mss_pdma_error_id_t
|
||||
MSS_PDMA_setup_transfer
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id,
|
||||
mss_pdma_channel_config_t *channel_config
|
||||
)
|
||||
{
|
||||
if (channel_id > MSS_PDMA_CHANNEL_3)
|
||||
{
|
||||
return MSS_PDMA_ERROR_INVALID_CHANNEL_ID;
|
||||
}
|
||||
|
||||
/* Set the register structure pointer for the PDMA channel. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET(channel_id);
|
||||
|
||||
/* Basic House Keeping, return if errors exist. */
|
||||
if (channel_config->src_addr == 0u)
|
||||
{
|
||||
return MSS_PDMA_ERROR_INVALID_SRC_ADDR;
|
||||
}
|
||||
|
||||
if (channel_config->dest_addr == 0u)
|
||||
{
|
||||
return MSS_PDMA_ERROR_INVALID_DEST_ADDR;
|
||||
}
|
||||
|
||||
/* If a run transaction is in progress, return error.
|
||||
* Channel can only be claimed when run is low */
|
||||
if (pdmareg->control_reg & MASK_PDMA_CONTROL_RUN)
|
||||
{
|
||||
return MSS_PDMA_ERROR_TRANSACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
/* Set or clear the interrupts for the transfer. */
|
||||
if (channel_config->enable_done_int)
|
||||
{
|
||||
pdmareg->control_reg |= ((uint32_t)MASK_PDMA_ENABLE_DONE_INT);
|
||||
}
|
||||
else
|
||||
{
|
||||
pdmareg->control_reg &= ~((uint32_t)MASK_PDMA_ENABLE_DONE_INT);
|
||||
}
|
||||
|
||||
if (channel_config->enable_err_int)
|
||||
{
|
||||
pdmareg->control_reg |= ((uint32_t)MASK_PDMA_ENABLE_ERR_INT);
|
||||
}
|
||||
else
|
||||
{
|
||||
pdmareg->control_reg &= ~((uint32_t)MASK_PDMA_ENABLE_ERR_INT);
|
||||
}
|
||||
|
||||
/* clear Next registers. */
|
||||
pdmareg->control_reg |= (uint32_t)MASK_CLAIM_PDMA_CHANNEL;
|
||||
|
||||
/* Setup the source and destination addresses.*/
|
||||
pdmareg->next_destination = channel_config->dest_addr;
|
||||
pdmareg->next_source = channel_config->src_addr;
|
||||
|
||||
/* Set the transfer size. */
|
||||
pdmareg->next_bytes = channel_config->num_bytes;
|
||||
|
||||
/* Setup repeat and force order requirements. */
|
||||
if (channel_config->repeat)
|
||||
{
|
||||
pdmareg->next_config |= MASK_REPEAT_TRANSCTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdmareg->next_config &= ~((uint32_t)MASK_REPEAT_TRANSCTION);
|
||||
}
|
||||
|
||||
if (channel_config->force_order)
|
||||
{
|
||||
pdmareg->next_config |= ((uint32_t)MASK_FORCE_ORDERING);
|
||||
}
|
||||
else
|
||||
{
|
||||
pdmareg->next_config &= ~((uint32_t)MASK_FORCE_ORDERING);
|
||||
}
|
||||
|
||||
/* PDMA transaction size.. set to maximum. */
|
||||
pdmareg->next_config |=
|
||||
(g_channel_nextcfg_wsize[channel_id] << SHIFT_CH_CONFIG_WSIZE);
|
||||
pdmareg->next_config |=
|
||||
(g_channel_nextcfg_rsize[channel_id] << SHIFT_CH_CONFIG_RSIZE);
|
||||
|
||||
return MSS_PDMA_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See pse_pdma.h for description of this function.
|
||||
*/
|
||||
mss_pdma_error_id_t
|
||||
MSS_PDMA_set_transction_size
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id,
|
||||
uint8_t write_size,
|
||||
uint8_t read_size
|
||||
)
|
||||
{
|
||||
uint8_t value;
|
||||
|
||||
if (channel_id > MSS_PDMA_CHANNEL_3)
|
||||
{
|
||||
return MSS_PDMA_ERROR_INVALID_CHANNEL_ID;
|
||||
}
|
||||
|
||||
if (write_size > 0x0Fu)
|
||||
{
|
||||
return MSS_PDMA_ERROR_INVALID_NEXTCFG_WSIZE;
|
||||
}
|
||||
|
||||
if (read_size > 0x0Fu)
|
||||
{
|
||||
return MSS_PDMA_ERROR_INVALID_NEXTCFG_RSIZE;
|
||||
}
|
||||
|
||||
g_channel_nextcfg_wsize[channel_id] = write_size;
|
||||
g_channel_nextcfg_rsize[channel_id] = read_size;
|
||||
|
||||
return MSS_PDMA_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See pse_pdma.h for description of this function.
|
||||
*/
|
||||
mss_pdma_error_id_t
|
||||
MSS_PDMA_start_transfer
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
)
|
||||
{
|
||||
if (channel_id > MSS_PDMA_CHANNEL_3)
|
||||
{
|
||||
return MSS_PDMA_ERROR_INVALID_CHANNEL_ID;
|
||||
}
|
||||
|
||||
/* Set the register structure pointer for the PDMA channel. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET(channel_id);
|
||||
|
||||
/* If a run transaction is in progress, return error.
|
||||
* Channel can only be claimed when run is low */
|
||||
pdmareg->control_reg |= ((uint32_t)MASK_PDMA_CONTROL_RUN);
|
||||
|
||||
return MSS_PDMA_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See pse_pdma.h for description of this function.
|
||||
*/
|
||||
uint32_t
|
||||
MSS_PDMA_get_active_transfer_type
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
)
|
||||
{
|
||||
if (channel_id > MSS_PDMA_CHANNEL_3)
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
|
||||
/* Set the register structure pointer for the PDMA channel. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET(channel_id);
|
||||
|
||||
return pdmareg->exec_config;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See pse_pdma.h for description of this function.
|
||||
*/
|
||||
uint64_t
|
||||
MSS_PDMA_get_number_bytes_remaining
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
)
|
||||
{
|
||||
if (channel_id > MSS_PDMA_CHANNEL_3)
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
|
||||
/* Set the register structure pointer for the PDMA channel. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET(channel_id);
|
||||
|
||||
return pdmareg->exec_bytes;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See pse_pdma.h for description of this function.
|
||||
*/
|
||||
uint64_t
|
||||
MSS_PDMA_get_destination_current_addr
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
)
|
||||
{
|
||||
if (channel_id > MSS_PDMA_CHANNEL_3)
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
|
||||
/* Set the register structure pointer for the PDMA channel. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET(channel_id);
|
||||
|
||||
return pdmareg->exec_destination;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See pse_pdma.h for description of this function.
|
||||
*/
|
||||
uint64_t
|
||||
MSS_PDMA_get_source_current_addr
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
)
|
||||
{
|
||||
if (channel_id > MSS_PDMA_CHANNEL_3)
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
|
||||
/* Set the register structure pointer for the PDMA channel. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET(channel_id);
|
||||
|
||||
return pdmareg->exec_source;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See pse_pdma.h for description of this function.
|
||||
*/
|
||||
uint8_t
|
||||
MSS_PDMA_get_transfer_complete_status
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
)
|
||||
{
|
||||
if (channel_id > MSS_PDMA_CHANNEL_3)
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
|
||||
/* Set the register structure pointer for the PDMA channel. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET(channel_id);
|
||||
|
||||
if (pdmareg->control_reg & MASK_PDMA_TRANSFER_DONE)
|
||||
{
|
||||
return 1u;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See pse_pdma.h for description of this function.
|
||||
*/
|
||||
uint8_t
|
||||
MSS_PDMA_get_transfer_error_status
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
)
|
||||
{
|
||||
if (channel_id > MSS_PDMA_CHANNEL_3)
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
|
||||
/* Set the register structure pointer for the PDMA channel. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET(channel_id);
|
||||
|
||||
if (pdmareg->control_reg & MASK_PDMA_TRANSFER_ERROR)
|
||||
{
|
||||
return 1u;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See pse_pdma.h for description of this function.
|
||||
*/
|
||||
uint8_t
|
||||
MSS_PDMA_clear_transfer_complete_status
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
)
|
||||
{
|
||||
uint8_t intStatus = 0u;
|
||||
|
||||
if (channel_id > MSS_PDMA_CHANNEL_3)
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
|
||||
/* Set the register structure pointer for the PDMA channel. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET(channel_id);
|
||||
|
||||
if (pdmareg->control_reg & MASK_PDMA_TRANSFER_DONE)
|
||||
{
|
||||
intStatus = 1u;
|
||||
pdmareg->control_reg &= ~((uint32_t)MASK_PDMA_TRANSFER_DONE);
|
||||
}
|
||||
|
||||
return intStatus;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See pse_pdma.h for description of this function.
|
||||
*/
|
||||
uint8_t
|
||||
MSS_PDMA_clear_transfer_error_status
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
)
|
||||
{
|
||||
uint8_t intStatus = 0u;
|
||||
|
||||
if (channel_id > MSS_PDMA_CHANNEL_3)
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
|
||||
/* Set the register structure pointer for the PDMA channel. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET(channel_id);
|
||||
|
||||
if (pdmareg->control_reg & MASK_PDMA_TRANSFER_ERROR)
|
||||
{
|
||||
intStatus = 1u;
|
||||
pdmareg->control_reg &= ~((uint32_t)MASK_PDMA_TRANSFER_ERROR);
|
||||
}
|
||||
|
||||
return intStatus;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Each DMA channel has two interrupts, one for transfer complete
|
||||
* and the other for the transfer error.
|
||||
*/
|
||||
uint8_t
|
||||
dma_ch0_DONE_IRQHandler
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Clear the interrupt enable bit. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET
|
||||
(MSS_PDMA_CHANNEL_0);
|
||||
|
||||
pdmareg->control_reg &= ~((uint32_t)MASK_PDMA_ENABLE_DONE_INT);
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
dma_ch0_ERR_IRQHandler
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Clear the interrupt enable bit. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET
|
||||
(MSS_PDMA_CHANNEL_0);
|
||||
|
||||
pdmareg->control_reg &= ~((uint32_t)MASK_PDMA_ENABLE_ERR_INT);
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
dma_ch1_DONE_IRQHandler
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Clear the interrupt enable bit. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET
|
||||
(MSS_PDMA_CHANNEL_1);
|
||||
|
||||
pdmareg->control_reg &= ~((uint32_t)MASK_PDMA_ENABLE_DONE_INT);
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
dma_ch1_ERR_IRQHandler
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Clear the interrupt enable bit. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET
|
||||
(MSS_PDMA_CHANNEL_1);
|
||||
|
||||
pdmareg->control_reg &= ~((uint32_t)MASK_PDMA_ENABLE_ERR_INT);
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
dma_ch2_DONE_IRQHandler
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Clear the interrupt enable bit. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET
|
||||
(MSS_PDMA_CHANNEL_2);
|
||||
|
||||
pdmareg->control_reg &= ~((uint32_t)MASK_PDMA_ENABLE_DONE_INT);
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
dma_ch2_ERR_IRQHandler
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Clear the interrupt enable bit. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET
|
||||
(MSS_PDMA_CHANNEL_2);
|
||||
|
||||
pdmareg->control_reg &= ~((uint32_t)MASK_PDMA_ENABLE_ERR_INT);
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
dma_ch3_DONE_IRQHandler
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Clear the interrupt enable bit. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET
|
||||
(MSS_PDMA_CHANNEL_3);
|
||||
|
||||
pdmareg->control_reg &= ~((uint32_t)MASK_PDMA_ENABLE_DONE_INT);
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
dma_ch3_ERR_IRQHandler
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Clear the interrupt enable bit. */
|
||||
volatile mss_pdma_t *pdmareg = (mss_pdma_t *)MSS_PDMA_REG_OFFSET
|
||||
(MSS_PDMA_CHANNEL_3);
|
||||
|
||||
pdmareg->control_reg &= ~((uint32_t)MASK_PDMA_ENABLE_ERR_INT);
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,580 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* PolarFire SoC Microprocessor subsystem PDMA bare metal software driver public
|
||||
* APIs.
|
||||
*/
|
||||
|
||||
/*=========================================================================*//**
|
||||
@mainpage PolarFire SoC MSS PDMA Bare Metal Driver.
|
||||
|
||||
==============================================================================
|
||||
Introduction
|
||||
==============================================================================
|
||||
The PolarFire SoC Microprocessor Subsystem (MSS) includes the MSS PDMA
|
||||
peripherals for autonomous data transfers. The MSS PDMA has memory-mapped
|
||||
control registers accessed over a TileLink slave interface to allow software
|
||||
to set up DMA transfers, and has a TileLink bus master port into the TileLink
|
||||
bus fabric to allow it to rapidly copy data between two locations in memory.
|
||||
The MSS PDMA can support multiple independent simultaneous DMA transfers
|
||||
using different PDMA channels and can generate PLIC interrupts on either a
|
||||
transfer has completed, or when a transfer error has occurred.
|
||||
|
||||
==============================================================================
|
||||
Hardware Flow Dependencies
|
||||
==============================================================================
|
||||
The configuration of all features of the MSS PDMA driver is covered by this
|
||||
driver. There are no dependencies on the hardware flow when configuring MSS
|
||||
PDMA.
|
||||
The source and destination of the DMA transaction must be enabled, either in
|
||||
the hardware or by your application program. The source and destination
|
||||
addresses must be located at valid addresses in the PolarFire SoC MSS memory
|
||||
map and must be appropriate to the configuration that you specify the PDMA
|
||||
channel.
|
||||
The base address, register addresses, and interrupt numbers associated with
|
||||
MSS PDMA block are defined in the mpfs hal as constants. User must ensure that
|
||||
the latest mpfs hal is included in the example project.
|
||||
|
||||
==============================================================================
|
||||
Theory of Operation
|
||||
==============================================================================
|
||||
The PDMA driver function are grouped into the following categories:
|
||||
- Initialization
|
||||
- Configuration
|
||||
- Transfer Control
|
||||
- Interrupt Control
|
||||
|
||||
--------------------------------
|
||||
Initialization
|
||||
--------------------------------
|
||||
The PolarFire SoC MSS PDMA driver is initialized through the call to the
|
||||
MSS_PDMA_init() function. The MSS_PDMA_init() function must be called before
|
||||
any other MSS PDMA driver functions.
|
||||
|
||||
--------------------------------
|
||||
Configuration
|
||||
--------------------------------
|
||||
Each PDMA channel is configured through the call to MSS_PDMA_setup_transfer()
|
||||
function. Configuration includes :
|
||||
- The PDMA channel for transaction.
|
||||
- Source and destination addresses.
|
||||
- The transfer sizes.
|
||||
- Repeat the transfer
|
||||
- Ordering requirements.
|
||||
- Set / Clear the interrupt for the transfer
|
||||
|
||||
The PolarFire SoC MSS PDMA has four independent DMA channels which operate
|
||||
concurrently to support multiple simultaneous transfers. Each channel has an
|
||||
independent set of registers and interrupts. The PDMA channels can be
|
||||
configured through the call to MSS_PDMA_setup_transfer() function. Apart from
|
||||
selecting the channel the MSS_PDMA_setup_transfer() function will also setup
|
||||
the transfer size, source and destination addresses.
|
||||
MSS_PDMA_setup_transfer() function will also configure the repeat and force
|
||||
order requirements as the PoalrFire SoC MSS PDMA supports multiple
|
||||
simultaneous transfers.
|
||||
The PDMA has two interrupts per channel which are used to signal when either
|
||||
a transfer has completed or when a transfer error has occurred. These
|
||||
interrupts are enabled by the application software and are set / cleared
|
||||
by MSS_PDMA_setup_transfer() function.
|
||||
|
||||
--------------------------------
|
||||
Transfer Control
|
||||
--------------------------------
|
||||
The PDMA transfers can be initiated by a call to the MSS_PDMA_start_transfer()
|
||||
function after a PDMA channel has been configured. The
|
||||
MSS_PDMA_start_transfer() function will write the config register in PDMA
|
||||
memory map. The write_size and read_size buffers are used to determine the
|
||||
size and alignment of individual PDMA transactions as a single PDMA transfers
|
||||
may require multiple transactions.
|
||||
The configuration of the currently selected PDMA channel can be read by
|
||||
calling the MSS_PDMA_get_active_transfer_type() function.
|
||||
|
||||
--------------------------------
|
||||
Interrupt Control
|
||||
--------------------------------
|
||||
The PDMA has two interrupts per channel which are used to signal either a
|
||||
successful completion og the transfer, a transfer error. These interrupts are
|
||||
enabled by the application software by a call to MSS_PDMA_setup_transfer()
|
||||
function. The MSS_PDMA_get_transfer_complete_status() function will indicate
|
||||
the DMA transfer success status for selected DMA channel. The
|
||||
MSS_PDMA_get_transfer_error_status() function will indicate the DMA transfer
|
||||
failure status for selected DMA channel. The
|
||||
MSS_PDMA_clear_transfer_complete_status() function can be used to clear the
|
||||
DMA transfer success status.
|
||||
The MSS_PDMA_clear_transfer_error_status() function can be used to clear the
|
||||
DMA transfer error status.
|
||||
|
||||
*//*==========================================================================*/
|
||||
#ifndef MSS_PDMA_H
|
||||
#define MSS_PDMA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*---------------------------Public Data Structure----------------------------*/
|
||||
/*----------------------------------PDMA--------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------/*
|
||||
The mss_pdma_channel_id_t enumeration is used to identify peripheral DMA
|
||||
channels. It is used as function parameter to specify the PDMA channel used.
|
||||
*/
|
||||
typedef enum __pdma_channel_id
|
||||
{
|
||||
MSS_PDMA_CHANNEL_0 = 0,
|
||||
MSS_PDMA_CHANNEL_1,
|
||||
MSS_PDMA_CHANNEL_2,
|
||||
MSS_PDMA_CHANNEL_3,
|
||||
MSS_PDMA_lAST_CHANNEL,
|
||||
} mss_pdma_channel_id_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The mss_pdma_channel_config_t structure is used to configure the desired
|
||||
Platform DMA channel. PDMA channel configuration includes configuration of
|
||||
source, destination address and the number of bytes for the DMA transfer.
|
||||
Single DMA transfer may require multiple DMA transactions, the size and
|
||||
alignment of the individual DMA transaction can be forced. The PDMA can be
|
||||
programmed to automatically repeat a transfer.
|
||||
The MSS PDMA have two interrupts per channel, transfer complete interrupt and
|
||||
transfer error interrupt. The two interrupts can be enabled by configuring
|
||||
respective bits in the mss_pdma_channel_config_t structure.
|
||||
*/
|
||||
typedef struct _pdmachannelconfig
|
||||
{
|
||||
volatile uint64_t src_addr; /* source address */
|
||||
volatile uint64_t dest_addr; /* destination address */
|
||||
volatile uint64_t num_bytes; /* Number of bytes to be transferred.
|
||||
* Base 2 Logarithm */
|
||||
volatile uint8_t enable_done_int; /* enable transfer complete interrupt*/
|
||||
volatile uint8_t enable_err_int; /* enable transfer error interrupt*/
|
||||
volatile uint8_t repeat; /* repeat the transaction */
|
||||
volatile uint8_t force_order; /* Enforces strict ordering by only
|
||||
allowing one of each transfer type
|
||||
in-flight at a time */
|
||||
} mss_pdma_channel_config_t;
|
||||
|
||||
/*------------------------Private data structures-----------------------------*/
|
||||
/*----------------------------------- PDMA -----------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------*//**
|
||||
* The mss_pdma_error_id_t enumeration is used to specify the error status from
|
||||
* MSS PDMA transfer / transaction functions.
|
||||
*/
|
||||
typedef enum __pdma_error_id_t
|
||||
{
|
||||
MSS_PDMA_OK = 0, //!< PDMA_OK
|
||||
MSS_PDMA_ERROR_INVALID_SRC_ADDR, //!< ERROR_INVALID_SRC_ADDR
|
||||
MSS_PDMA_ERROR_INVALID_DEST_ADDR, //!< ERROR_INVALID_DEST_ADDR
|
||||
MSS_PDMA_ERROR_TRANSACTION_IN_PROGRESS,//!< ERROR_TRANSACTION_IN_PROGRESS
|
||||
MSS_PDMA_ERROR_INVALID_CHANNEL_ID, //!< ERROR_INVALID_CHANNEL_ID
|
||||
MSS_PDMA_ERROR_INVALID_NEXTCFG_WSIZE, //!< ERROR_INVALID_NEXTCFG_WSIZE
|
||||
MSS_PDMA_ERROR_INVALID_NEXTCFG_RSIZE, //!< ERROR_INVALID_NEXTCFG_RSIZE
|
||||
MSS_PDMA_ERROR_LAST_ID, //!< ERROR_LAST_ID
|
||||
} mss_pdma_error_id_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* The mss_pdma_t structure will describe the functionality of the memory mapped
|
||||
* registers in the Platform DMA Engine.
|
||||
*/
|
||||
typedef struct _pdmaregs
|
||||
{
|
||||
volatile uint32_t control_reg; /* Channel Control Register */
|
||||
volatile uint32_t next_config; /* Next transfer type */
|
||||
volatile uint64_t next_bytes; /* Number of bytes to be transferred.
|
||||
* Base 2 Logarithm */
|
||||
volatile uint64_t next_destination; /* Destination Start Address */
|
||||
volatile uint64_t next_source; /* Source start Address*/
|
||||
const volatile uint32_t exec_config; /* Active transfer type */
|
||||
const volatile uint64_t exec_bytes; /* Number of bytes remaining. */
|
||||
const volatile uint64_t exec_destination;/* Destination current address. */
|
||||
const volatile uint64_t exec_source; /* Source current address. */
|
||||
} mss_pdma_t;
|
||||
|
||||
/* PDMA Register base address. */
|
||||
#define PDMA_REG_BASE 0x03000000U
|
||||
|
||||
/* PDMA Channel Register offset.*/
|
||||
#define PDMA_CHL_REG_OFFSET 0x1000U
|
||||
|
||||
#define MASK_PDMA_CONTROL_RUN 0x02U
|
||||
|
||||
#define MASK_CLAIM_PDMA_CHANNEL 0x01U
|
||||
|
||||
#define MASK_PDMA_ENABLE_DONE_INT 0x00004000U
|
||||
#define MASK_PDMA_ENABLE_ERR_INT 0x00008000U
|
||||
|
||||
#define SHIFT_CH_CONFIG_WSIZE 24U
|
||||
#define SHIFT_CH_CONFIG_RSIZE 28U
|
||||
|
||||
#define MASK_MAXIUM_WSIZE 0x0F000000U
|
||||
#define MASK_MAXIUM_RSIZE 0xF0000000U
|
||||
|
||||
#define MASK_REPEAT_TRANSCTION 0x04U
|
||||
#define MASK_FORCE_ORDERING 0x08U
|
||||
|
||||
#define MASK_PDMA_TRANSFER_ERROR 0x80000000U
|
||||
#define MASK_PDMA_TRANSFER_DONE 0x40000000U
|
||||
|
||||
/*--------------------------------Public APIs---------------------------------*/
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_PDMA_init() function is used to initialize the PolarFire SoC MSS
|
||||
Platform DMA engine. It initializes the basic data structures required for
|
||||
driver functionality.
|
||||
@param
|
||||
This function does not need any parameters.
|
||||
|
||||
@return
|
||||
This function does not return value.
|
||||
@endcode
|
||||
*/
|
||||
void
|
||||
MSS_PDMA_init
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_PDMA_setup_transfer() function is used to configure an individual
|
||||
DMA channel. Apart from selecting the DMA channel the MSS_PDMA_setup_transfer()
|
||||
function will also setup the transfer size, source and destination addresses.
|
||||
This function will also configure the repeat and force order requirements as
|
||||
the PolarFire SoC MSS Peripheral DMA supports multiple simultaneous transfers.
|
||||
Once transfer is setup, it can be started.
|
||||
|
||||
@param channel_id
|
||||
The channel_id parameter specifies the Platform DMA channel selected
|
||||
for DMA transaction.
|
||||
|
||||
@param channel_config
|
||||
The channel_config parameter structure contains the data needed for
|
||||
a DMA transfer.
|
||||
- Source Address
|
||||
- Destination address
|
||||
- Number of Bytes
|
||||
- Enable the Done Interrupt
|
||||
- Enable the ErrorInterrupt
|
||||
- Set the active transfer type, single or repeat.
|
||||
- Force Order.
|
||||
|
||||
@return pdma_error_id_t
|
||||
The function returns error signals of type mss_pdma_error_id_t.
|
||||
|
||||
Example:
|
||||
The following call will configure channel 0
|
||||
@code
|
||||
g_pdma_error_code = MSS_PDMA_setup_transfer(PDMA_CHANNEL_0,
|
||||
&pdma_config_ch0);
|
||||
@endcode
|
||||
*/
|
||||
mss_pdma_error_id_t
|
||||
MSS_PDMA_setup_transfer
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id,
|
||||
mss_pdma_channel_config_t *channel_config
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_PDMA_start_transfer() function is used to initiate an individual
|
||||
transfer on selected DMA channel . The source and destination address of
|
||||
the transfer and the number of bytes to be transferred must be configured
|
||||
before calling this function.
|
||||
|
||||
@param channel_id
|
||||
The channel_id parameter specifies the Platform DMA channel selected
|
||||
for DMA transaction.
|
||||
|
||||
@return
|
||||
The function returns error signals of type mss_pdma_error_id_t.
|
||||
|
||||
Example:
|
||||
The following call will configure channel 0
|
||||
@code
|
||||
/*Setup the PDMA channel for transfer
|
||||
g_pdma_error_code = MSS_PDMA_setup_transfer(PDMA_CHANNEL_0,
|
||||
&pdma_config_ch0);
|
||||
|
||||
/*Initiate the transfer for channel 0.
|
||||
MSS_PDMA_start_transfer(PDMA_CHANNEL_0);
|
||||
@endcode
|
||||
*/
|
||||
mss_pdma_error_id_t
|
||||
MSS_PDMA_start_transfer
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_PDMA_set_transction_size() function is used to set a channel
|
||||
DMA transaction size. The write_size and read_size buffers are used to
|
||||
determine the size and alignment of individual PDMA transaction as a single
|
||||
PDMA transfer may require multiple transaction.
|
||||
|
||||
@param channel_id
|
||||
The channel_id parameter specifies the Platform DMA channel selected
|
||||
for DMA transaction.
|
||||
|
||||
@param write_size
|
||||
The write_size parameter specifies the base 2 logarithm of PDMA
|
||||
transaction.
|
||||
e.g. 0 is 1 byte, 3 is 8 bytes, 5 is 32 bytes
|
||||
|
||||
@param read_size
|
||||
The read_size parameter specifies the base 2 logarithm of PDMA
|
||||
transaction.
|
||||
e.g. 0 is 1 byte, 3 is 8 bytes, 5 is 32 bytes
|
||||
|
||||
@return
|
||||
The function returns error signals of type mss_pdma_error_id_t.
|
||||
|
||||
Example:
|
||||
The following call will configure channel 0 transaction to 32bytes.
|
||||
@code
|
||||
MSS_PDMA_set_transction_size(PDMA_CHANNEL_0,
|
||||
write_size,
|
||||
read_size)
|
||||
@endcode
|
||||
*/
|
||||
mss_pdma_error_id_t
|
||||
MSS_PDMA_set_transction_size
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id,
|
||||
uint8_t write_size,
|
||||
uint8_t read_size
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_PDMA_get_active_transfer_type() function is used to request active
|
||||
transfer type for selected DMA channel.
|
||||
The transfer type for the DMA channel was configured during the channel
|
||||
configuration process, calling this function will read the transfer type
|
||||
from the configured DMA channel.
|
||||
|
||||
@param channel_id
|
||||
The channel_id parameter specifies the Platform DMA channel selected
|
||||
for DMA transaction.
|
||||
|
||||
@return
|
||||
This function returns a 32-bit value indicating the active transfer
|
||||
type of the DMA channel.
|
||||
|
||||
Example:
|
||||
The following call will return the Channel (0) active transfer type.
|
||||
|
||||
@code
|
||||
MSS_PDMA_get_active_transfer_type(PDMA_CHANNEL_0);
|
||||
@endcode
|
||||
*/
|
||||
uint32_t
|
||||
MSS_PDMA_get_active_transfer_type
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_PDMA_get_number_bytes_remaining() function is used to request number
|
||||
of bytes remaining to be transferred.
|
||||
|
||||
@param channel_id
|
||||
The channel_id parameter specifies the Platform DMA channel selected
|
||||
for DMA transaction.
|
||||
|
||||
@return
|
||||
This function return 64-bit value indicating number of bytes
|
||||
remaining to be transferred.
|
||||
|
||||
Example:
|
||||
The following call will return the number of bytes remaining Channel (0).
|
||||
|
||||
@code
|
||||
MSS_PDMA_get_number_bytes_remaining(PDMA_CHANNEL_0);
|
||||
@endcode
|
||||
*/
|
||||
uint64_t
|
||||
MSS_PDMA_get_number_bytes_remaining
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_PDMA_get_destination_current_addr() function is used to request the
|
||||
channel Destination address.
|
||||
|
||||
@param channel_id
|
||||
The channel_id parameter specifies the Platform DMA channel selected
|
||||
for DMA transaction.
|
||||
|
||||
@return
|
||||
This function return 64-bit value indicating destination address of
|
||||
the selected DMA channel.
|
||||
|
||||
Example:
|
||||
The following call will return the Channel (0) Destination address register
|
||||
value.
|
||||
|
||||
@code
|
||||
MSS_PDMA_get_destination_current_addr(PDMA_CHANNEL_0);
|
||||
@endcode
|
||||
*/
|
||||
uint64_t
|
||||
MSS_PDMA_get_destination_current_addr
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_PDMA_get_source_current_addr() function is used to request the
|
||||
channel Source address.
|
||||
|
||||
@param channel_id
|
||||
The channel_id parameter specifies the Platform DMA channel selected
|
||||
for DMA transaction.
|
||||
|
||||
@return
|
||||
This function return 64-bit value indicating source address of
|
||||
the selected DMA channel.
|
||||
|
||||
Example:
|
||||
The following call will return the Channel (0) Source address register
|
||||
value.
|
||||
|
||||
@code
|
||||
MSS_PDMA_get_source_current_addr(PDMA_CHANNEL_0);
|
||||
@endcode
|
||||
*/
|
||||
uint64_t
|
||||
MSS_PDMA_get_source_current_addr
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_PDMA_get_transfer_complete_status() function is used to request the
|
||||
completion status of last DMA transfer.
|
||||
|
||||
@param channel_id
|
||||
The channel_id parameter specifies the Platform DMA channel selected
|
||||
for DMA transaction.
|
||||
|
||||
@return
|
||||
This function return 8-bit value indicating completion status of the
|
||||
last DMA transfer.
|
||||
|
||||
Example:
|
||||
The following call will return the Channel (0) transfer status.
|
||||
|
||||
@code
|
||||
MSS_PDMA_get_transfer_complete_status(PDMA_CHANNEL_0);
|
||||
@endcode
|
||||
|
||||
*/
|
||||
uint8_t
|
||||
MSS_PDMA_get_transfer_complete_status
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_PDMA_get_transfer_error_status() function is used to request the
|
||||
error status of last DMA transfer.
|
||||
|
||||
@param channel_id
|
||||
The channel_id parameter specifies the Platform DMA channel selected
|
||||
for DMA transaction.
|
||||
|
||||
@return
|
||||
This function return 8-bit value indicating the error status of the
|
||||
last DMA transfer.
|
||||
|
||||
Example:
|
||||
The following call will return the Channel (0) transfer error status.
|
||||
|
||||
@code
|
||||
MSS_PDMA_get_transfer_error_status(PDMA_CHANNEL_0);
|
||||
@endcode
|
||||
|
||||
*/
|
||||
uint8_t
|
||||
MSS_PDMA_get_transfer_error_status
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_PDMA_clear_transfer_complete_status() function is used to request the
|
||||
transfer complete interrupt status. If the function returns one, that indicates
|
||||
that the transfer is complete and the transfer complete interrupt is cleared.
|
||||
|
||||
@param channel_id
|
||||
The channel_id parameter specifies the Platform DMA channel selected
|
||||
for DMA transaction.
|
||||
|
||||
@return
|
||||
This function return 8-bit value indicating the transfer complete
|
||||
interrupt status of the last DMA transfer.
|
||||
|
||||
Example:
|
||||
The following call will return the Channel (0) transfer complete
|
||||
interrupt status of the last DMA transfer
|
||||
|
||||
@code
|
||||
MSS_PDMA_clear_transfer_complete_status(PDMA_CHANNEL_0);
|
||||
@endcode
|
||||
*/
|
||||
uint8_t
|
||||
MSS_PDMA_clear_transfer_complete_status
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_PDMA_clear_transfer_error_status() function is used to request the
|
||||
transfer error interrupt status. If the function returns one, that indicates
|
||||
that the transfer error has occurred and error interrupt is cleared.
|
||||
|
||||
@param channel_id
|
||||
The channel_id parameter specifies the Platform DMA channel selected
|
||||
for DMA transaction.
|
||||
|
||||
@return
|
||||
This function return 8-bit value indicating the transfer error
|
||||
interrupt status of the last DMA transfer.
|
||||
|
||||
Example:
|
||||
The following call will return the Channel (0) transfer error
|
||||
interrupt status of the last DMA transfer
|
||||
|
||||
@code
|
||||
MSS_PDMA_clear_transfer_complete_status(PDMA_CHANNEL_0);
|
||||
@endcode
|
||||
|
||||
*/
|
||||
uint8_t
|
||||
MSS_PDMA_clear_transfer_error_status
|
||||
(
|
||||
mss_pdma_channel_id_t channel_id
|
||||
);
|
||||
|
||||
#endif /* MSS_PDMA_H */
|
|
@ -0,0 +1,366 @@
|
|||
/***************************************************************************//**
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* PolarFire SoC (MPFS) Microprocessor SubSystem QSPI bare metal software driver
|
||||
* implementation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
#include "mss_qspi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define QSPI_BYTESUPPER_MASK ((uint32_t)0xFFFF0000u)
|
||||
|
||||
static void default_status_hanlder(uint32_t value);
|
||||
static volatile uint32_t g_irq_rd_byte_size = 0u;
|
||||
static volatile uint8_t g_rx_complete = 0u;
|
||||
static void * g_rd_buffer;
|
||||
static volatile mss_qspi_status_handler_t g_handler;
|
||||
|
||||
/***************************************************************************//**
|
||||
* See mss_qspi.h for details of how to use this function.
|
||||
*/
|
||||
void MSS_QSPI_init
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
g_handler = default_status_hanlder;
|
||||
|
||||
QSPI->CONTROL = CTRL_EN_MASK |
|
||||
CTRL_SAMPLE_SCK |
|
||||
(0x1u << CTRL_CLKRATE) | CTRL_CLKIDL_MASK ;
|
||||
|
||||
QSPI->INTENABLE = 0x0u;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See mss_qspi.h for details of how to use this function.
|
||||
*/
|
||||
void MSS_QSPI_configure
|
||||
(
|
||||
const mss_qspi_config_t* config
|
||||
)
|
||||
{
|
||||
QSPI->CONTROL = (uint32_t)(config->sample << CTRL_SAMPLE) |
|
||||
(uint32_t)(config->io_format << CTRL_QMODE0) |
|
||||
(uint32_t)(config->clk_div << CTRL_CLKRATE) |
|
||||
(uint32_t)(config->xip << CTRL_XIP) |
|
||||
(uint32_t)(config->xip_addr << CTRL_XIPADDR) |
|
||||
(uint32_t)(config->spi_mode << CTRL_CLKIDL) |
|
||||
CTRL_EN_MASK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See mss_qspi.h for details of how to use this function.
|
||||
*/
|
||||
void MSS_QSPI_get_config
|
||||
(
|
||||
mss_qspi_config_t* config
|
||||
)
|
||||
{
|
||||
volatile uint32_t reg =0;
|
||||
|
||||
reg = QSPI->CONTROL;
|
||||
|
||||
config->spi_mode = ((reg & CTRL_CLKIDL_MASK) >> CTRL_CLKIDL);
|
||||
reg = reg & (uint32_t )((uint32_t )CTRL_QMODE12_MASK | (uint32_t )CTRL_QMODE0_MASK);
|
||||
reg = reg >> CTRL_QMODE0;
|
||||
|
||||
config->io_format = (mss_qspi_io_format)reg;
|
||||
|
||||
config->clk_div = (mss_qspi_clk_div)((reg & CTRL_CLKRATE_MASK)
|
||||
>> CTRL_CLKRATE);
|
||||
config->xip = (uint8_t)((reg & CTRL_XIP_MASK) >> CTRL_XIP);
|
||||
config->xip_addr = (uint8_t)((reg & CTRL_XIPADDR_MASK) >> CTRL_XIPADDR);
|
||||
config->sample = (uint8_t)((reg & CTRL_SAMPLE_MASK) >> CTRL_SAMPLE);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See mss_qspi.h for details of how to use this function.
|
||||
*/
|
||||
void MSS_QSPI_polled_transfer_block
|
||||
(
|
||||
uint8_t num_addr_bytes,
|
||||
const void * const tx_buffer,
|
||||
uint32_t tx_byte_size,
|
||||
const void * const rd_buffer,
|
||||
uint32_t rd_byte_size,
|
||||
uint8_t num_idle_cycles
|
||||
)
|
||||
{
|
||||
uint32_t idx;
|
||||
uint8_t* buf8 = (uint8_t*)tx_buffer;
|
||||
uint32_t* buf32 = (uint32_t*)tx_buffer;
|
||||
volatile uint32_t skips;
|
||||
uint32_t cbytes;
|
||||
uint32_t total_byte_cnt;
|
||||
uint32_t words = 0u;
|
||||
|
||||
cbytes = 1u + tx_byte_size + num_addr_bytes;
|
||||
total_byte_cnt = 1u + tx_byte_size + num_addr_bytes + rd_byte_size;
|
||||
|
||||
QSPI->INTENABLE = 0u;
|
||||
|
||||
while ((QSPI->STATUS & STTS_READY_MASK) == 0u){};
|
||||
|
||||
/*bit16 to 31 define the number of Upper bytes when count is >65535
|
||||
Write to lower 16 bit is ignored*/
|
||||
QSPI->FRAMESUP = total_byte_cnt & QSPI_BYTESUPPER_MASK;
|
||||
|
||||
num_idle_cycles = (num_idle_cycles << 3u);
|
||||
|
||||
skips = (total_byte_cnt & 0x0000FFFFu);
|
||||
skips |= (cbytes << FRMS_CBYTES);
|
||||
skips |= (((QSPI->CONTROL & CTRL_QMODE12_MASK)? 1u:0u) << FRMS_QSPI);
|
||||
skips |= ((uint32_t)num_idle_cycles) << 23u;
|
||||
skips |= FRMS_FWORD_MASK;
|
||||
|
||||
QSPI->FRAMES = (uint32_t)skips;
|
||||
|
||||
QSPI->CONTROL |= CTRL_FLAGSX4_MASK;
|
||||
|
||||
words = cbytes / (uint32_t)4u;
|
||||
|
||||
for (idx = 0u; idx < words; ++idx)
|
||||
{
|
||||
while (QSPI->STATUS & STTS_TFFULL_MASK){};
|
||||
|
||||
QSPI->TXDATAX4 = (uint32_t)buf32[idx];
|
||||
}
|
||||
|
||||
QSPI->CONTROL &= ~CTRL_FLAGSX4_MASK;
|
||||
|
||||
for (idx = (cbytes - (cbytes % 4u)); idx < cbytes; ++idx)
|
||||
{
|
||||
while (QSPI->STATUS & STTS_TFFULL_MASK){};
|
||||
|
||||
QSPI->TXDATAX1 = (uint8_t)buf8[idx];
|
||||
}
|
||||
|
||||
buf32 = (uint32_t*)rd_buffer;
|
||||
buf8 = (uint8_t*)rd_buffer;
|
||||
|
||||
if (rd_byte_size)
|
||||
{
|
||||
words = rd_byte_size / 4u;
|
||||
|
||||
QSPI->CONTROL |= CTRL_FLAGSX4_MASK;
|
||||
|
||||
for (idx = 0u; idx < words; ++idx)
|
||||
{
|
||||
while (QSPI->STATUS & STTS_RFEMPTY_MASK){};
|
||||
buf32[idx] = QSPI->RXDATAX4;
|
||||
}
|
||||
|
||||
QSPI->CONTROL &= ~CTRL_FLAGSX4_MASK;
|
||||
|
||||
for (idx = (rd_byte_size - (rd_byte_size % 4u));
|
||||
idx < rd_byte_size; ++idx)
|
||||
{
|
||||
while (QSPI->STATUS & STTS_RFEMPTY_MASK){};
|
||||
buf8[idx] = QSPI->RXDATAX1;
|
||||
}
|
||||
|
||||
while (0u == (QSPI->STATUS & STTS_RDONE_MASK))
|
||||
{
|
||||
skips = (uint64_t)((QSPI->STATUS & STTS_FLAGSX4_MASK) ?
|
||||
QSPI->RXDATAX4 : QSPI->RXDATAX1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See mss_qspi.h for details of how to use this function.
|
||||
*/
|
||||
uint8_t MSS_QSPI_irq_transfer_block
|
||||
(
|
||||
uint8_t num_addr_bytes,
|
||||
const void * const tx_buffer,
|
||||
uint32_t tx_byte_size,
|
||||
const void * const rd_buffer,
|
||||
uint32_t rd_byte_size,
|
||||
uint8_t num_idle_cycles
|
||||
)
|
||||
{
|
||||
uint32_t idx;
|
||||
uint32_t cbytes;
|
||||
uint32_t total_byte_cnt;
|
||||
const uint8_t* buf8 = tx_buffer;
|
||||
const uint32_t* buf32 = tx_buffer;
|
||||
|
||||
uint8_t returnval = 0u;
|
||||
|
||||
|
||||
g_rd_buffer = (uint32_t*)rd_buffer;
|
||||
cbytes = 1u + tx_byte_size + num_addr_bytes;
|
||||
total_byte_cnt = 1u + tx_byte_size + num_addr_bytes + rd_byte_size;
|
||||
|
||||
if ((QSPI->STATUS & STTS_READY_MASK) == 0u)
|
||||
{
|
||||
returnval = 1u;
|
||||
}
|
||||
else
|
||||
{
|
||||
volatile uint32_t skips=0;
|
||||
uint32_t enable = 0u;
|
||||
|
||||
enable = INTE_TDONE_MASK;
|
||||
|
||||
/*bit16 to 31 define the number of Upper bytes when count is >65535
|
||||
Write to lower 16 bit is ignored*/
|
||||
QSPI->FRAMESUP = total_byte_cnt & QSPI_BYTESUPPER_MASK;
|
||||
num_idle_cycles = (num_idle_cycles << 3u);
|
||||
|
||||
skips = (total_byte_cnt & 0x0000FFFFu);
|
||||
skips |= (cbytes << FRMS_CBYTES);
|
||||
skips |= (((QSPI->CONTROL & CTRL_QMODE12_MASK)? 1u:0u) << FRMS_QSPI);
|
||||
skips |= ((uint32_t)num_idle_cycles) << 23u;
|
||||
skips |= FRMS_FWORD_MASK;
|
||||
|
||||
QSPI->FRAMES = skips;
|
||||
|
||||
QSPI->CONTROL |= CTRL_FLAGSX4_MASK;
|
||||
|
||||
if (rd_byte_size)
|
||||
{
|
||||
g_rx_complete = 0u;
|
||||
g_irq_rd_byte_size = rd_byte_size;
|
||||
|
||||
QSPI->CONTROL |= CTRL_FLAGSX4_MASK;
|
||||
|
||||
enable |= (uint32_t )((uint32_t )INTE_RDONE_MASK | (uint32_t )INTE_RAVLB_MASK);
|
||||
}
|
||||
|
||||
uint32_t words = 0u;
|
||||
words = cbytes / (uint32_t)4u;
|
||||
|
||||
for (idx = 0u; idx < words; ++idx)
|
||||
{
|
||||
while (QSPI->STATUS & STTS_TFFULL_MASK){};
|
||||
|
||||
QSPI->TXDATAX4 = (uint32_t)buf32[idx];
|
||||
}
|
||||
|
||||
QSPI->CONTROL &= ~CTRL_FLAGSX4_MASK;
|
||||
|
||||
for (idx = (cbytes - (cbytes % 4u)); idx < cbytes; ++idx)
|
||||
{
|
||||
while (QSPI->STATUS & STTS_TFFULL_MASK){};
|
||||
|
||||
QSPI->TXDATAX1 = (uint8_t)buf8[idx];
|
||||
}
|
||||
|
||||
QSPI->INTENABLE = enable;
|
||||
returnval = 0u;
|
||||
}
|
||||
|
||||
return(returnval);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* See mss_qspi.h for details of how to use this function.
|
||||
*/
|
||||
void MSS_QSPI_set_status_handler
|
||||
(
|
||||
mss_qspi_status_handler_t handler
|
||||
)
|
||||
{
|
||||
if ((mss_qspi_status_handler_t)0 != handler)
|
||||
{
|
||||
g_handler = handler;
|
||||
}
|
||||
}
|
||||
|
||||
static void qspi_isr(void)
|
||||
{
|
||||
uint32_t idx;
|
||||
static uint32_t empty = 0u;
|
||||
static uint32_t tx_fifo_full = 0u;
|
||||
uint32_t status;
|
||||
|
||||
status = QSPI->STATUS;
|
||||
|
||||
if (STTS_TDONE_MASK == (uint32_t)(status & STTS_TDONE_MASK))
|
||||
{
|
||||
g_handler(STTS_TDONE_MASK);
|
||||
QSPI->STATUS |= STTS_TDONE_MASK;
|
||||
}
|
||||
|
||||
if (STTS_RAVLB_MASK == (uint32_t)(status & STTS_RAVLB_MASK))
|
||||
{
|
||||
if (0u == g_rx_complete)
|
||||
{
|
||||
uint8_t* buf8 = g_rd_buffer;
|
||||
uint32_t* buf32 = g_rd_buffer;
|
||||
uint32_t words = 0u;
|
||||
|
||||
words = g_irq_rd_byte_size / 4u;
|
||||
|
||||
QSPI->CONTROL |= CTRL_FLAGSX4_MASK;
|
||||
|
||||
for (idx = 0u; idx < words; ++idx)
|
||||
{
|
||||
while (status & STTS_RFEMPTY_MASK){};
|
||||
|
||||
buf32[idx] = QSPI->RXDATAX4;
|
||||
}
|
||||
|
||||
QSPI->CONTROL &= ~CTRL_FLAGSX4_MASK;
|
||||
|
||||
for (idx = (g_irq_rd_byte_size - (g_irq_rd_byte_size % 4u));
|
||||
idx < g_irq_rd_byte_size; ++idx)
|
||||
{
|
||||
while (status & STTS_RFEMPTY_MASK){};
|
||||
|
||||
buf8[idx] = QSPI->RXDATAX1;
|
||||
}
|
||||
|
||||
uint32_t skips = 0;
|
||||
|
||||
while (0u == (QSPI->STATUS & STTS_RFEMPTY_MASK))
|
||||
{
|
||||
/*Make sure that the Receive FIFO is empty and any
|
||||
remaining data is read from it after desired bytes
|
||||
have been received.*/
|
||||
skips = (uint32_t)((QSPI->STATUS & STTS_FLAGSX4_MASK) ?
|
||||
QSPI->RXDATAX4 : QSPI->RXDATAX1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (STTS_RDONE_MASK == (uint32_t)(status & STTS_RDONE_MASK))
|
||||
{
|
||||
g_rx_complete = 1u;
|
||||
|
||||
/*This means receive transfer is now complete. invoke the callback
|
||||
* function*/
|
||||
g_handler(STTS_RDONE_MASK);
|
||||
|
||||
/*disable RXDONE, RXEMPTY, RXAVLBL interrupt*/
|
||||
QSPI->INTENABLE &= ~(INTE_RDONE_MASK | INTE_RAVLB_MASK);
|
||||
QSPI->STATUS |= STTS_RDONE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
static void default_status_hanlder(uint32_t value)
|
||||
{
|
||||
/*Take some default interrupt handling action here*/
|
||||
}
|
||||
|
||||
/*QSPI interrupt handler function*/
|
||||
uint8_t qspi_plic_IRQHandler(void)
|
||||
{
|
||||
qspi_isr();
|
||||
return (uint8_t)EXT_IRQ_KEEP_ENABLED;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,741 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
* PolarFire SoC (MPFS) Microprocessor SubSystem QSPI bare metal software
|
||||
* driver public API.
|
||||
*
|
||||
*/
|
||||
/*=========================================================================*//**
|
||||
@mainpage PolarFire SoC MSS QSPI Bare Metal Driver
|
||||
|
||||
==============================================================================
|
||||
Introduction
|
||||
==============================================================================
|
||||
The PolarFire SoC Microprocessor SubSystem (MSS) includes a QSPI controller
|
||||
for fast SPI transfers. The MSS QSPI is designed as a SPI master to work
|
||||
specifically with the (Q)SPI memory devices. The PolarFire SoC MSS QSPI driver
|
||||
provides a set of functions for controlling the MSS QSPI as part of a bare
|
||||
metal system, where no operating system is available. This driver can be
|
||||
adapted for use as part of an operating system, but the implementation of the
|
||||
adaptation layer between this driver and the operating system's driver model
|
||||
is outside the scope of this driver.
|
||||
|
||||
--------------------------------
|
||||
Features
|
||||
--------------------------------
|
||||
The PolarFire SoC MSS QSPI driver provides the following features:
|
||||
- QSPI Master operations in 1-bit, 2-bit, 4-bit formats and extended
|
||||
operations
|
||||
- XIP operations
|
||||
- Configurable SPI mode0 and mode3
|
||||
- Programmable SPI clock
|
||||
|
||||
==============================================================================
|
||||
Hardware Flow Dependencies
|
||||
==============================================================================
|
||||
The configuration of all the features of the MSS QSPI peripheral is covered by
|
||||
this driver, with the exception of the PolarFire SoC IOMUX configuration.
|
||||
The PolarFire SoC allows multiple non-concurrent uses of few external pins
|
||||
through IOMUX configuration. This feature allows optimization of external pin
|
||||
usage by assigning external pins for use by either the microprocessor
|
||||
subsystem or the FPGA fabric. The MSS QSPI serial signals are routed through
|
||||
IOMUXs to the PolarFire SoC device external pins. The MSS QSPI serial
|
||||
signals can also be routed through IOMUXs to the PolarFire SoC FPGA fabric.
|
||||
For more information on IOMUX, see the IOMUX section of the PolarFire SoC
|
||||
Microprocessor Subsystem (MSS) User's Guide.
|
||||
|
||||
The IOMUXs are configured using the PolarFire SoC MSS configurator tool. You
|
||||
must ensure that the MSS QSPI peripherals are enabled and configured in the
|
||||
PolarFire SoC MSS configurator if you wish to use them. For more information
|
||||
on IOMUXs, refer to the IOMUX section of the PolarFire SoC microprocessor
|
||||
Subsystem (MSS) User's Guide.
|
||||
|
||||
The base address and the register addresses are defined in this driver as
|
||||
constants. The interrupt number assignment for the MSS QSPI peripherals is
|
||||
defined as constants in the MPFS HAL. You must ensure that the latest MPFS HAL
|
||||
is included in the project settings of the SoftConsole toolchain and that it
|
||||
is generated into your project.
|
||||
|
||||
==============================================================================
|
||||
Theory of Operation
|
||||
==============================================================================
|
||||
The MSS QSPI driver functions are grouped into the following categories.
|
||||
- Initialization and configuration functions
|
||||
- Polled transmit and receive functions
|
||||
- Interrupt driven transmit and receive functions
|
||||
|
||||
--------------------------------
|
||||
Initialization and Configuration
|
||||
--------------------------------
|
||||
The MSS QSPI supports the following operations.
|
||||
- Normal SPI operations (1 bit)
|
||||
- Dual SPI operations (2 bit)
|
||||
- Quad SPI operations (4 bit)
|
||||
|
||||
The MSS QSPI driver provides the MSS_QSPI_init() function to initialize the
|
||||
MSS QSPI hardware block. This initialization function must be called before
|
||||
any other MSS QSPI driver functions can be called.
|
||||
|
||||
The MSS QSPI driver provides the MSS_QSPI_config() function to configure the
|
||||
MSS QSPI with desired configuration values. It also provides the
|
||||
MSS_QSPI_get_config() function to read back the current configurations of the
|
||||
MSS QSPI. You can use this function to retrieve the current configurations and
|
||||
then overwrite them with the application specific values, such as SPI mode,
|
||||
SPI clock rate, SDI sampling, QSPI operation, XIP mode and XIP address bits.
|
||||
All these configuration options are explained in detail in the API function
|
||||
description of the respective function.
|
||||
|
||||
--------------------------------------
|
||||
SPI master block transfer control
|
||||
--------------------------------------
|
||||
The driver can transmit and receive data when initialized and configured with
|
||||
the desired configuration values. The MSS QSPI is designed to specifically
|
||||
work with SPI flash memories. It supports a single, active-low slave-select
|
||||
output. Block transfers can be accomplished in the following ways.
|
||||
- Polled block transfer
|
||||
- Interrupt driven block transfer
|
||||
|
||||
---------------------------
|
||||
Polled block transfer
|
||||
---------------------------
|
||||
The MSS_QSPI_polled_transfer_block() is provided to accomplish data transfers
|
||||
where no interrupt is used. This function polls the status register to know
|
||||
the current status of the on-going transfer. This is a blocking
|
||||
function. A MSS QSPI block transfer always has some amount of data to be
|
||||
transmitted (at least one command byte) but receiving useful data from target
|
||||
memory device is optional. So, if the scheduled block transfer
|
||||
is only transferring data (and not receiving any data), then this function
|
||||
will exit after transmitting the required bytes. In a given transfer, if
|
||||
there is data to be received from the target memory device, then this function
|
||||
will exit when the expected data is received from the target memory device.
|
||||
|
||||
--------------------------------
|
||||
Interrupt driven block transfer
|
||||
--------------------------------
|
||||
This block transfer can be accomplished using interrupts instead of polling
|
||||
the status register. The Following functions are provided to support interrupt
|
||||
driven block transfers.
|
||||
- MSS_QSPI_irq_transfer_block()
|
||||
- MSS_QSPI_set_status_handler()
|
||||
|
||||
The MSS_QSPI_set_status_handler() function must be used to set a status handler
|
||||
call-back function with the driver. This function will be called-back by the
|
||||
driver at two different stages of the transfer. At the first stage, it will
|
||||
be called when the required number of bytes are transmitted. At the second
|
||||
stage, if there is data to be received from the target memory device then it
|
||||
will be called again when the desired data is received. Appropriate status
|
||||
value is passed by the driver as a parameter of this call-back function, so
|
||||
that the application can infer the event occurred.
|
||||
|
||||
-----------
|
||||
QSPI Status
|
||||
-----------
|
||||
The MSS_QSPI_read_status() function reads the current status of the MSS QSPI.
|
||||
This function can typically be used to know the status of the ongoing transfer.
|
||||
This function returns the status register value and can be called at any time
|
||||
after the MSS QSPI is initialized and configured.
|
||||
|
||||
-------------
|
||||
Direct Access
|
||||
-------------
|
||||
MSS QSPI allows direct access to the QSPI interface pins to support access to
|
||||
non-standard SPI devices via direct CPU control.
|
||||
|
||||
This driver provides following functions to read and write the direct access
|
||||
register of the MSS QSPI.
|
||||
- MSS_QSPI_read_direct_access_reg()
|
||||
- MSS_QSPI_write_direct_access_reg()
|
||||
|
||||
Using these functions, you can generate any sequence of binary transitions on
|
||||
the QSPI pins which might be needed to communicate with non-standard target
|
||||
devices.
|
||||
|
||||
*//*=========================================================================*/
|
||||
|
||||
#ifndef MSS_QSPI_H_
|
||||
#define MSS_QSPI_H_ 1
|
||||
|
||||
#include "drivers/mss_qspi/mss_qspi_regs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* The following constants can be used as input parameter value to configure the
|
||||
* event on which the SDI pin is sampled as shown below:
|
||||
* qspi_config.sample = MSS_QSPI_SAMPLE_POSAGE_SPICLK;
|
||||
* MSS_QSPI_configure(&qspi_config);
|
||||
*
|
||||
* */
|
||||
/* The SDI pin is sampled at the rising edge off SPI CLOCK */
|
||||
#define MSS_QSPI_SAMPLE_POSAGE_SPICLK 0x00u
|
||||
|
||||
/* The SDI pin is sampled on the last falling HCLK edge in the SPI clock period */
|
||||
#define MSS_QSPI_SAMPLE_ACTIVE_SPICLK 0x01u
|
||||
|
||||
/* The SDI pin is sampled at the rising HCLK edge as SPICLK falls */
|
||||
#define MSS_QSPI_SAMPLE_NEGAGE_SPICLK 0x02u
|
||||
|
||||
/* Public constant definitions
|
||||
* The following constants can be used to configure the MSS QSPI where a zero
|
||||
* or non-zero value such as enable or disable is to be provided as input
|
||||
* parameter as shown below:
|
||||
* qspi_config.xip = MSS_QSPI_DISABLE;
|
||||
* MSS_QSPI_configure(&qspi_config);
|
||||
*
|
||||
* */
|
||||
#define MSS_QSPI_ENABLE 0x01u
|
||||
#define MSS_QSPI_DISABLE 0x00u
|
||||
|
||||
/***************************************************************************//**
|
||||
These values are used to program the io_format parameter of the configuration
|
||||
structure of this driver as shown below:
|
||||
qspi_config.io_format = MSS_QSPI_QUAD_FULL;
|
||||
MSS_QSPI_configure(&qspi_config);
|
||||
|
||||
| Value | Description |
|
||||
|--------------------|----------------------------------------------------------|
|
||||
|MSS_QSPI_NORMAL | 1 bit Normal SPI operations |
|
||||
| | (single DQ0 TX and single DQ1 RX lines) |
|
||||
| | |
|
||||
|MSS_QSPI_DUAL_EX_RO | 2 bit SPI operations |
|
||||
| | (command and address bytes on DQ0 only. Data on DQ[1:0])|
|
||||
| | |
|
||||
|MSS_QSPI_QUAD_EX_RO | 4 bit SPI operations |
|
||||
| | (command and address bytes on DQ0 only. Data on DQ[3:0])|
|
||||
| | |
|
||||
|MSS_QSPI_DUAL_EX_RW | 2 bit SPI operations |
|
||||
| | (command byte on DQ0 only. Address and Data on DQ[1:0]) |
|
||||
| | |
|
||||
|MSS_QSPI_QUAD_EX_RW | 4 bit SPI operations |
|
||||
| | (command byte on DQ0 only. Address and Data on DQ[3:0]) |
|
||||
| | |
|
||||
|MSS_QSPI_DUAL_FULL | 2 bit SPI operations |
|
||||
| | (command, address and Data on DQ[1:0]) |
|
||||
| | |
|
||||
|MSS_QSPI_QUAD_FULL | 4 bit SPI operations |
|
||||
| | (command, address and Data on DQ[3:0]) |
|
||||
| | |
|
||||
|
||||
*/
|
||||
typedef enum mss_qspi_io_format_t
|
||||
{
|
||||
MSS_QSPI_NORMAL = 0u,
|
||||
MSS_QSPI_DUAL_EX_RO = 2u,
|
||||
MSS_QSPI_QUAD_EX_RO = 3u,
|
||||
MSS_QSPI_DUAL_EX_RW = 4u,
|
||||
MSS_QSPI_QUAD_EX_RW = 5u,
|
||||
MSS_QSPI_DUAL_FULL = 6u,
|
||||
MSS_QSPI_QUAD_FULL = 7u
|
||||
|
||||
} mss_qspi_io_format;
|
||||
|
||||
/***************************************************************************//**
|
||||
These values are used to program the spi_mode parameter of the configuration
|
||||
structure of this driver as shown below:
|
||||
qspi_config.spi_mode = MSS_QSPI_MODE0;
|
||||
MSS_QSPI_configure(&qspi_config);
|
||||
|
||||
| Value | Description |
|
||||
|-------------------|----------------------------------------------------------|
|
||||
| MSS_QSPI_MODE0 | Set clock IDLE to low (0) |
|
||||
| MSS_QSPI_MODE0 | Set clock IDLE to high (1) |
|
||||
|
||||
*/
|
||||
typedef enum mss_qspi_protocol_mode_t
|
||||
{
|
||||
MSS_QSPI_MODE0 = 0x0u,
|
||||
MSS_QSPI_MODE3 = 0x1u
|
||||
|
||||
} mss_qspi_protocol_mode;
|
||||
|
||||
/***************************************************************************//**
|
||||
These values are used to program the spi_mode parameter of the configuration
|
||||
structure of this driver as shown below:
|
||||
qspi_config.clk_div = MSS_QSPI_CLK_DIV_2;
|
||||
MSS_QSPI_configure(&qspi_config);
|
||||
|
||||
| Value | Description |
|
||||
|-----------------------|---------------------------|
|
||||
| MSS_QSPI_CLK_DIV_2 | Set SPI clock to HCLK/2 |
|
||||
| MSS_QSPI_CLK_DIV_4 | Set SPI clock to HCLK/4 |
|
||||
| MSS_QSPI_CLK_DIV_6 | Set SPI clock to HCLK/6 |
|
||||
| MSS_QSPI_CLK_DIV_8 | Set SPI clock to HCLK/8 |
|
||||
| MSS_QSPI_CLK_DIV_10 | Set SPI clock to HCLK/10 |
|
||||
| MSS_QSPI_CLK_DIV_12 | Set SPI clock to HCLK/12 |
|
||||
| MSS_QSPI_CLK_DIV_14 | Set SPI clock to HCLK/14 |
|
||||
| MSS_QSPI_CLK_DIV_16 | Set SPI clock to HCLK/16 |
|
||||
| MSS_QSPI_CLK_DIV_18 | Set SPI clock to HCLK/18 |
|
||||
| MSS_QSPI_CLK_DIV_20 | Set SPI clock to HCLK/20 |
|
||||
| MSS_QSPI_CLK_DIV_22 | Set SPI clock to HCLK/22 |
|
||||
| MSS_QSPI_CLK_DIV_24 | Set SPI clock to HCLK/24 |
|
||||
| MSS_QSPI_CLK_DIV_26 | Set SPI clock to HCLK/26 |
|
||||
| MSS_QSPI_CLK_DIV_28 | Set SPI clock to HCLK/28 |
|
||||
| MSS_QSPI_CLK_DIV_30 | Set SPI clock to HCLK/30 |
|
||||
|
||||
*/
|
||||
typedef enum mss_qspi_clk_div_t
|
||||
{
|
||||
MSS_QSPI_CLK_DIV_2 = 0x1u,
|
||||
MSS_QSPI_CLK_DIV_4 = 0x2u,
|
||||
MSS_QSPI_CLK_DIV_6 = 0x3u,
|
||||
MSS_QSPI_CLK_DIV_8 = 0x4u,
|
||||
MSS_QSPI_CLK_DIV_10 = 0x5u,
|
||||
MSS_QSPI_CLK_DIV_12 = 0x6u,
|
||||
MSS_QSPI_CLK_DIV_14 = 0x7u,
|
||||
MSS_QSPI_CLK_DIV_16 = 0x8u,
|
||||
MSS_QSPI_CLK_DIV_18 = 0x9u,
|
||||
MSS_QSPI_CLK_DIV_20 = 0xAu,
|
||||
MSS_QSPI_CLK_DIV_22 = 0xBu,
|
||||
MSS_QSPI_CLK_DIV_24 = 0xCu,
|
||||
MSS_QSPI_CLK_DIV_26 = 0xDu,
|
||||
MSS_QSPI_CLK_DIV_28 = 0xEu,
|
||||
MSS_QSPI_CLK_DIV_30 = 0xFu
|
||||
|
||||
} mss_qspi_clk_div;
|
||||
|
||||
/***************************************************************************//**
|
||||
This prototype defines the function prototype that must be followed by MSS QSPI
|
||||
status handler functions. This function is registered with the MSS QSPI driver
|
||||
through a call to the MSS_QSPI_set_status_handler() function.
|
||||
|
||||
Declaring and Implementing Status Handler Function:
|
||||
Slave frame receive handler functions should follow the following prototype.
|
||||
void transfer_status_handler(uint32_t status);
|
||||
|
||||
The actual name of the status handler is unimportant. You can use any name
|
||||
of your choice. The status parameter will contain a value indicating which
|
||||
of the TX-DONE, RX-DONE event has caused the interrupt.
|
||||
*/
|
||||
typedef void (*mss_qspi_status_handler_t)(uint32_t status);
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
MSS QSPI configuration structure.
|
||||
This is structure definition for MSS QSPI configuration instance. It defines
|
||||
the configuration data to be exchanged by the application with the driver.
|
||||
|
||||
Configuration options for MSS QSPI
|
||||
|
||||
| Parameter | Description |
|
||||
|-------------|----------------------------------------------------------------|
|
||||
| xip | Enable or disable XIP mode |
|
||||
| xip_addr | Number of address bytes used in XIP mode |
|
||||
| spi_mode | Select either Motorola mode0 or mode3 |
|
||||
| clk_div | HCLK Clock divider for generating SPI clock |
|
||||
| io_format | QSPI transfer format, extended,dual,quad etc. |
|
||||
| sample | Select the event on which the QSPI samples the incoming data |
|
||||
|
||||
*/
|
||||
typedef struct mss_qspi_config{
|
||||
uint8_t xip;
|
||||
uint8_t xip_addr;
|
||||
mss_qspi_protocol_mode spi_mode; /*clkidl mode0 or mode3*/
|
||||
mss_qspi_clk_div clk_div;
|
||||
mss_qspi_io_format io_format;
|
||||
uint8_t sample;
|
||||
}mss_qspi_config_t;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*------------------------MSS QSPI internal structures ---------------------*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*Register map of the PolarFire SoC MSS QSPI*/
|
||||
typedef struct
|
||||
{
|
||||
volatile uint32_t CONTROL;
|
||||
volatile uint32_t FRAMES;
|
||||
volatile uint32_t RESERVED1;
|
||||
volatile uint32_t INTENABLE;
|
||||
volatile uint32_t STATUS;
|
||||
volatile uint32_t DIRECT;
|
||||
volatile uint8_t ADDRUP;
|
||||
volatile uint8_t ADDRUP_R1;
|
||||
volatile uint8_t ADDRUP_R2;
|
||||
volatile uint8_t ADDRUP_R3;
|
||||
volatile uint32_t RESERVED2[9];
|
||||
volatile uint8_t RXDATAX1;
|
||||
volatile uint8_t RXDATAX1_R1;
|
||||
volatile uint8_t RXDATAX1_R2;
|
||||
volatile uint8_t RXDATAX1_R3;
|
||||
volatile uint8_t TXDATAX1;
|
||||
volatile uint8_t TXDATAX1_R1;
|
||||
volatile uint8_t TXDATAX1_R2;
|
||||
volatile uint8_t TXDATAX1_R3;
|
||||
volatile uint32_t RXDATAX4;
|
||||
volatile uint32_t TXDATAX4;
|
||||
volatile uint32_t FRAMESUP;
|
||||
|
||||
} QSPI_TypeDef;
|
||||
|
||||
/*PolarFire SoC MSS QSPI base memory address*/
|
||||
#define QSPI_BASE 0x21000000u
|
||||
|
||||
/*PolarFire SoC MSS QSPI hardware instance*/
|
||||
#define QSPI ((QSPI_TypeDef *) QSPI_BASE)
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*------------------------MSS QSPI Public APIs--------------------------------*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
The MSS_QSPI_init() function initializes and enables the PolarFireSoC MSS QSPI.
|
||||
|
||||
It enables the MSS QSPI hardware block, and configures it with the default
|
||||
values.
|
||||
|
||||
@param
|
||||
This function takes no function parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
@code
|
||||
@endcode
|
||||
*/
|
||||
void MSS_QSPI_init
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
The MSS_QSPI_enable() function enables the MSS QSPI hardware block.
|
||||
|
||||
@param
|
||||
This function takes no function parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
@code
|
||||
@endcode
|
||||
*/
|
||||
static inline void MSS_QSPI_enable(void)
|
||||
{
|
||||
QSPI->CONTROL |= CTRL_EN_MASK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
The MSS_QSPI_disable() function disables the MSS QSPI hardware block.
|
||||
|
||||
@param
|
||||
This function takes no function parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
@code
|
||||
@endcode
|
||||
*/
|
||||
static inline void MSS_QSPI_disable(void)
|
||||
{
|
||||
QSPI->CONTROL &= ~CTRL_EN_MASK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
The MSS_QSPI_configure() function configures the MSS QSPI to desired
|
||||
configuration values.
|
||||
|
||||
@param config
|
||||
The config parameter is a pointer to the mss_qspi_config_t structure, which
|
||||
provides new configuration values. See the mss_qspi_config_t section for
|
||||
details.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
@code
|
||||
@endcode
|
||||
*/
|
||||
void MSS_QSPI_configure
|
||||
(
|
||||
const mss_qspi_config_t* config
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
The MSS_QSPI_get_config() function reads-back the current configurations of
|
||||
the MSS QSPI. This function can be used when you want to read the current
|
||||
configurations, modify the configuration values of your choice and reconfigure
|
||||
the MSS QSPI hardware, using MSS_QSPI_configure() function.
|
||||
|
||||
@param config
|
||||
The config parameter is a pointer to an mss_qspi_config_t structure in which
|
||||
the current configuration values of the MSS QSPI are returned.
|
||||
|
||||
Please see description of mss_qspi_config_t for more details.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
@code
|
||||
@endcode
|
||||
*/
|
||||
void MSS_QSPI_get_config
|
||||
(
|
||||
mss_qspi_config_t* config
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
The MSS_QSPI_polled_transfer_block() function is used to carry out a QSPI
|
||||
transfer with the target memory device using polling method of data transfer.
|
||||
The QSPI transfer characteristics are configured every time a new transfer is
|
||||
initiated. This is a blocking function.
|
||||
|
||||
@param num_addr_bytes
|
||||
The num_addr_bytes parameter indicates the number of address bytes to be
|
||||
used while transacting with the target memory device. Depending on the
|
||||
target memory device, the address within the target memory device can be
|
||||
either 3 or 4 bytes long. You must make sure that you provide the exact same
|
||||
number with which the target memory device is configured.
|
||||
|
||||
Note: Few command opcodes do not require specified addresses. For example
|
||||
READ_ID. For such commands the num_addr_bytes parameter must be set to 0x0.
|
||||
|
||||
@param target_mem_addr
|
||||
The target_mem_addr parameter is the memory address in the target memory
|
||||
device on which the read/write operation is to be carried out.
|
||||
|
||||
@param tx_buffer
|
||||
The tx_buffer parameter is the pointer to the buffer from which the data
|
||||
needs to transmitted to the target memory device.
|
||||
|
||||
@param tx_byte_size
|
||||
The tx_byte_size parameter is the exact number of bytes that needs to be
|
||||
transmitted to the target memory device.
|
||||
|
||||
Note: This parameter must not consider the command opcode and address bytes
|
||||
as part of the data that needs to be transmitted.
|
||||
|
||||
@param rd_buffer
|
||||
The rd_buffer parameter is the pointer to the buffer where the data returned
|
||||
by the target memory device is to be stored.
|
||||
|
||||
@param rd_byte_size
|
||||
The rd_byte_size parameter is the exact number of bytes that needs to be
|
||||
received from the target memory device.
|
||||
|
||||
@param num_idle_cycles
|
||||
The num_idle_cycles parameter indicates the number of Idle cycles/dummy clock
|
||||
edges that must be generated after the address bytes are transmitted and
|
||||
before target memory device starts sending data. This must be correctly set
|
||||
based on the target memory device and the SPI command being used – this may
|
||||
also vary based on SPI clock and the way the target memory device is
|
||||
configured.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
@code
|
||||
@endcode
|
||||
*/
|
||||
void MSS_QSPI_polled_transfer_block
|
||||
(
|
||||
uint8_t num_addr_bytes,
|
||||
const void * const tx_buffer,
|
||||
uint32_t tx_byte_size,
|
||||
const void * const rd_buffer,
|
||||
uint32_t rd_byte_size,
|
||||
uint8_t num_idle_cycles
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
The MSS_QSPI_irq_transfer_block() function is used to carry out a QSPI transfer
|
||||
with the target memory device using interrupt method of data transfers.
|
||||
The QSPI transfer characteristics are configured every time a new transfer is
|
||||
initiated. This is non-blocking function. You must configure the interrupt
|
||||
handler function, before calling this function.It will enable the interrupts
|
||||
and start transmitting as many bytes as requested. You will get an indication
|
||||
when the actual SPI transmit operation is complete when The transmit-done
|
||||
interrupt event occurs and this driver calls-back the interrupt handler
|
||||
function that you previously provided. If the transfer includes receiving
|
||||
data from the target memory device then the receive-available and receive-done
|
||||
interrupts are also enabled by this function. The data will be received in the
|
||||
interrupt routine. The interrupt handler provided by you will be called-back
|
||||
again when the receive-done interrupt event occurs.
|
||||
|
||||
@param num_addr_bytes
|
||||
The num_addr_bytes parameter indicates the number of address bytes to be
|
||||
used while transacting with the target memory device. Depending on the the
|
||||
target memory device, the address within the target memory device can be
|
||||
either 3 or 4 bytes long. You must make sure that you provide the exact
|
||||
same number with which the target memory device is configured.
|
||||
|
||||
Note: There will be some command opcodes for which no address needs to be
|
||||
specified. e.g. READ_ID. For such commands the num_addr_bytes parameter
|
||||
must be set to 0x0.
|
||||
|
||||
@param target_mem_addr
|
||||
The target_mem_addr parameter is the memory address in the target memory
|
||||
device on which the read/write operation is to be carried out.
|
||||
|
||||
@param tx_buffer
|
||||
The tx_buffer parameter is the pointer to the buffer from which the data
|
||||
needs to transmitted to the target QSPI memory.
|
||||
|
||||
@param tx_byte_size
|
||||
The tx_byte_size parameter is the exact number of bytes that needs to be
|
||||
transmitted to target memory device.
|
||||
|
||||
Note: This parameter must not consider the command opcode and address bytes
|
||||
as part of the data that needs to be transmitted.
|
||||
|
||||
@param rd_buffer
|
||||
The rd_buffer parameter is the pointer to the buffer where the data returned
|
||||
by the target memory device is to be stored.
|
||||
|
||||
@param rd_byte_size
|
||||
The rd_byte_size parameter is the exact number of bytes that needs to be
|
||||
received from the target memory device.
|
||||
|
||||
@param num_idle_cycles
|
||||
The num_idle_cycles parameter indicates the The number of IDLE/dummy clock
|
||||
edges that must be generated after the address bytes are transmitted and
|
||||
before target memory device starts sending data. This must be correctly set
|
||||
based on the target memory device and the SPI command being used – this may
|
||||
also vary based on SPI clock and the way the target memory device is
|
||||
configured.
|
||||
|
||||
@return
|
||||
This function a non-zero value if the MSS QSPI is busy completing the
|
||||
previous transfer and can not accept a new transfer. A zero return value
|
||||
indicates successful execution of this function.
|
||||
|
||||
Example:
|
||||
@code
|
||||
@endcode
|
||||
*/
|
||||
uint8_t MSS_QSPI_irq_transfer_block
|
||||
(
|
||||
uint8_t num_addr_bytes,
|
||||
const void * const tx_buffer,
|
||||
uint32_t tx_byte_size,
|
||||
const void * const rd_buffer,
|
||||
uint32_t rd_byte_size,
|
||||
uint8_t num_idle_cycles
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
The MSS_QSPI_set_status_handler() function registers an interrupt handler
|
||||
function with this driver which is used to indicate the interrupt status back
|
||||
to the application. This status handler function is called by this driver in
|
||||
two events. First, when the transmission of required bytes is completed
|
||||
(Transmit-Done). Second, if data is to be received from the target memory
|
||||
device then this function is called again when required data is received
|
||||
(Receive-Done).
|
||||
|
||||
@param handler
|
||||
The handler parameter is the interrupt handler function of the type
|
||||
mss_qspi_status_handler_t which needs to be registered.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
@code
|
||||
@endcode
|
||||
*/
|
||||
void MSS_QSPI_set_status_handler
|
||||
(
|
||||
mss_qspi_status_handler_t handler
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
The MSS_QSPI_read_direct_access_reg() reads the current value of the direct
|
||||
access register(DAR) of the MSS QSPI. DAR allows direct access to the QSPI
|
||||
interface pins to support access to non-standard SPI devices through direct
|
||||
CPU control.
|
||||
|
||||
@param
|
||||
This function takes no function parameters.
|
||||
|
||||
@return
|
||||
This function returns the current value of the DAR of the MSS QSPI.
|
||||
|
||||
Example:
|
||||
@code
|
||||
@endcode
|
||||
*/
|
||||
static inline uint32_t MSS_QSPI_read_direct_access_reg(void)
|
||||
{
|
||||
return(QSPI->DIRECT);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
The MSS_QSPI_write_direct_access_reg() to write a value of the DAR of the MSS
|
||||
QSPI. DAR allows direct access to the QSPI interface pins, to support access
|
||||
to non-standard SPI devices through direct CPU control.
|
||||
|
||||
@param value
|
||||
The value parameter is the value that needs to be set into the direct access
|
||||
register of the MSS QSPI.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
@code
|
||||
@endcode
|
||||
*/
|
||||
static inline void MSS_QSPI_write_direct_access_reg(uint32_t value)
|
||||
{
|
||||
QSPI->DIRECT = value;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
The function MSS_QSPI_read_status() is used to read the status of the MSS QSPI.
|
||||
This function returns the status register value and can be called any time
|
||||
after the MSS QSPI is initialized and configured.
|
||||
|
||||
@param
|
||||
This function takes no function parameters.
|
||||
|
||||
@return
|
||||
This function returns the the current value of the status register of the
|
||||
MSS QSPI.
|
||||
|
||||
Example:
|
||||
@code
|
||||
@endcode
|
||||
*/
|
||||
static inline uint32_t MSS_QSPI_read_status(void)
|
||||
{
|
||||
return(QSPI->STATUS);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_QSPI_H_*/
|
|
@ -0,0 +1,142 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Register bit offsets and masks definitions for PolarFire SoC(MPFS) MSS QSPI.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#ifndef MSS_QSPI_REGS_H_
|
||||
#define MSS_QSPI_REGS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
Register Bit definitions
|
||||
*/
|
||||
#define CTRL_EN 0u
|
||||
#define CTRL_XIP 2u
|
||||
#define CTRL_XIPADDR 3u
|
||||
#define CTRL_CLKIDL 10u
|
||||
#define CTRL_SAMPLE 11u
|
||||
#define CTRL_QMODE0 13u
|
||||
#define CTRL_QMODE12 14u
|
||||
#define CTRL_FLAGSX4 16u
|
||||
#define CTRL_CLKRATE 24u
|
||||
|
||||
#define CTRL_EN_MASK (0x1u << CTRL_EN)
|
||||
#define CTRL_XIP_MASK (0x1u << CTRL_XIP)
|
||||
#define CTRL_XIPADDR_MASK (0x1u << CTRL_XIPADDR)
|
||||
#define CTRL_CLKIDL_MASK (0x1u << CTRL_CLKIDL)
|
||||
#define CTRL_SAMPLE_MASK (0x3u << CTRL_SAMPLE)
|
||||
#define CTRL_QMODE0_MASK (0x1u << CTRL_QMODE0)
|
||||
#define CTRL_QMODE12_MASK (0x3u << CTRL_QMODE12)
|
||||
#define CTRL_FLAGSX4_MASK (0x1u << CTRL_FLAGSX4)
|
||||
#define CTRL_CLKRATE_MASK (0xFu << CTRL_CLKRATE)
|
||||
|
||||
#define CTRL_SAMPLE_SCK (0x0u << CTRL_SAMPLE)
|
||||
#define CTRL_SAMPLE_HCLKF (0x1u << CTRL_SAMPLE)
|
||||
#define CTRL_SAMPLE_HCLKR (0x2u << CTRL_SAMPLE)
|
||||
|
||||
#define FRMS_TBYTES 0u
|
||||
#define FRMS_CBYTES 16u
|
||||
#define FRMS_QSPI 25u
|
||||
#define FRMS_IDLE 26u
|
||||
#define FRMS_FBYTE 30u
|
||||
#define FRMS_FWORD 31u
|
||||
|
||||
#define FRMS_TBYTES_MASK (0xFFFFu << FRMS_TBYTES)
|
||||
#define FRMS_CBYTES_MASK (0x1FFu << FRMS_CBYTES)
|
||||
#define FRMS_QXIP_MASK (0x1u << FRMS_QXIP)
|
||||
#define FRMS_IDLE_MASK (0xFu << FRMS_IDLE)
|
||||
#define FRMS_FBYTE_MASK (0x1u << FRMS_FBYTE)
|
||||
#define FRMS_FWORD_MASK (0x1u << FRMS_FWORD)
|
||||
|
||||
#define INTE_TDONE 0u
|
||||
#define INTE_RDONE 1u
|
||||
#define INTE_RAVLB 2u
|
||||
#define INTE_TAVLB 3u
|
||||
#define INTE_RFEMPTY 4u
|
||||
#define INTE_TFFULL 5u
|
||||
|
||||
#define INTE_TDONE_MASK (0x1u << INTE_TDONE)
|
||||
#define INTE_RDONE_MASK (0x1u << INTE_RDONE)
|
||||
#define INTE_RAVLB_MASK (0x1u << INTE_RAVLB)
|
||||
#define INTE_TAVLB_MASK (0x1u << INTE_TAVLB)
|
||||
#define INTE_RFEMPTY_MASK (0x1u << INTE_RFEMPTY)
|
||||
#define INTE_TFFULL_MASK (0x1u << INTE_TFFULL)
|
||||
|
||||
|
||||
#define STTS_TDONE 0u
|
||||
#define STTS_RDONE 1u
|
||||
#define STTS_RAVLB 2u
|
||||
#define STTS_TAVLB 3u
|
||||
#define STTS_RFEMPTY 4u
|
||||
#define STTS_TFFULL 5u
|
||||
#define STTS_READY 7u
|
||||
#define STTS_FLAGSX4 8u
|
||||
|
||||
#define STTS_TDONE_MASK (0x1u << STTS_TDONE)
|
||||
#define STTS_RDONE_MASK (0x1u << STTS_RDONE)
|
||||
#define STTS_RAVLB_MASK (0x1u << STTS_RAVLB)
|
||||
#define STTS_TAVLB_MASK (0x1u << STTS_TAVLB)
|
||||
#define STTS_RFEMPTY_MASK (0x1u << STTS_RFEMPTY)
|
||||
#define STTS_TFFULL_MASK (0x1u << STTS_TFFULL)
|
||||
#define STTS_READY_MASK (0x1u << STTS_READY)
|
||||
#define STTS_FLAGSX4_MASK (0x1u << STTS_FLAGSX4)
|
||||
|
||||
|
||||
#define RDAT 0u
|
||||
|
||||
#define RDAT_MASK 0xFFu
|
||||
|
||||
#define TDAT 0u
|
||||
|
||||
#define TDAT_MASK 0xFFu
|
||||
|
||||
#define X4RDAT 0u
|
||||
|
||||
#define X4RDAT_MASK 0xFFFFFFFFu
|
||||
|
||||
#define X4TDAT 0u
|
||||
|
||||
#define X4TDAT_MASK 0xFFFFFFFFu
|
||||
|
||||
#define DIRECT_EN_SSEL 0u
|
||||
#define DIRECT_OP_SSEL 1u
|
||||
#define DIRECT_EN_SCLK 2u
|
||||
#define DIRECT_OP_SCLK 3u
|
||||
#define DIRECT_EN_SDO 4u
|
||||
#define DIRECT_OP_SDO 8u
|
||||
#define DIRECT_OP_SDOE 12u
|
||||
#define DIRECT_IP_SDI 16u
|
||||
#define DIRECT_Reserved 20u
|
||||
#define DIRECT_IP_SCLK 21u
|
||||
#define DIRECT_IP_SSEL 22u
|
||||
#define DIRECT_IDLE 23u
|
||||
|
||||
#define DIRECT_EN_SSEL_MASK (0x1u << DIRECT_EN_SSEL)
|
||||
#define DIRECT_OP_SSEL_MASK (0x1u << DIRECT_OP_SSEL)
|
||||
#define DIRECT_EN_SCLK_MASK (0x1u << DIRECT_EN_SCLK)
|
||||
#define DIRECT_OP_SCLK_MASK (0x1u << DIRECT_OP_SCLK)
|
||||
#define DIRECT_EN_SDO_MASK (0xFu << DIRECT_EN_SDO)
|
||||
#define DIRECT_OP_SDO_MASK (0xFu << DIRECT_OP_SDO)
|
||||
#define DIRECT_OP_SDOE_MASK (0xFu << DIRECT_OP_SDOE)
|
||||
#define DIRECT_IP_SDI_MASK (0xFu << DIRECT_IP_SDI)
|
||||
#define DIRECT_Reserved_MASK (0x1u << DIRECT_Reserved)
|
||||
#define DIRECT_IP_SCLK_MASK (0x1u << DIRECT_IP_SCLK)
|
||||
#define DIRECT_IP_SSEL_MASK (0x1u << DIRECT_IP_SSEL)
|
||||
#define DIRECT_IDLE_MASK (0x1u << DIRECT_IDLE)
|
||||
|
||||
|
||||
#define UADDAR 0u
|
||||
#define UADDAR_MASK 0xFFu
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_QSPI_REGS_H_ */
|
|
@ -0,0 +1,667 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* PoalrFire SoC Microprocessor Subsystem RTC bare metal driver implementation.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
#include "mss_rtc_regs.h"
|
||||
#include "mss_rtc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* CONTROL_REG register masks.
|
||||
*/
|
||||
#define CONTROL_RUNNING_MASK 0x00000001u
|
||||
#define CONTROL_RTC_START_MASK 0x00000001u
|
||||
#define CONTROL_RTC_STOP_MASK 0x00000002u
|
||||
#define CONTROL_ALARM_ON_MASK 0x00000004u
|
||||
#define CONTROL_ALARM_OFF_MASK 0x00000008u
|
||||
#define CONTROL_RESET_MASK 0x00000010u
|
||||
#define CONTROL_UPLOAD_MASK 0x00000020u
|
||||
#define CONTROL_WAKEUP_CLR_MASK 0x00000100u
|
||||
#define CONTROL_UPDATED_MASK 0x00000400u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MODE_REG register masks.
|
||||
*/
|
||||
#define MODE_CLK_MODE_MASK 0x00000001u
|
||||
#define MODE_WAKEUP_EN_MASK 0x00000002u
|
||||
#define MODE_WAKEUP_RESET_MASK 0x00000004u
|
||||
#define MODE_WAKEUP_CONTINUE_MASK 0x00000008u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Other masks.
|
||||
*/
|
||||
#define MAX_BINARY_HIGHER_COUNT 0x7FFu
|
||||
#define MASK_32_BIT 0xFFFFFFFFu
|
||||
#define MAX_PRESCALAR_COUNT 0x03FFFFFFu
|
||||
#define CALENDAR_SHIFT 8u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Index into look-up table.
|
||||
*/
|
||||
#define SECONDS 0
|
||||
#define MINUTES 1
|
||||
#define HOURS 2
|
||||
#define DAYS 3
|
||||
#define MONTHS 4
|
||||
#define YEARS 5
|
||||
#define WEEKDAYS 6
|
||||
#define WEEKS 7
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* A pointer to the RTC_TypeDef structure is used to configure the user selected
|
||||
* RTC. This pointer is used by all the mss RTC driver function to carry out the
|
||||
* required functionality.
|
||||
*/
|
||||
RTC_TypeDef * mss_rtc;
|
||||
|
||||
static uint8_t
|
||||
get_clock_mode
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
static void
|
||||
set_rtc_mode
|
||||
(
|
||||
uint8_t requested_mode
|
||||
);
|
||||
|
||||
static void add_alarm_cfg_values
|
||||
(
|
||||
uint8_t calendar_item,
|
||||
uint32_t * p_calendar_value,
|
||||
uint32_t * p_compare_mask
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_init
|
||||
(
|
||||
RTC_TypeDef *base_address,
|
||||
uint8_t mode,
|
||||
uint32_t prescaler
|
||||
)
|
||||
{
|
||||
ASSERT(prescaler <= MAX_PRESCALAR_COUNT);
|
||||
|
||||
/* Assigning the user selected MSS RTC base address to global RTC structure
|
||||
* pointer so that the other driver functions can use it.
|
||||
*/
|
||||
mss_rtc = base_address;
|
||||
|
||||
if (prescaler <= MAX_PRESCALAR_COUNT)
|
||||
{
|
||||
/* Stop the RTC. */
|
||||
MSS_RTC_stop();
|
||||
|
||||
/* Disable alarm. */
|
||||
mss_rtc->CONTROL_REG = CONTROL_ALARM_OFF_MASK;
|
||||
|
||||
/* Disable Interrupt */
|
||||
MSS_RTC_disable_irq();
|
||||
|
||||
/* Clear RTC wake up interrupt signal */
|
||||
MSS_RTC_clear_irq();
|
||||
|
||||
/* Select mode of operation, including the wake configuration. */
|
||||
if (MSS_RTC_CALENDAR_MODE == mode)
|
||||
{
|
||||
mss_rtc->MODE_REG = MODE_CLK_MODE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
mss_rtc->MODE_REG = 0u;
|
||||
}
|
||||
|
||||
/* Reset the alarm and compare registers to a known value. */
|
||||
mss_rtc->ALARM_LOWER_REG = 0u;
|
||||
mss_rtc->ALARM_UPPER_REG = 0u;
|
||||
mss_rtc->COMPARE_LOWER_REG = 0u;
|
||||
mss_rtc->COMPARE_UPPER_REG = 0u;
|
||||
|
||||
/* Reset the calendar counters */
|
||||
MSS_RTC_reset_counter();
|
||||
|
||||
/* Set new Prescaler value */
|
||||
mss_rtc->PRESCALER_REG = prescaler;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_set_calendar_count
|
||||
(
|
||||
const mss_rtc_calender_t *new_rtc_value
|
||||
)
|
||||
{
|
||||
uint8_t error = 0u;
|
||||
uint8_t clock_mode;
|
||||
|
||||
const uint8_t g_rtc_max_count_lut[] =
|
||||
{
|
||||
/* Calendar mode */
|
||||
59u, /* Seconds */
|
||||
59u, /* Minutes */
|
||||
23u, /* Hours */
|
||||
31u, /* Days */
|
||||
12u, /* Months */
|
||||
254u, /* Years */
|
||||
7u, /* Weekdays */
|
||||
52u /* Week */
|
||||
};
|
||||
|
||||
const uint8_t g_rtc_min_count_lut[] =
|
||||
{
|
||||
/* Calendar mode */
|
||||
0u, /* Seconds */
|
||||
0u, /* Minutes */
|
||||
0u, /* Hours */
|
||||
1u, /* Days */
|
||||
1u, /* Months */
|
||||
0u, /* Years */
|
||||
1u, /* Weekdays */
|
||||
1u /* Week */
|
||||
};
|
||||
|
||||
/* Assert if the values cross the limit */
|
||||
ASSERT(new_rtc_value->second >= g_rtc_min_count_lut[SECONDS]);
|
||||
ASSERT(new_rtc_value->second <= g_rtc_max_count_lut[SECONDS]);
|
||||
ASSERT(new_rtc_value->minute >= g_rtc_min_count_lut[MINUTES]);
|
||||
ASSERT(new_rtc_value->minute <= g_rtc_max_count_lut[MINUTES]);
|
||||
ASSERT(new_rtc_value->hour >= g_rtc_min_count_lut[HOURS]);
|
||||
ASSERT(new_rtc_value->hour <= g_rtc_max_count_lut[HOURS]);
|
||||
ASSERT(new_rtc_value->day >= g_rtc_min_count_lut[DAYS]);
|
||||
ASSERT(new_rtc_value->day <= g_rtc_max_count_lut[DAYS]);
|
||||
ASSERT(new_rtc_value->month >= g_rtc_min_count_lut[MONTHS]);
|
||||
ASSERT(new_rtc_value->month <= g_rtc_max_count_lut[MONTHS]);
|
||||
ASSERT(new_rtc_value->year >= g_rtc_min_count_lut[YEARS]);
|
||||
ASSERT(new_rtc_value->year <= g_rtc_max_count_lut[YEARS]);
|
||||
ASSERT(new_rtc_value->weekday >= g_rtc_min_count_lut[WEEKDAYS]);
|
||||
ASSERT(new_rtc_value->weekday <= g_rtc_max_count_lut[WEEKDAYS]);
|
||||
ASSERT(new_rtc_value->week >= g_rtc_min_count_lut[WEEKS]);
|
||||
ASSERT(new_rtc_value->week <= g_rtc_max_count_lut[WEEKS]);
|
||||
|
||||
if (new_rtc_value->second < g_rtc_min_count_lut[SECONDS]) {error = 1u;}
|
||||
if (new_rtc_value->second > g_rtc_max_count_lut[SECONDS]) {error = 1u;}
|
||||
if (new_rtc_value->minute < g_rtc_min_count_lut[MINUTES]) {error = 1u;}
|
||||
if (new_rtc_value->minute > g_rtc_max_count_lut[MINUTES]) {error = 1u;}
|
||||
if (new_rtc_value->hour < g_rtc_min_count_lut[HOURS]) {error = 1u;}
|
||||
if (new_rtc_value->hour > g_rtc_max_count_lut[HOURS]) {error = 1u;}
|
||||
if (new_rtc_value->day < g_rtc_min_count_lut[DAYS]) {error = 1u;}
|
||||
if (new_rtc_value->day > g_rtc_max_count_lut[DAYS]) {error = 1u;}
|
||||
if (new_rtc_value->month < g_rtc_min_count_lut[MONTHS]) {error = 1u;}
|
||||
if (new_rtc_value->month > g_rtc_max_count_lut[MONTHS]) {error = 1u;}
|
||||
if (new_rtc_value->year < g_rtc_min_count_lut[YEARS]) {error = 1u;}
|
||||
if (new_rtc_value->year > g_rtc_max_count_lut[YEARS]) {error = 1u;}
|
||||
if (new_rtc_value->weekday < g_rtc_min_count_lut[WEEKDAYS]) {error = 1u;}
|
||||
if (new_rtc_value->weekday > g_rtc_max_count_lut[WEEKDAYS]) {error = 1u;}
|
||||
if (new_rtc_value->week < g_rtc_min_count_lut[WEEKS]) {error = 1u;}
|
||||
if (new_rtc_value->week > g_rtc_max_count_lut[WEEKS]) {error = 1u;}
|
||||
|
||||
/* This function can only be used when the RTC is configured to operate in
|
||||
* calendar counter mode. */
|
||||
clock_mode = get_clock_mode();
|
||||
ASSERT(MSS_RTC_CALENDAR_MODE == clock_mode);
|
||||
|
||||
if ((0u == error) && (MSS_RTC_CALENDAR_MODE == clock_mode))
|
||||
{
|
||||
uint32_t upload_in_progress;
|
||||
|
||||
/* Write the RTC new value. */
|
||||
mss_rtc->SECONDS_REG = new_rtc_value->second;
|
||||
mss_rtc->MINUTES_REG = new_rtc_value->minute;
|
||||
mss_rtc->HOURS_REG = new_rtc_value->hour;
|
||||
mss_rtc->DAY_REG = new_rtc_value->day;
|
||||
mss_rtc->MONTH_REG = new_rtc_value->month;
|
||||
mss_rtc->YEAR_REG = new_rtc_value->year;
|
||||
mss_rtc->WEEKDAY_REG = new_rtc_value->weekday;
|
||||
mss_rtc->WEEK_REG = new_rtc_value->week;
|
||||
|
||||
/* Data is copied, now issue upload command */
|
||||
mss_rtc->CONTROL_REG = CONTROL_UPLOAD_MASK ;
|
||||
|
||||
/* Wait for the upload to complete. */
|
||||
do {
|
||||
upload_in_progress = mss_rtc->CONTROL_REG & CONTROL_UPLOAD_MASK;
|
||||
} while (upload_in_progress);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_set_binary_count
|
||||
(
|
||||
uint64_t new_rtc_value
|
||||
)
|
||||
{
|
||||
uint8_t clock_mode;
|
||||
|
||||
/* This function can only be used when the RTC is configured to operate in
|
||||
* binary counter mode. */
|
||||
clock_mode = get_clock_mode();
|
||||
ASSERT(MSS_RTC_BINARY_MODE == clock_mode);
|
||||
|
||||
if (MSS_RTC_BINARY_MODE == clock_mode)
|
||||
{
|
||||
uint32_t rtc_upper_32_bit_value;
|
||||
|
||||
rtc_upper_32_bit_value = (uint32_t)(new_rtc_value >> 32u) & MASK_32_BIT;
|
||||
|
||||
/* Assert if the values cross the limit */
|
||||
ASSERT(rtc_upper_32_bit_value <= MAX_BINARY_HIGHER_COUNT);
|
||||
|
||||
if (rtc_upper_32_bit_value <= MAX_BINARY_HIGHER_COUNT)
|
||||
{
|
||||
uint32_t upload_in_progress;
|
||||
|
||||
/* Write the RTC new value. */
|
||||
mss_rtc->DATE_TIME_LOWER_REG = (uint32_t)new_rtc_value;
|
||||
mss_rtc->DATE_TIME_UPPER_REG =
|
||||
(uint32_t)(( new_rtc_value >> 32u) & MAX_BINARY_HIGHER_COUNT);
|
||||
|
||||
/* Data is copied, now issue upload command */
|
||||
mss_rtc->CONTROL_REG = CONTROL_UPLOAD_MASK;
|
||||
|
||||
/* Wait for the upload to complete. */
|
||||
do {
|
||||
upload_in_progress = mss_rtc->CONTROL_REG & CONTROL_UPLOAD_MASK;
|
||||
} while (upload_in_progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_get_calendar_count
|
||||
(
|
||||
mss_rtc_calender_t *p_rtc_calendar
|
||||
)
|
||||
{
|
||||
uint8_t clock_mode;
|
||||
/* This function can only be used when the RTC is configured to operate in
|
||||
* calendar counter mode. */
|
||||
clock_mode = get_clock_mode();
|
||||
ASSERT(MSS_RTC_CALENDAR_MODE == clock_mode);
|
||||
|
||||
if (MSS_RTC_CALENDAR_MODE == clock_mode)
|
||||
{
|
||||
p_rtc_calendar->second = (uint8_t)mss_rtc->SECONDS_REG;
|
||||
p_rtc_calendar->minute = (uint8_t)mss_rtc->MINUTES_REG;
|
||||
p_rtc_calendar->hour = (uint8_t)mss_rtc->HOURS_REG;
|
||||
p_rtc_calendar->day = (uint8_t)mss_rtc->DAY_REG;
|
||||
p_rtc_calendar->month = (uint8_t)mss_rtc->MONTH_REG;
|
||||
p_rtc_calendar->year = (uint8_t)mss_rtc->YEAR_REG;
|
||||
p_rtc_calendar->weekday = (uint8_t)mss_rtc->WEEKDAY_REG;
|
||||
p_rtc_calendar->week = (uint8_t)mss_rtc->WEEK_REG;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set returned calendar count to zero if the RTC is not configured for
|
||||
* calendar counter mode. This should make incorrect release application
|
||||
* code behave consistently and help application debugging. */
|
||||
memset(p_rtc_calendar, 0, sizeof(mss_rtc_calender_t));
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
uint64_t
|
||||
MSS_RTC_get_binary_count
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
uint64_t rtc_count;
|
||||
uint8_t clock_mode;
|
||||
|
||||
/* This function can only be used when the RTC is configured to operate in
|
||||
* binary counter mode. */
|
||||
clock_mode = get_clock_mode();
|
||||
ASSERT(MSS_RTC_BINARY_MODE == clock_mode);
|
||||
|
||||
if (MSS_RTC_BINARY_MODE == clock_mode)
|
||||
{
|
||||
rtc_count = mss_rtc->DATE_TIME_LOWER_REG;
|
||||
rtc_count = rtc_count | ((uint64_t)mss_rtc->DATE_TIME_UPPER_REG << 32u);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set returned binary count to zero if the RTC is not configured for
|
||||
* binary counter mode. This should make incorrect release application
|
||||
* code behave consistently and help application debugging. */
|
||||
rtc_count = 0u;
|
||||
}
|
||||
|
||||
return rtc_count;
|
||||
}
|
||||
|
||||
static void add_alarm_cfg_values
|
||||
(
|
||||
uint8_t calendar_item,
|
||||
uint32_t * p_calendar_value,
|
||||
uint32_t * p_compare_mask
|
||||
)
|
||||
{
|
||||
if (MSS_RTC_CALENDAR_DONT_CARE == calendar_item)
|
||||
{
|
||||
*p_calendar_value = (uint32_t)(*p_calendar_value << CALENDAR_SHIFT);
|
||||
*p_compare_mask = (uint32_t)(*p_compare_mask << CALENDAR_SHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
*p_calendar_value = (uint32_t)((*p_calendar_value << CALENDAR_SHIFT) |
|
||||
(uint32_t)calendar_item);
|
||||
*p_compare_mask = (uint32_t)((*p_compare_mask << CALENDAR_SHIFT) |
|
||||
(uint32_t)0xFFu);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_RTC_set_calendar_count_alarm
|
||||
(
|
||||
const mss_rtc_calender_t * alarm_value
|
||||
)
|
||||
{
|
||||
uint32_t calendar_value;
|
||||
uint32_t compare_mask;
|
||||
uint8_t mode;
|
||||
|
||||
mode = (uint8_t)(mss_rtc->MODE_REG & MODE_CLK_MODE_MASK);
|
||||
|
||||
/* This function can only be used with the RTC set to operate in calendar
|
||||
* mode. */
|
||||
ASSERT(MSS_RTC_CALENDAR_MODE == mode);
|
||||
|
||||
if (MSS_RTC_CALENDAR_MODE == mode)
|
||||
{
|
||||
uint8_t required_mode_reg;
|
||||
|
||||
/* Disable the alarm before updating */
|
||||
mss_rtc->CONTROL_REG = CONTROL_ALARM_OFF_MASK;
|
||||
|
||||
/* Set alarm and compare lower registers. */
|
||||
calendar_value = 0u;
|
||||
compare_mask = 0u;
|
||||
|
||||
add_alarm_cfg_values(alarm_value->day, &calendar_value, &compare_mask);
|
||||
add_alarm_cfg_values(alarm_value->hour, &calendar_value, &compare_mask);
|
||||
add_alarm_cfg_values(alarm_value->minute, &calendar_value, &compare_mask);
|
||||
add_alarm_cfg_values(alarm_value->second, &calendar_value, &compare_mask);
|
||||
|
||||
mss_rtc->ALARM_LOWER_REG = calendar_value;
|
||||
mss_rtc->COMPARE_LOWER_REG = compare_mask;
|
||||
|
||||
/* Set alarm and compare upper registers. */
|
||||
calendar_value = 0u;
|
||||
compare_mask = 0u;
|
||||
|
||||
add_alarm_cfg_values(alarm_value->week, &calendar_value, &compare_mask);
|
||||
add_alarm_cfg_values(alarm_value->weekday, &calendar_value, &compare_mask);
|
||||
add_alarm_cfg_values(alarm_value->year, &calendar_value, &compare_mask);
|
||||
add_alarm_cfg_values(alarm_value->month, &calendar_value, &compare_mask);
|
||||
|
||||
mss_rtc->ALARM_UPPER_REG = calendar_value;
|
||||
mss_rtc->COMPARE_UPPER_REG = compare_mask;
|
||||
|
||||
/* Configure the RTC to enable the alarm. */
|
||||
required_mode_reg = mode | MODE_WAKEUP_EN_MASK | MODE_WAKEUP_CONTINUE_MASK;
|
||||
set_rtc_mode(required_mode_reg);
|
||||
|
||||
/* Enable the alarm */
|
||||
mss_rtc->CONTROL_REG = CONTROL_ALARM_ON_MASK ;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
We only write the RTC mode register if really required because the RTC needs
|
||||
to be stopped for the mode register to be written. Stopping the RTC every time
|
||||
the wake-up alarm configuration is set might induce drift on the RTC time.
|
||||
This function is intended to be used when setting alarms.
|
||||
*/
|
||||
static void
|
||||
set_rtc_mode
|
||||
(
|
||||
uint8_t requested_mode
|
||||
)
|
||||
{
|
||||
if (mss_rtc->MODE_REG != requested_mode)
|
||||
{
|
||||
uint32_t rtc_running;
|
||||
rtc_running = mss_rtc->CONTROL_REG & CONTROL_RUNNING_MASK;
|
||||
if (rtc_running)
|
||||
{
|
||||
/* Stop the RTC in order to change the mode register content. */
|
||||
MSS_RTC_stop();
|
||||
mss_rtc->MODE_REG = requested_mode;
|
||||
MSS_RTC_start();
|
||||
}
|
||||
else
|
||||
{
|
||||
mss_rtc->MODE_REG = requested_mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_set_binary_count_alarm
|
||||
(
|
||||
uint64_t alarm_value,
|
||||
mss_rtc_alarm_type_t alarm_type
|
||||
)
|
||||
{
|
||||
uint8_t mode;
|
||||
|
||||
mode = (uint8_t)(mss_rtc->MODE_REG & MODE_CLK_MODE_MASK);
|
||||
|
||||
/* This function can only be used with the RTC set to operate in binary
|
||||
* counter mode. */
|
||||
ASSERT(MSS_RTC_BINARY_MODE == mode);
|
||||
if (MSS_RTC_BINARY_MODE == mode)
|
||||
{
|
||||
uint8_t required_mode_reg;
|
||||
|
||||
/* Disable the alarm before updating */
|
||||
mss_rtc->CONTROL_REG = CONTROL_ALARM_OFF_MASK;
|
||||
|
||||
/* Set the alarm value. */
|
||||
mss_rtc->COMPARE_LOWER_REG = COMPARE_ALL_BITS;
|
||||
mss_rtc->COMPARE_UPPER_REG = COMPARE_ALL_BITS;
|
||||
mss_rtc->ALARM_LOWER_REG = (uint32_t)alarm_value;
|
||||
mss_rtc->ALARM_UPPER_REG = (uint32_t)(alarm_value >> 32u);
|
||||
|
||||
/* Configure the RTC to enable the alarm. */
|
||||
required_mode_reg = mode | MODE_WAKEUP_EN_MASK | MODE_WAKEUP_CONTINUE_MASK;
|
||||
if (MSS_RTC_PERIODIC_ALARM == alarm_type)
|
||||
{
|
||||
/* The RTC binary counter will be fully reset when the alarm occurs.
|
||||
* The counter will continue counting while the wake-up interrupt is
|
||||
* active. */
|
||||
required_mode_reg |= MODE_WAKEUP_RESET_MASK;
|
||||
}
|
||||
set_rtc_mode(required_mode_reg);
|
||||
|
||||
/* Enable the alarm */
|
||||
mss_rtc->CONTROL_REG = CONTROL_ALARM_ON_MASK;
|
||||
|
||||
uint8_t test = get_clock_mode();
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_start
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
mss_rtc->CONTROL_REG = CONTROL_RTC_START_MASK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_stop
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
uint32_t rtc_running;
|
||||
|
||||
/* Send command to stop RTC. */
|
||||
mss_rtc->CONTROL_REG = CONTROL_RTC_STOP_MASK;
|
||||
|
||||
/* Wait for RTC internal synchronization to take place and RTC to actually
|
||||
* stop. */
|
||||
do {
|
||||
rtc_running = mss_rtc->CONTROL_REG & CONTROL_RUNNING_MASK;
|
||||
} while(rtc_running);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_reset_counter
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
uint32_t upload_in_progress;
|
||||
|
||||
mss_rtc->CONTROL_REG = CONTROL_RESET_MASK;
|
||||
|
||||
/* Wait for the upload to complete. */
|
||||
do {
|
||||
upload_in_progress = mss_rtc->CONTROL_REG & CONTROL_UPLOAD_MASK;
|
||||
} while (upload_in_progress);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
uint32_t
|
||||
MSS_RTC_get_update_flag
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
uint32_t updated;
|
||||
updated = mss_rtc->CONTROL_REG & CONTROL_UPDATED_MASK;
|
||||
return updated;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_clear_update_flag
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Clear the "updated" control bit. */
|
||||
mss_rtc->CONTROL_REG = CONTROL_UPDATED_MASK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_enable_irq
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Only the PLIC level interrupt enable is performed within this function.
|
||||
* The RTC level interrupt enable is performed within the alarm setting
|
||||
* functions.
|
||||
* This avoid the MODE register being modified whenever RTC
|
||||
* interrupts are enabled/disabled. */
|
||||
PLIC_EnableIRQ(RTC_WAKEUP_PLIC);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_disable_irq
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Only the PLIC level interrupt disable is performed within this function.
|
||||
* This avoid the MODE register being modified whenever RTC
|
||||
* interrupts are enabled/disabled. */
|
||||
PLIC_DisableIRQ(RTC_WAKEUP_PLIC);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_clear_irq
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
volatile uint32_t dummy_read;
|
||||
|
||||
/* Clear wake up interrupt signal */
|
||||
mss_rtc->CONTROL_REG = CONTROL_WAKEUP_CLR_MASK;
|
||||
|
||||
/* Ensure that the posted write to the CONTROL_REG register completed before
|
||||
* returning from this function. Not doing this may result in the interrupt
|
||||
* only being cleared some time after this function returns. */
|
||||
dummy_read = mss_rtc->CONTROL_REG;
|
||||
|
||||
/* Dummy operation to avoid warning message */
|
||||
++dummy_read;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The get_clock_mode() function gets the clock mode of RTC hardware.
|
||||
Possible clock modes are:
|
||||
MSS_RTC_CALENDAR_MODE
|
||||
MSS_RTC_BINARY_MODE
|
||||
*/
|
||||
static uint8_t
|
||||
get_clock_mode
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
uint8_t clock_mode;
|
||||
|
||||
clock_mode = (uint8_t)(mss_rtc->MODE_REG & MODE_CLK_MODE_MASK);
|
||||
|
||||
return(clock_mode);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,832 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* PolarFire SoC Microprocessor subsystem RTC bare metal software driver public
|
||||
* APIs.
|
||||
*/
|
||||
|
||||
/*=========================================================================*//**
|
||||
@mainpage PolarFire MSS RTC Bare Metal Driver.
|
||||
|
||||
==============================================================================
|
||||
Introduction
|
||||
==============================================================================
|
||||
The PolarFire SoC Microprocessor Subsystem (MSS) includes a real time counter
|
||||
(RTC) that can generate alarms and wake-up functions in real time. The RTC core
|
||||
also provides the feature of real time clock. This software driver provides a
|
||||
set of functions for controlling the MSS RTC as part of a bare metal system
|
||||
where no operating system is available. The driver can be adapted for use as
|
||||
part of an operating system, but the implementation of the adaptation layer
|
||||
between the driver and the operating system's driver model is outside the
|
||||
scope of the driver.
|
||||
|
||||
The MSS RTC driver provides support for the following features:
|
||||
- Initialization of the RTC
|
||||
- Configuration of the RTC time-base
|
||||
- Configuration as a calendar or binary mode counter
|
||||
- Set the current calendar or binary mode count
|
||||
- Get the current calendar or binary mode count
|
||||
- Start and stop the RTC counting
|
||||
- Set alarm conditions
|
||||
- Enable, disable and clear the wake-up interrupt
|
||||
|
||||
==============================================================================
|
||||
Hardware Flow Dependencies
|
||||
==============================================================================
|
||||
The configuration of all features of the MSS RTC driver is covered by this
|
||||
driver except for the clock source driving the MSS RTC clock(RTCCLK) input.
|
||||
The PolarFire SoC MSS clock controller supplies single clock source of 1 MHz
|
||||
to the MSS RTC clock input.
|
||||
On PolarFire SoC an AXI switch forms a bus matrix interconnect among multiple
|
||||
masters and multiple slaves. Five RISC-V CPUs connect to the Master ports M10
|
||||
to M14 of the AXI switch. By default, all the APB peripherals are accessible
|
||||
on AXI-Slave 5 of the AXI switch via the AXI to AHB and AHB to APB bridges
|
||||
(referred as main APB bus). However, to support logical separation in the
|
||||
Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals can
|
||||
alternatively be accessed on the AXI-Slave 6 via the AXI to AHB and AHB to
|
||||
APB bridges (referred as the AMP APB bus).
|
||||
Application must make sure that the RTC is appropriately configured on one of
|
||||
the APB bus described above by configuring the PolarFire SoC system registers
|
||||
(SYSREG) as per the application need and that the appropriate data structures
|
||||
are provided to this driver as parameter to the functions provided by this
|
||||
driver.
|
||||
The base address and register addresses and interrupt number assignment for
|
||||
the MSS RTC block are defined as constants in the PolarFire SoC MPFS HAL. You
|
||||
must ensure that the latest PolarFire SoC MPFS HAL is included in the project
|
||||
settings of the software tool chain used to build your project and that it is
|
||||
generated into your project.
|
||||
|
||||
==============================================================================
|
||||
Theory of Operation
|
||||
==============================================================================
|
||||
The MSS RTC driver functions are grouped into the following categories:
|
||||
- Initialization of the RTC driver and hardware
|
||||
- Setting and reading the RTC counter current value
|
||||
- Setting RTC alarm values
|
||||
- Starting and stopping the RTC
|
||||
- Interrupt Control
|
||||
|
||||
--------------------------------
|
||||
Initialization of the RTC driver and hardware
|
||||
--------------------------------
|
||||
The MSS RTC driver is initialized through a call to the MSS_RTC_init()
|
||||
function. The MSS_RTC_init() function must be called before any other MSS RTC
|
||||
driver functions are called.
|
||||
The MSS_RTC_init() function:
|
||||
• Stops the RTC counters and disables the RTC alarm
|
||||
• Disables the RTC wake-up interrupt in the RTC and in the Platform Level
|
||||
Interrupt Controller (PLIC).
|
||||
• Clears any pending RTC wake-up interrupt in the RTC and in the Platform
|
||||
Level Interrupt Controller (PLIC).
|
||||
• Enables the RTC_WAKEUP_CR[0] mask bit in the MSS System Register to
|
||||
connect the RTC wake-up interrupt to the Platform Level Interrupt
|
||||
Controller.
|
||||
• Resets the RTC counters, alarm and the compare registers
|
||||
• Sets the RTC's operating mode to binary counter mode or calendar
|
||||
counter mode, as specified by the mode parameter
|
||||
• Sets the RTC's prescaler register to the value specified by the
|
||||
prescaler parameter. The frequency of the clock source driving the MSS
|
||||
RTC clock (RTCCLK) input is required to calculate the prescaler value.
|
||||
|
||||
--------------------------------------------
|
||||
Setting and Reading the RTC Counter Value
|
||||
--------------------------------------------
|
||||
The MSS RTC supports two mode of operation – binary mode and calendar mode.
|
||||
The following functions are used to set and read the current value of the
|
||||
counter when the MSS RTC is configured to operate in binary mode:
|
||||
• MSS_RTC_set_binary_count() – This function is used to set the current
|
||||
value of the RTC binary counter.
|
||||
• MSS_RTC_get_binary_count() – This function is used to read the current
|
||||
value of the RTC binary counter.
|
||||
|
||||
The following functions are used to set and read the current value of the
|
||||
counter the MSS RTC is configured to operate in calendar mode:
|
||||
• MSS_RTC_set_calendar_count() – This function is used to set the current
|
||||
value of the RTC calendar counter.
|
||||
• MSS_RTC_get_calendar_count() – This function is used to read the current
|
||||
value of the RTC calendar counter.
|
||||
|
||||
The following functions resets the RTC counter in either binary or calendar
|
||||
operating mode:
|
||||
• MSS_RTC_reset_counter() – This function resets the RTC counter.
|
||||
|
||||
|
||||
--------------------------------------------
|
||||
Setting RTC Alarms
|
||||
--------------------------------------------
|
||||
The MSS RTC can generate alarms when the counter matches a specified count
|
||||
value in binary mode or a date and time in calendar mode.
|
||||
The following functions are used to set up alarms:
|
||||
• MSS_RTC_set_binary_count_alarm() – This function sets up one-shot or
|
||||
periodic alarms when the MSS RTC is
|
||||
configured to operate in binary mode.
|
||||
• MSS_RTC_set_calendar_count_alarm() – This function sets up one-shot or
|
||||
periodic alarms when the MSS RTC is
|
||||
configured to operate in calendar
|
||||
mode.
|
||||
Note: The alarm asserts a wake-up interrupt to the RISC-V Core. This function
|
||||
enables the RTC’s wake-up interrupt output, however the RTC wake-up interrupt
|
||||
input to the RISC-V PLIC must be enabled separately by calling the
|
||||
MSS_RTC_enable_irq() function. The alarm can be disabled at any time by
|
||||
calling the MSS_RTC_disable_irq() function.
|
||||
|
||||
--------------------------------------------
|
||||
Starting and Stopping the RTC Counter
|
||||
--------------------------------------------
|
||||
The following functions start and stop the RTC counter:
|
||||
- MSS_RTC_start() – This function starts the RTC counter.
|
||||
- MSS_RTC_stop() – This function stops the RTC counter.
|
||||
|
||||
-------------------------------------------
|
||||
Interrupt Control
|
||||
-------------------------------------------
|
||||
The MSS_RTC_enable_irq () function enables the RTC_WAKEUP_CR[0] mask bit in
|
||||
the MSS System Register to connect the RTC wake-up interrupt to the Platform
|
||||
Level Interrupt Controller.
|
||||
An rtc_wakeup_plic_IRQHandler () default implementation is defined, with weak
|
||||
linkage, in the PolarFire SoC MPFS HAL. You must provide your own
|
||||
implementation of the rtc_wakeup_plic_IRQHandler () function, which will
|
||||
override the default implementation, to suit your application.
|
||||
The function prototype for the RTC wake-up interrupt handler is as follows:
|
||||
uint8_t rtc_wakeup_plic_IRQHandler(void);
|
||||
|
||||
The RTC wake-up interrupt is controlled using the following functions:
|
||||
• MSS_RTC_enable_irq() – The MSS_RTC_enable_irq() function enables the RTC
|
||||
to interrupt the MSS when a wake-up alarm occurs.
|
||||
• MSS_RTC_disable_irq() – The MSS_RTC_disable_irq() function disables the
|
||||
RTC from interrupting the MSS when a wake-up
|
||||
alarm occurs.
|
||||
• MSS_RTC_clear_irq() – The MSS_RTC_clear_irq() function clears a pending
|
||||
RTC wake-up interrupt at the RTC wake-up output.
|
||||
You must call the MSS_RTC_clear_irq() function as
|
||||
part of your implementation of the
|
||||
rtc_wakeup_plic_IRQHandler() interrupt service
|
||||
routine (ISR) in order to prevent the same
|
||||
interrupt event retriggering a call to the ISR.
|
||||
|
||||
*//*=========================================================================*/
|
||||
#ifndef MSS_RTC_H_
|
||||
#define MSS_RTC_H_
|
||||
|
||||
#include "mss_rtc_regs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_BINARY_MODE constant is used to specify the mode parameter to the
|
||||
MSS_RTC_init() function. The RTC will run in binary mode if this constant is
|
||||
used. In binary mode, the calendar counter counts consecutively from 0 all the
|
||||
way to 2^43.
|
||||
*/
|
||||
#define MSS_RTC_BINARY_MODE 0u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_CALENDAR_MODE constant is used to specify the mode parameter to
|
||||
the MSS_RTC_init() function. The RTC will run in calendar mode if this
|
||||
constant is used. In calendar mode, the calendar counter counts seconds,
|
||||
minutes, hours, days, months, years, weekdays and weeks.
|
||||
*/
|
||||
#define MSS_RTC_CALENDAR_MODE 1u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The alarm_value parameter of the MSS_RTC_set_calendar_count_alarm() function
|
||||
is a pointer to an mss_rtc_calender_t data structure specifying the date and
|
||||
time at which the alarm is to occur. You must assign the required date and
|
||||
time values to the mss_rtc_calender_t structure before calling the function.
|
||||
Any of the fields of the mss_rtc_calender_t structure can be set to
|
||||
MSS_RTC_CALENDAR_DONT_CARE, to indicate that they are not to be considered in
|
||||
deciding when the alarm will occur; this is necessary when setting periodic
|
||||
alarms.
|
||||
*/
|
||||
#define MSS_RTC_CALENDAR_DONT_CARE 0xFFu
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Days of the week.
|
||||
*/
|
||||
#define MSS_RTC_SUNDAY 1u
|
||||
#define MSS_RTC_MONDAY 2u
|
||||
#define MSS_RTC_TUESDAY 3u
|
||||
#define MSS_RTC_WEDNESDAY 4u
|
||||
#define MSS_RTC_THRUSDAY 5u
|
||||
#define MSS_RTC_FRIDAY 6u
|
||||
#define MSS_RTC_SATURDAY 7u
|
||||
|
||||
/***************************************************************************//**
|
||||
MSS RTC base addresses.
|
||||
These definitions provides access to the MSS RTC mapped at two different
|
||||
memory regions. User can provide one of these constants to the MSS_RTC_init()
|
||||
function for configuring the MSS RTC block.
|
||||
*/
|
||||
#define MSS_RTC_LO_BASE (RTC_TypeDef *)MSS_RTC_LO_ADDR
|
||||
#define MSS_RTC_HI_BASE (RTC_TypeDef *)MSS_RTC_HI_ADDR
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The mss_rtc_alarm_type_t enumeration is used as the alarm_type parameter for
|
||||
the MSS_RTC_set_calendar_count_alarm() and MSS_RTC_set_binary_count_alarm()
|
||||
functions to specify whether the requested alarm should occur only one time or
|
||||
periodically.
|
||||
*/
|
||||
typedef enum {
|
||||
MSS_RTC_SINGLE_SHOT_ALARM,
|
||||
MSS_RTC_PERIODIC_ALARM
|
||||
} mss_rtc_alarm_type_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
A pointer to an instance of the mss_rtc_calender_t data structure is used to
|
||||
write new date and time values to the RTC using the
|
||||
MSS_RTC_set_rtc_calendar_count() and MSS_RTC_set_calendar_count_alarm()
|
||||
functions. The MSS_RTC_get_calendar_count() function also uses a pointer to an
|
||||
instance of the mss_rtc_calender_t data structure to read the current date and
|
||||
time value from the RTC.
|
||||
*/
|
||||
typedef struct mss_rtc_calender
|
||||
{
|
||||
uint8_t second;
|
||||
uint8_t minute;
|
||||
uint8_t hour;
|
||||
uint8_t day;
|
||||
uint8_t month;
|
||||
uint8_t year;
|
||||
uint8_t weekday;
|
||||
uint8_t week;
|
||||
} mss_rtc_calender_t ;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_init() function initializes the RTC driver and hardware to a known
|
||||
state. To initialize the RTC hardware, this function:
|
||||
• Stops the RTC counters and disables the RTC alarm
|
||||
• Disables the RTC wakeup interrupt in the RTC and in the PolarFire SoC
|
||||
MSS Platform Level Interrupt Controller (PLIC).
|
||||
• Clears any pending RTC wakeup interrupt in the RTC and in the PolarFire
|
||||
SoC MSS Platform Level Interrupt Controller (PLIC).
|
||||
• Resets the RTC counters and the alarm and compare registers
|
||||
• Sets the RTC's operating mode to binary counter mode or calendar counter
|
||||
mode, as specified by the mode parameter
|
||||
• Sets the RTC's prescaler register to the value specified by the
|
||||
prescaler parameter
|
||||
• The MSS clock controller can supply one of three clock sources to the
|
||||
RTC clock input (RTCCLK):
|
||||
- Crystal Oscillator 32.768 kHz
|
||||
- 1MHz Oscillator
|
||||
- 50MHz Oscillator. (25 MHz in a 1.0v part).
|
||||
|
||||
For calendar mode, program the prescaler register to generate a 1Hz signal
|
||||
from the active RTCCLK according to the following equation:
|
||||
prescaler = RTCCLK – 1 (where RTCCLK unit is Hz)
|
||||
For a 32.768 kHz clock, set the prescaler to 32768 - 1 = 32767.
|
||||
The prescaler register is 26 bits wide, allowing clock sources of up to 67 MHz
|
||||
to generate the 1Hz time base.
|
||||
|
||||
For binary mode, the prescaler register can be programmed to generate a 1Hz
|
||||
time base or a different time base, as required.
|
||||
|
||||
@param base_address
|
||||
The base address parameter provides the base address of the MSS RTC
|
||||
peripheral. The MSS RTC can appear on either the AXI slave 5 or slave 6 per
|
||||
SYSREG configurations. The corresponding base address of this peripheral
|
||||
must be provided per your configuration.
|
||||
|
||||
@param mode
|
||||
The mode parameter is used to specify the operating mode of the RTC. The
|
||||
allowed values for mode are:
|
||||
- MSS_RTC_BINARY_MODE
|
||||
- MSS_RTC_CALENDAR_MODE
|
||||
|
||||
@param prescaler
|
||||
The prescaler parameter specifies the value to divide the incoming RTC clock
|
||||
by, to generate the RTC time base signal. For calendar mode, set the
|
||||
prescaler value to generate a 1Hz time base from the incoming RTC clock
|
||||
according to the following equation:
|
||||
prescaler = RTCCLK – 1 (where the RTCCLK unit is Hz)
|
||||
For binary mode, set the prescaler value to generate a 1Hz time base or a
|
||||
different time base, as required.
|
||||
The prescaler parameter can be any integer value in the range 2 to 2^26.
|
||||
|
||||
@return
|
||||
This function does not return any value.
|
||||
|
||||
Example:
|
||||
The example code below shows how the RTC can be initialized only after a
|
||||
power-on reset.
|
||||
@code
|
||||
#define PO_RESET_DETECT_MASK 0x00000001u
|
||||
|
||||
void e51(void)
|
||||
{
|
||||
uint32_t power_on_reset;
|
||||
power_on_reset = SYSREG->RESET_SOURCE_CR & PO_RESET_DETECT_MASK;
|
||||
if(power_on_reset)
|
||||
{
|
||||
MSS_RTC_init(MSS_RTC_LO_BASE, MSS_RTC_BINARY_MODE,
|
||||
RTC_PERIPH_PRESCALER/ 10u );
|
||||
SYSREG->RESET_SOURCE_CR = PO_RESET_DETECT_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
@endcode
|
||||
*/
|
||||
void
|
||||
MSS_RTC_init
|
||||
(
|
||||
RTC_TypeDef *base_address,
|
||||
uint8_t mode,
|
||||
uint32_t prescaler
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_set_binary_count() function sets the current value of the RTC
|
||||
binary counter.
|
||||
Note: This function must only be used when the RTC is configured to operate in
|
||||
binary counter mode.
|
||||
|
||||
@param new_rtc_value
|
||||
The new_rtc_value parameter specifies the new count value from which the RTC
|
||||
will increment. The binary counter is 43 bits wide, so the maximum allowed
|
||||
binary value is 2^43.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
|
||||
void
|
||||
MSS_RTC_set_binary_count
|
||||
(
|
||||
uint64_t new_rtc_value
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_set_rtc_calendar_count() function sets the current value of the
|
||||
RTC calendar counter.
|
||||
Note: This function must only be used when the RTC is configured to operate in
|
||||
calendar counter mode.
|
||||
|
||||
@param new_rtc_value
|
||||
The new_rtc_value parameter is a pointer to an mss_rtc_calender_t data
|
||||
structure specifying the new date and time value from which the RTC will
|
||||
increment. You must populate the mss_rtc_calender_t structure with the
|
||||
required date and time values before calling this function.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
|
||||
void
|
||||
MSS_RTC_set_calendar_count
|
||||
(
|
||||
const mss_rtc_calender_t *new_rtc_value
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_get_calendar_count() function returns the current value of the RTC
|
||||
calendar counter via the data structure pointed to by the p_rtc_calendar
|
||||
parameter.
|
||||
Note: This function must only be used when the RTC is configured to operate in
|
||||
calendar counter mode.
|
||||
|
||||
@param p_rtc_calendar
|
||||
The p_rtc_calendar parameter is a pointer to an mss_rtc_calender_t data
|
||||
structure where the current value of the calendar counter will be written by
|
||||
the MSS_RTC_get_calendar_count() function
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_get_calendar_count
|
||||
(
|
||||
mss_rtc_calender_t *p_rtc_calendar
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_get_binary_count() function returns the current value of the RTC
|
||||
binary counter.
|
||||
Note: This function must only be used when the RTC is configured to operate in
|
||||
binary counter mode.
|
||||
|
||||
@param
|
||||
This function takes no parameters.
|
||||
|
||||
@return
|
||||
This function returns the current value of the RTC binary counter as an
|
||||
unsigned 64-bit integer.
|
||||
*/
|
||||
uint64_t
|
||||
MSS_RTC_get_binary_count
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_start() function starts the RTC incrementing.
|
||||
|
||||
@param
|
||||
This function takes no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_start
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_stop() function stops the RTC from incrementing.
|
||||
|
||||
@param
|
||||
This function takes no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_stop
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_reset_counter() function resets the RTC counters. If the counter
|
||||
was running before calling this function, then it continues incrementing from
|
||||
the counter’s reset value.
|
||||
|
||||
@param
|
||||
This function takes no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_reset_counter
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_enable_irq() function enables the RTC wakeup output to interrupt
|
||||
the MSS when an alarm occurs. It enables the RTC wakeup interrupt
|
||||
(RTC_Wakeup_IRQn) in the PoalrFire SoC PLIC. The rtc_wakeup_plic_IRQHandler()
|
||||
function will be called when an RTC wakeup interrupt occurs.
|
||||
|
||||
Note: The rtc_wakeup_plic_IRQHandler() default implementation is defined,
|
||||
with weak linkage, in the PoalrFire SoC MPFS HAL. You must provide your own
|
||||
implementation of the rtc_wakeup_plic_IRQHandler() function, which will
|
||||
override the default implementation, to suit your application.
|
||||
|
||||
Note: This function only enables the RTC wakeup interrupt at the PolarFire SoC
|
||||
PLIC level. The alarm setting functions enable the wakeup interrupt output
|
||||
from the RTC.
|
||||
|
||||
@param
|
||||
This function takes no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_enable_irq
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_disable_irq() function disables the RTC wakeup interrupt
|
||||
(RTC_WAKEUP_PLIC)in the PolarFire SoC MSS PLIC.
|
||||
Note: This function only disables the RTC wakeup interrupt at the PolarFire
|
||||
SoC PLIC level. It does not disable the wakeup interrupt output from the RTC.
|
||||
|
||||
@param
|
||||
This function takes no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_disable_irq
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_clear_irq() function clears a pending wakeup interrupt from the
|
||||
RTC. This function does not clear the interrupt in the PolarFire SoC PLIC; it
|
||||
only clears the wakeup output from the RTC.
|
||||
Note: You must call the MSS_RTC_clear_irq() function as part of your
|
||||
implementation of the rtc_wakeup_plic_IRQHandler() RTC wakeup interrupt
|
||||
service routine (ISR) in order to prevent the same interrupt event
|
||||
retriggering a call to the ISR.
|
||||
|
||||
@param
|
||||
This function takes no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
The example code below demonstrates how the MSS_RTC_clear_irq() function is
|
||||
intended to be used as part of the RTC wakeup interrupt service routine used
|
||||
by an application to handle RTC alarms.
|
||||
@code
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((__interrupt__)) void rtc_wakeup_plic_IRQHandler( void )
|
||||
#else
|
||||
void rtc_wakeup_plic_IRQHandler( void )
|
||||
#endif
|
||||
{
|
||||
process_alarm();
|
||||
MSS_RTC_clear_irq();
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
void
|
||||
MSS_RTC_clear_irq
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_set_calendar_count_alarm() function sets up the RTC to generate an
|
||||
alarm when the RTC count reaches the time/date specified by the alarm_value
|
||||
parameter. The alarm asserts a wakeup interrupt to the MSS. This function
|
||||
enables the RTC’s wakeup interrupt output, however the RTC wakeup interrupt
|
||||
input to the PolarFire SoC PLIC must be enabled separately by calling the
|
||||
MSS_RTC_enable_irq() function. The alarm can be disabled at any time by
|
||||
calling the MSS_RTC_disable_irq() function.
|
||||
|
||||
Single-shot alarm
|
||||
The alarm can be a single-shot alarm, which will generate a single wakeup
|
||||
interrupt the first time the RTC count reaches the time/date specified by
|
||||
alarm_value. A single shot alarm is achieved by specifying a value for every
|
||||
field of the mss_rtc_calender_t data structure pointed to by the alarm_value
|
||||
parameter. The RTC counter will keep incrementing after a single shot alarm
|
||||
occurs.
|
||||
|
||||
Periodic alarm
|
||||
The alarm can also be a periodic alarm, which will generate a wakeup interrupt
|
||||
every time the RTC count reaches the time/date specified by alarm_value, with
|
||||
the counter running in a continuous loop. The periodic alarm can be set to
|
||||
occur every minute, hour, day, month, year, week, day of the week, or any
|
||||
valid combination of these. This is achieved by setting some of the fields of
|
||||
the mss_rtc_calender_t data structure pointed to by the alarm_value parameter,
|
||||
to MSS_RTC_CALENDAR_DONT_CARE. For example, setting the weekday field to
|
||||
MSS_RTC_MONDAY and all other fields to MSS_RTC_CALENDAR_DONT_CARE will result
|
||||
in an alarm occurring every Monday. You can refine the time at which the alarm
|
||||
will occur by specifying values for the hour, minute and second fields.
|
||||
|
||||
Note: This function must only be used when the RTC is configured to operate
|
||||
in calendar counter mode.
|
||||
|
||||
|
||||
@param alarm_value
|
||||
The alarm_value parameter is a pointer to an mss_rtc_calender_t data
|
||||
structure specifying the date and time at which the alarm is to occur. You
|
||||
must assign the required date and time values to the mss_rtc_calender_t
|
||||
structure before calling this function. Some of the fields within the
|
||||
mss_rtc_calender_t structure can be set to MSS_RTC_CALENDAR_DONT_CARE, to
|
||||
indicate that they are not to be considered in deciding when the alarm will
|
||||
occur; this is necessary when setting periodic alarms.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Examples:
|
||||
|
||||
The following example code demonstrates how to configure the RTC to generate a
|
||||
single calendar alarm at a specific date and time. The alarm will only occur
|
||||
once and the RTC will keep incrementing regardless of the alarm taking place.
|
||||
|
||||
@code
|
||||
const mss_rtc_calender_t initial_calendar_count =
|
||||
{
|
||||
15u, second
|
||||
30u, minute
|
||||
6u, hour
|
||||
6u, day
|
||||
9u, month
|
||||
12u, year
|
||||
5u, weekday
|
||||
37u week
|
||||
};
|
||||
|
||||
mss_rtc_calender_t alarm_calendar_count =
|
||||
{
|
||||
17u, second
|
||||
30u, minute
|
||||
6u, hour
|
||||
6u, day
|
||||
9u, month
|
||||
12u, year
|
||||
5u, weekday
|
||||
37u week
|
||||
};
|
||||
|
||||
MSS_RTC_init(MSS_RTC_LO_BASE, MSS_RTC_BINARY_MODE, RTC_PERIPH_PRESCALER/ 10u);
|
||||
MSS_RTC_clear_irq();
|
||||
MSS_RTC_set_calendar_count(&initial_calendar_count);
|
||||
MSS_RTC_enable_irq();
|
||||
MSS_RTC_start();
|
||||
|
||||
MSS_RTC_set_calendar_count_alarm(&alarm_calendar_count);
|
||||
@endcode
|
||||
|
||||
The following example code demonstrates how to configure the RTC to generate a
|
||||
periodic calendar alarm. The RTC is configured to generate an alarm every
|
||||
Tuesday at 16:45:00. The alarm will reoccur every week until the RTC wakeup
|
||||
interrupt is disabled using a call to MSS_RTC_disable_irq().
|
||||
|
||||
@code
|
||||
mss_rtc_calender_t initial_calendar_count =
|
||||
{
|
||||
58u, <--second
|
||||
59u, <--minute
|
||||
23u, <--hour
|
||||
10u, <--day
|
||||
9u, <--month
|
||||
12u, <--year
|
||||
MSS_RTC_MONDAY, <--weekday
|
||||
37u <--week
|
||||
};
|
||||
|
||||
mss_rtc_calender_t alarm_calendar_count =
|
||||
{
|
||||
MSS_RTC_CALENDAR_DONT_CARE, <--second
|
||||
45u, <--minute
|
||||
16u, <--hour
|
||||
MSS_RTC_CALENDAR_DONT_CARE, <--day
|
||||
MSS_RTC_CALENDAR_DONT_CARE, <--month
|
||||
MSS_RTC_CALENDAR_DONT_CARE, <--year
|
||||
MSS_RTC_TUESDAY, <--weekday
|
||||
MSS_RTC_CALENDAR_DONT_CARE <--week
|
||||
};
|
||||
|
||||
MSS_RTC_init(MSS_RTC_LO_BASE, MSS_RTC_BINARY_MODE, RTC_PERIPH_PRESCALER/ 10u);
|
||||
MSS_RTC_set_calendar_count(&initial_calendar_count);
|
||||
MSS_RTC_enable_irq();
|
||||
MSS_RTC_start();
|
||||
|
||||
MSS_RTC_set_calendar_count_alarm(&alarm_calendar_count);
|
||||
@endcode
|
||||
|
||||
The following example code demonstrates the code that you need to include in
|
||||
your application to handle alarms. It is the interrupt service routine for the
|
||||
RTC wakeup interrupt input to the PolarFire SoC PLIC. You need to add your
|
||||
application code in this function in place of the process_alarm() function but
|
||||
you must retain the call to MSS_RTC_clear_irq() to ensure that the same alarm
|
||||
does not retrigger the interrupt.
|
||||
|
||||
@code
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((__interrupt__)) void rtc_wakeup_plic_IRQHandler( void )
|
||||
#else
|
||||
void rtc_wakeup_plic_IRQHandler( void )
|
||||
#endif
|
||||
{
|
||||
process_alarm();
|
||||
MSS_RTC_clear_irq();
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
void
|
||||
MSS_RTC_set_calendar_count_alarm
|
||||
(
|
||||
const mss_rtc_calender_t * alarm_value
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_set_binary_count_alarm() function sets up the RTC to generate an
|
||||
alarm when the RTC count reaches the value specified by the alarm_value
|
||||
parameter. The alarm asserts a wakeup interrupt to the MSS. This function
|
||||
enables the RTC’s wakeup interrupt output, however the RTC wakeup interrupt
|
||||
input to the PolarFire SoC PLIC must be enabled separately by calling the
|
||||
MSS_RTC_enable_irq() function. The alarm can be disabled at any time by
|
||||
calling the MSS_RTC_disable_irq() function.
|
||||
|
||||
Single-shot alarm
|
||||
The alarm can be a single-shot alarm, which will generate a single wakeup
|
||||
interrupt the first time the RTC count reaches the value specified by the
|
||||
alarm_value parameter. Setting the alarm_value parameter to
|
||||
MSS_RTC_PERIODIC_ALARM produces a single-shot alarm. The RTC counter continues
|
||||
incrementing when a single shot alarm occurs.
|
||||
|
||||
Periodic alarm
|
||||
The alarm can also be a periodic alarm, which will generate a wakeup interrupt
|
||||
every time the RTC count reaches the value specified by the alarm_value
|
||||
parameter. Setting the alarm_value parameter to MSS_RTC_SINGLE_SHOT_ALARM
|
||||
produces a periodic alarm. The RTC counter automatically wraps around to zero
|
||||
and continues incrementing when a periodic alarm occurs.
|
||||
|
||||
Note: This function must only be used when the RTC is configured to operate
|
||||
in binary counter mode.
|
||||
|
||||
@param alarm_value
|
||||
The alarm_value parameter is a 64-bit unsigned value specifying the RTC
|
||||
counter value that must be reached for the requested alarm to occur.
|
||||
|
||||
@param alarm_type
|
||||
The alarm_type parameter specifies whether the requested alarm is a single
|
||||
shot or periodic alarm. It can only take one of these two values:
|
||||
- MSS_RTC_SINGLE_SHOT_ALARM,
|
||||
- MSS_RTC_PERIODIC_ALARM
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_set_binary_count_alarm
|
||||
(
|
||||
uint64_t alarm_value,
|
||||
mss_rtc_alarm_type_t alarm_type
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_get_update_flag() function indicates if the RTC counter has
|
||||
incremented since the last call to MSS_RTC_clear_update_flag(). It returns
|
||||
zero if no RTC counter increment has occurred. It returns a non-zero value if
|
||||
the RTC counter has incremented. This function can be used whether the RTC is
|
||||
configured to operate in calendar or binary counter mode.
|
||||
|
||||
@return
|
||||
This function returns,
|
||||
|
||||
|Value | Description |
|
||||
|---------|-----------------------------------------------------------|
|
||||
|zero: | if the RTC has not incremented since the last call to |
|
||||
| | MSS_RTC_clear_update_flag(), |
|
||||
|---------|-----------------------------------------------------------|
|
||||
|non-zero:| if the RTC has incremented since the last call to |
|
||||
| | MSS_RTC_clear_update_flag(). |
|
||||
|
||||
Example
|
||||
This example waits for the RTC timer to increment by one second.
|
||||
@code
|
||||
void wait_start_of_second(void)
|
||||
{
|
||||
uint32_t rtc_count_updated;
|
||||
MSS_RTC_clear_update_flag();
|
||||
do {
|
||||
rtc_count_updated = MSS_RTC_get_update_flag();
|
||||
} while(!rtc_count_updated)
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
uint32_t
|
||||
MSS_RTC_get_update_flag
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_clear_update_flag() function clears the CONTROL register flag that
|
||||
is set when the RTC counter increments. It is used alongside function
|
||||
MSS_RTC_get_update_flag() to detect RTC counter increments.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example
|
||||
The example below will wait for the RTC timer to increment by one second.
|
||||
@code
|
||||
void wait_start_of_second(void)
|
||||
{
|
||||
uint32_t rtc_count_updated;
|
||||
MSS_RTC_clear_update_flag();
|
||||
do {
|
||||
rtc_count_updated = MSS_RTC_get_update_flag();
|
||||
} while(!rtc_count_updated)
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
void
|
||||
MSS_RTC_clear_update_flag
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_RTC_H_ */
|
|
@ -0,0 +1,67 @@
|
|||
/******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Register bit offsets and masks definitions for PolarFire SoC MSS RTC Driver.
|
||||
|
||||
*/
|
||||
#ifndef MSS_RTC_REG_H__
|
||||
#define MSS_RTC_REG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* Device Specific Peripheral registers structures */
|
||||
/******************************************************************************/
|
||||
typedef struct
|
||||
{
|
||||
volatile uint32_t CONTROL_REG ;
|
||||
volatile uint32_t MODE_REG ;
|
||||
volatile uint32_t PRESCALER_REG ;
|
||||
volatile uint32_t ALARM_LOWER_REG ;
|
||||
volatile uint32_t ALARM_UPPER_REG ;
|
||||
volatile uint32_t COMPARE_LOWER_REG ;
|
||||
volatile uint32_t COMPARE_UPPER_REG ;
|
||||
uint32_t RESERVED0 ;
|
||||
volatile uint32_t DATE_TIME_LOWER_REG ;
|
||||
volatile uint32_t DATE_TIME_UPPER_REG ;
|
||||
|
||||
uint32_t RESERVED1[2] ;
|
||||
volatile uint32_t SECONDS_REG ;
|
||||
volatile uint32_t MINUTES_REG ;
|
||||
volatile uint32_t HOURS_REG ;
|
||||
volatile uint32_t DAY_REG ;
|
||||
volatile uint32_t MONTH_REG ;
|
||||
volatile uint32_t YEAR_REG ;
|
||||
volatile uint32_t WEEKDAY_REG ;
|
||||
volatile uint32_t WEEK_REG ;
|
||||
|
||||
volatile uint32_t SECONDS_CNT_REG ;
|
||||
volatile uint32_t MINUTES_CNT_REG ;
|
||||
volatile uint32_t HOURS_CNT_REG ;
|
||||
volatile uint32_t DAY_CNT_REG ;
|
||||
volatile uint32_t MONTH_CNT_REG ;
|
||||
volatile uint32_t YEAR_CNT_REG ;
|
||||
volatile uint32_t WEEKDAY_CNT_REG ;
|
||||
volatile uint32_t WEEK_CNT_REG ;
|
||||
} RTC_TypeDef;
|
||||
|
||||
/******************************************************************************/
|
||||
/* Peripheral declaration */
|
||||
/******************************************************************************/
|
||||
#define MSS_RTC_LO_ADDR 0x20124000u
|
||||
#define MSS_RTC_HI_ADDR 0x28124000u
|
||||
|
||||
#define COMPARE_ALL_BITS 0xFFFFFFFFu
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_RTC_REG_H__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,55 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Register bit offsets and masks definitions for PolarFire SoC MSS system
|
||||
* services
|
||||
*/
|
||||
#ifndef MSS_SYS_SERVICES_REGS_H_
|
||||
#define MSS_SYS_SERVICES_REGS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************SCBCTRL SERVICES_CR register*************************/
|
||||
|
||||
#define SCBCTRL_SERVICESCR_REQ (0u)
|
||||
#define SCBCTRL_SERVICESCR_REQ_MASK (1u << SCBCTRL_SERVICESCR_REQ)
|
||||
|
||||
#define SCBCTRL_SERVICESCR_BUSY (1u)
|
||||
#define SCBCTRL_SERVICESCR_BUSY_MASK (1u << SCBCTRL_SERVICESCR_BUSY)
|
||||
|
||||
#define SCBCTRL_SERVICESCR_ABORT (2u)
|
||||
#define SCBCTRL_SERVICESCR_ABORT_MASK (1u << SCBCTRL_SERVICESCR_ABORT)
|
||||
|
||||
#define SCBCTRL_SERVICESCR_NOTIFY (3u)
|
||||
#define SCBCTRL_SERVICESCR_NOTIFY_MASK (1u << SCBCTRL_SERVICESCR_NOTIFY)
|
||||
|
||||
#define SCBCTRL_SERVICESCR_COMMAND (16u)
|
||||
#define SCBCTRL_SERVICESCR_COMMAND_MASK (0xFFFFu << SCBCTRL_SERVICESCR_COMMAND)
|
||||
|
||||
|
||||
/***************SCBCTRL SERVICES_SR registers*************************/
|
||||
|
||||
#define SCBCTRL_SERVICESSR_REQ (0u)
|
||||
#define SCBCTRL_SERVICESSR_REQ_MASK (1u << SCBCTRL_SERVICESSR_REQ)
|
||||
|
||||
#define SCBCTRL_SERVICESSR_BUSY (1u)
|
||||
#define SCBCTRL_SERVICESSR_BUSY_MASK (1u << SCBCTRL_SERVICESSR_BUSY)
|
||||
|
||||
#define SCBCTRL_SERVICESSR_ABORT (2u)
|
||||
#define SCBCTRL_SERVICESSR_ABORT_MASK (1u << SCBCTRL_SERVICESSR_ABORT)
|
||||
|
||||
#define SCBCTRL_SERVICESSR_NOTIFY (3u)
|
||||
#define SCBCTRL_SERVICESSR_NOTIFY_MASK (1u << SCBCTRL_SERVICESSR_NOTIFY)
|
||||
|
||||
#define SCBCTRL_SERVICESSR_STATUS (16u)
|
||||
#define SCBCTRL_SERVICESSR_STATUS_MASK (0xFFFFu << SCBCTRL_SERVICESSR_STATUS)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_SYS_SERVICES_REGS_H_ */
|
|
@ -0,0 +1,779 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* PolarFire SoC Microprocessor Subsystem (MSS) Timer bare metal software driver
|
||||
* public API.
|
||||
*/
|
||||
/*=========================================================================*//**
|
||||
@mainpage PolarFire SoC MSS Timer Bare Metal Driver.
|
||||
|
||||
@section intro_sec Introduction
|
||||
The PolarFire SoC Microprocessor Subsystem (MSS) includes a timer hardware
|
||||
block which can be used as two independent 32-bits timers or as a single
|
||||
64-bits timer in periodic or one-shot mode.
|
||||
|
||||
This driver provides a set of functions for controlling the MSS timer as part
|
||||
of a bare metal system where no operating system is available. These drivers
|
||||
can be adapted for use as part of an operating system but the implementation
|
||||
of the adaptation layer between this driver and the operating system's driver
|
||||
model is outside the scope of this driver.
|
||||
|
||||
@section theory_op Theory of Operation
|
||||
The PolarFire SoC MSS Timer can be used in one of two mutually exclusive modes
|
||||
either as a single 64-bits timer or as two independent 32-bits timers. The MSS
|
||||
Timer can be used in either periodic mode or one-shot mode. A timer configured
|
||||
for periodic mode operations will generate an interrupt and reload its
|
||||
down-counter when it reaches 0. The timer will then continue decrementing from
|
||||
its reload value without waiting for the interrupt to be cleared. A timer
|
||||
configured for one-shot mode will only generate an interrupt once when its
|
||||
down-counter reaches 0. It must be explicitly reloaded to start decrementing
|
||||
again.
|
||||
|
||||
The MSS Timer driver functions are grouped into the following categories:
|
||||
- Initialization and Configuration
|
||||
- Timer control
|
||||
- Interrupt control
|
||||
|
||||
The MSS Timer driver provides three initialization functions:
|
||||
- MSS_TIM1_init()
|
||||
- MSS_TIM2_init()
|
||||
- MSS_TIM64_init()
|
||||
|
||||
The MSS Timer driver is initialized through calls to these functions and at
|
||||
least one of them must be called before any other MSS Timer driver functions
|
||||
can be called.
|
||||
You should only use the MSS_TIM1_init() and MSS_TIM2_init() functions if you
|
||||
intend to use the timer in 32-bits mode. Use the MSS_TIM64_init() function is
|
||||
you intend to use the MSS Timer as a single 64-bits timer. The initialization
|
||||
functions take a single parameter specifying the operating mode of the timer
|
||||
being initialized.
|
||||
|
||||
Once initialized a timer can be controlled using the following functions:
|
||||
- MSS_TIM1_load_immediate()
|
||||
- MSS_TIM1_load_background()
|
||||
- MSS_TIM1_get_current_value()
|
||||
- MSS_TIM1_start()
|
||||
- MSS_TIM1_stop()
|
||||
- MSS_TIM2_load_immediate()
|
||||
- MSS_TIM2_load_background()
|
||||
- MSS_TIM2_get_current_value()
|
||||
- MSS_TIM2_start()
|
||||
- MSS_TIM2_stop()
|
||||
- MSS_TIM64_load_immediate()
|
||||
- MSS_TIM64_load_background()
|
||||
- MSS_TIM64_get_current_value()
|
||||
- MSS_TIM64_start()
|
||||
- MSS_TIM64_stop()
|
||||
|
||||
Timer interrupts are controlled using the following functions:
|
||||
- MSS_TIM1_enable_irq()
|
||||
- MSS_TIM1_disable_irq()
|
||||
- MSS_TIM1_clear_irq()
|
||||
- MSS_TIM2_enable_irq()
|
||||
- MSS_TIM2_disable_irq()
|
||||
- MSS_TIM2_clear_irq()
|
||||
- MSS_TIM64_enable_irq()
|
||||
- MSS_TIM64_disable_irq()
|
||||
- MSS_TIM64_clear_irq()
|
||||
|
||||
The function prototypes for the timer interrupt handlers are:
|
||||
- void Timer1_IRQHandler( void )
|
||||
- void Timer2_IRQHandler( void )
|
||||
|
||||
Entries for these interrupt handlers are provided in the PolarFire SoC MPFS
|
||||
HAL vector table. To add a Timer 1 interrupt handler, you must implement a
|
||||
Timer1_IRQHandler( ) function as part of your application code. To add a
|
||||
Timer 2 interrupt handler, you must implement a Timer2_IRQHandler( ) function
|
||||
as part of your application code. When using the MSS Timer as a 64-bit timer,
|
||||
you must implement a Timer1_IRQHandler( ) function as part of your
|
||||
application code. The Timer 2 interrupt is not used when the MSS Timer is
|
||||
configured as a 64-bit timer.
|
||||
|
||||
*//*=========================================================================*/
|
||||
#ifndef MSS_TIMER_H_
|
||||
#define MSS_TIMER_H_
|
||||
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
#include "mss_timer_regs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Peripheral declaration */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define TIMER_LO ((TIMER_TypeDef *) TIMER_LO_BASE)
|
||||
#define TIMER_HI ((TIMER_TypeDef*) TIMER_HI_BASE)
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Timer mode selection. This enumeration is used to select between the two
|
||||
* possible timer modes of operation: periodic and one-shot mode. It is used as
|
||||
* an argument to the MSS_TIM1_init(), MSS_TIM2_init() and MSS_TIM64_init()
|
||||
* functions.
|
||||
* MSS_TIMER_PERIODIC_MODE:
|
||||
* In periodic mode the timer generates interrupts at constant intervals. On
|
||||
* reaching zero, the timer's counter is reloaded with a value held in a
|
||||
* register and begins counting down again.
|
||||
* MSS_TIMER_ONE_SHOT_MODE:
|
||||
* The timer generates a single interrupt in this mode. On reaching zero, the
|
||||
* timer's counter halts until reprogrammed by the user.
|
||||
*/
|
||||
typedef enum __mss_timer_mode
|
||||
{
|
||||
MSS_TIMER_PERIODIC_MODE = 0,//!< MSS_TIMER_PERIODIC_MODE
|
||||
MSS_TIMER_ONE_SHOT_MODE = 1 //!< MSS_TIMER_ONE_SHOT_MODE
|
||||
} mss_timer_mode_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Timer operation mask defines.
|
||||
*/
|
||||
/* Timer 1 interrupt enable bits */
|
||||
#define TIM1_INTEN_MASK 0x00000004u
|
||||
|
||||
/* Timer 1 Mode bits */
|
||||
#define TIM1_MODE_SHIFT 1u
|
||||
#define TIM1_MODE_MASK 0x00000002u
|
||||
|
||||
/* Timer 1 enable bits */
|
||||
#define TIM1_ENABLE_MASK 0x00000001u
|
||||
|
||||
/* Timer 2 interrupt enable bits */
|
||||
#define TIM2_INTEN_MASK 0x00000004u
|
||||
|
||||
/* Timer 2 Mode bits */
|
||||
#define TIM2_MODE_SHIFT 1u
|
||||
#define TIM2_MODE_MASK 0x00000002u
|
||||
|
||||
/* Timer 2 enable bits */
|
||||
#define TIM2_ENABLE_MASK 0x00000001u
|
||||
|
||||
/* Timer 64 interrupt enable bits */
|
||||
#define TIM64_INTEN_MASK 0x00000004u
|
||||
|
||||
/* Timer 64 mode bits */
|
||||
#define TIM64_MODE_SHIFT 1u
|
||||
#define TIM64_MODE_MASK 0x00000002u
|
||||
|
||||
/* Timer 64 enable bits */
|
||||
#define TIM64_ENABLE_MASK 0x00000001u
|
||||
|
||||
static uint32_t readvalue[52] = {0};
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_init() function initializes the MSS Timer block for use as a
|
||||
32-bit timer and selects the operating mode for Timer 1. The MSS Timer block
|
||||
is out of reset before executing this function. The MSS_TIM1_init() function
|
||||
stops Timer 1, disables its interrupt, and sets the Timer 1 operating mode.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
@param mode
|
||||
The mode parameter specifies whether the timer will operate in periodic or
|
||||
one-shot mode. Allowed values for this parameter are:
|
||||
- MSS_TIMER_PERIODIC_MODE
|
||||
- MSS_TIMER_ONE_SHOT_MODE
|
||||
|
||||
Note:The MSS Timer block cannot be used both as a 64-bit and 32-bit timer.
|
||||
Calling MSS_TIM1_init() will overwrite any previous configuration
|
||||
of the MSS Timer as a 64-bit timer.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM1_init(TIMER_TypeDef* timer, mss_timer_mode_t mode)
|
||||
{
|
||||
PLIC_DisableIRQ(TIMER1_PLIC); /* Disable timer 1 irq */
|
||||
|
||||
timer->TIM64_MODE = 0u; /* switch to 32 bits mode */
|
||||
readvalue[1] = timer->TIM64_MODE;
|
||||
|
||||
/* Disable timer and interrupt and set mode (continuous/one-shot) */
|
||||
timer->TIM1_CTRL = TIM1_MODE_MASK & ((uint32_t)mode << TIM1_MODE_SHIFT);
|
||||
readvalue[2] = timer->TIM1_CTRL;
|
||||
|
||||
timer->TIM1_RIS = 1u; /* clear timer 1 interrupt */
|
||||
readvalue[3] = timer->TIM1_RIS;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_start() function enables Timer 1 and starts its down-counter
|
||||
decrementing from the load_value specified in previous calls to the
|
||||
MSS_TIM1_load_immediate() or MSS_TIM1_load_background() functions.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
Note: The MSS_TIM1_start() function is also used to resume the down-counter
|
||||
if previously stopped using the MSS_TIM1_stop() function.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM1_start(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM1_CTRL |= TIM1_ENABLE_MASK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_stop() function disables Timer 1 and stops its down-counter
|
||||
decrementing.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM1_stop(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM1_CTRL &= ~((uint32_t)TIM1_ENABLE_MASK); /* disable timer */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_get_current_value() returns the current value of the Timer 1
|
||||
down-counter.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
@return
|
||||
This function returns the 32-bits current value of the Timer 1 down-counter.
|
||||
*/
|
||||
static inline uint32_t
|
||||
MSS_TIM1_get_current_value(TIMER_TypeDef* timer)
|
||||
{
|
||||
return timer->TIM1_VAL;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_load_immediate() function loads the value passed by the
|
||||
load_value parameter into the Timer 1 down-counter. The counter will
|
||||
decrement immediately from this value once Timer 1 is enabled. The MSS
|
||||
Timer will generate an interrupt when the counter reaches zero, if Timer 1
|
||||
interrupts are enabled. This function is intended to be used when Timer 1
|
||||
is configured for one-shot mode to time a single delay.
|
||||
|
||||
Note: The value passed by the load_value parameter is loaded immediately
|
||||
into the down-counter regardless of whether Timer 1 is operating in
|
||||
periodic or one-shot mode.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
@param load_value
|
||||
The load_value parameter specifies the value from which the Timer 1
|
||||
down-counter will start decrementing from.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM1_load_immediate(TIMER_TypeDef* timer, uint32_t load_value)
|
||||
{
|
||||
timer->TIM1_LOADVAL = load_value;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_load_background() function is used to specify the value that will
|
||||
be reloaded into the Timer 1 down-counter the next time the counter reaches
|
||||
zero. This function is typically used when Timer 1 is configured for periodic
|
||||
mode operation to select or change the delay period between the interrupts
|
||||
generated by Timer 1.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
@param load_value
|
||||
The load_value parameter specifies the value that will be loaded into the
|
||||
Timer 1 down-counter the next time the down-counter reaches zero. The Timer
|
||||
1 down-counter will start decrementing from this value after the current
|
||||
count expires.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM1_load_background(TIMER_TypeDef* timer, uint32_t load_value)
|
||||
{
|
||||
timer->TIM1_BGLOADVAL = load_value;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_enable_irq() function is used to enable interrupt generation for
|
||||
Timer 1. This function also enables the interrupt in the RISC-V PLIC. The
|
||||
Timer1_IRQHandler() function will be called when a Timer 1 interrupt occurs.
|
||||
|
||||
Note: A Timer1_IRQHandler() default implementation is defined, with weak
|
||||
linkage, in the MPFS HAL. You must provide your own implementation of
|
||||
the Timer1_IRQHandler() function, which will override the default
|
||||
implementation, to suit your application.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM1_enable_irq(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM1_CTRL |= TIM1_INTEN_MASK;
|
||||
readvalue[8] = timer->TIM1_CTRL;
|
||||
PLIC_EnableIRQ(TIMER1_PLIC);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_disable_irq() function is used to disable interrupt generation for
|
||||
Timer 1. This function also disables the interrupt in the RISC-V PLIC.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM1_disable_irq(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM1_CTRL &= ~((uint32_t)TIM1_INTEN_MASK);
|
||||
PLIC_DisableIRQ(TIMER1_PLIC); /* Disable timer 1 irq */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_clear_irq() function is used to clear a pending interrupt from
|
||||
Timer 1. This function also clears the interrupt in the RISC-V PLIC.
|
||||
|
||||
Note:You must call the MSS_TIM1_clear_irq() function as part of your
|
||||
implementation of the Timer1_IRQHandler() Timer 1 interrupt service
|
||||
routine (ISR) in order to prevent the same interrupt event
|
||||
retriggering a call to the ISR.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM1_clear_irq(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM1_RIS = 1u;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_init() function initializes the MSS Timer block for use as a
|
||||
32-bit timer and selects the operating mode for Timer 2. The MSS Timer block
|
||||
is already out of reset before executing MSS_TIM2_init() function. This
|
||||
function stops Timer 2, disables its interrupt and sets the Timer 2 operating
|
||||
mode.
|
||||
|
||||
Note:The MSS Timer block cannot be used both as a 64-bit and 32-bit timer.
|
||||
Calling MSS_TIM2_init() will overwrite any previous configuration of the
|
||||
MSS Timer as a 64-bit timer.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
@param mode
|
||||
The mode parameter specifies whether the timer will operate in periodic or
|
||||
one-shot mode. Allowed values for this parameter are:
|
||||
- MSS_TIMER_PERIODIC_MODE
|
||||
- MSS_TIMER_ONE_SHOT_MODE
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM2_init(TIMER_TypeDef* timer, mss_timer_mode_t mode)
|
||||
{
|
||||
PLIC_DisableIRQ(TIMER2_PLIC); /* Disable timer 2 irq */
|
||||
timer->TIM64_MODE = 0u; /* switch to 32 bits mode */
|
||||
|
||||
/* Disable timer and interrupt. Set mode (continuous/one-shot) */
|
||||
timer->TIM2_CTRL = TIM2_MODE_MASK & ((uint32_t)mode << TIM2_MODE_SHIFT);
|
||||
|
||||
timer->TIM2_RIS = 1u; /* clear timer 2 interrupt */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_start() function enables Timer 2 and starts its down-counter
|
||||
decrementing from the load_value specified in previous calls to the
|
||||
MSS_TIM2_load_immediate() or MSS_TIM2_load_background() functions.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
Note:The MSS_TIM2_start() function is also used to resume the down-counter
|
||||
if previously stopped using the MSS_TIM2_stop() function.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM2_start(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM2_CTRL |= TIM2_ENABLE_MASK; /* enable timer */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_stop() function disables Timer 2 and stops its down-counter
|
||||
decrementing.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM2_stop(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM2_CTRL &= ~((uint32_t)TIM2_ENABLE_MASK); /* disable timer */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_get_current_value() returns the current value of the Timer 2
|
||||
down-counter.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
*/
|
||||
static inline uint32_t
|
||||
MSS_TIM2_get_current_value(TIMER_TypeDef* timer)
|
||||
{
|
||||
return timer->TIM2_VAL;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_load_immediate() function loads the value passed by the
|
||||
load_value parameter into the Timer 2 down-counter. The counter will
|
||||
decrement immediately from this value once Timer 2 is enabled. The MSS Timer
|
||||
will generate an interrupt when the counter reaches zero if Timer 2
|
||||
interrupts are enabled. This function is intended to be used when Timer 2
|
||||
is configured for one-shot mode to time a single delay.
|
||||
|
||||
Note:The value passed by the load_value parameter is loaded immediately into
|
||||
the down-counter regardless of whether Timer 2 is operating in periodic
|
||||
or one-shot mode.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
@param load_value
|
||||
The load_value parameter specifies the value from which the Timer 2
|
||||
down-counter will start decrementing.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM2_load_immediate(TIMER_TypeDef* timer, uint32_t load_value)
|
||||
{
|
||||
timer->TIM2_LOADVAL = load_value;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_load_background() function is used to specify the value that will
|
||||
be reloaded into the Timer 2 down-counter the next time the counter reaches
|
||||
zero. This function is typically used when Timer 2 is configured for periodic
|
||||
mode operation to select or change the delay period between the interrupts
|
||||
generated by Timer 2.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
@param load_value
|
||||
The load_value parameter specifies the value that will be loaded into the
|
||||
Timer 2 down-counter the next time the down-counter reaches zero. The Timer
|
||||
2 down-counter will start decrementing from this value after the current
|
||||
count expires.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM2_load_background(TIMER_TypeDef* timer, uint32_t load_value)
|
||||
{
|
||||
timer->TIM2_BGLOADVAL = load_value;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_enable_irq() function is used to enable interrupt generation for
|
||||
Timer 2. This function also enables the interrupt in the RISC-V PLIC. The
|
||||
Timer2_IRQHandler() function will be called when a Timer 2 interrupt occurs.
|
||||
|
||||
Note:A Timer2_IRQHandler() default implementation is defined, with weak
|
||||
linkage, in the MPFS HAL. You must provide your own implementation of
|
||||
the Timer2_IRQHandler() function, which will override the default
|
||||
implementation, to suit your application.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM2_enable_irq(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM2_CTRL |= TIM2_INTEN_MASK;
|
||||
PLIC_EnableIRQ(TIMER2_PLIC);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_disable_irq() function is used to disable interrupt generation for
|
||||
Timer 2. This function also disables the interrupt in the RISC-V PLIC.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM2_disable_irq(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM2_CTRL &= ~((uint32_t)TIM2_INTEN_MASK);
|
||||
PLIC_DisableIRQ(TIMER2_PLIC); /* Disable timer 2 irq */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_clear_irq() function is used to clear a pending interrupt from
|
||||
Timer 2. This function also clears the interrupt in the RISC-V PLIC.
|
||||
|
||||
Note:You must call the MSS_TIM2_clear_irq() function as part of your
|
||||
implementation of the Timer2_IRQHandler() Timer 2 interrupt service
|
||||
routine (ISR) in order to prevent the same interrupt event retriggering
|
||||
a call to the ISR.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM2_clear_irq(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM2_RIS = 1u;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_init() function initializes the MSS Timer block for use as a
|
||||
single 64-bit timer and selects the operating mode of the timer. The MSS Timer
|
||||
block is already out of reset before executing MSS_TIM64_init() function.
|
||||
This function stops the timer, disables its interrupts, and sets the timer's
|
||||
operating mode.
|
||||
|
||||
Note:The MSS Timer block cannot be used both as a 64-bit and 32-bit timer.
|
||||
Calling MSS_TIM64_init() will overwrite any previous configuration of the
|
||||
MSS Timer as a 32-bit timer.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
@param mode
|
||||
The mode parameter specifies whether the timer will operate in periodic or
|
||||
one-shot mode. Allowed values for this parameter are:
|
||||
- MSS_TIMER_PERIODIC_MODE
|
||||
- MSS_TIMER_ONE_SHOT_MODE
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM64_init(TIMER_TypeDef* timer, mss_timer_mode_t mode)
|
||||
{
|
||||
PLIC_DisableIRQ(TIMER1_PLIC); /* Disable timer 1 irq */
|
||||
PLIC_DisableIRQ(TIMER2_PLIC); /* Disable timer 2 irq */
|
||||
|
||||
timer->TIM64_MODE = 1u; /* switch to 64 bits mode */
|
||||
|
||||
/* Disable timer and interrupt and set mode (continuous/one-shot) */
|
||||
timer->TIM64_CTRL = TIM64_MODE_MASK & ((uint32_t)mode << TIM64_MODE_SHIFT);
|
||||
|
||||
timer->TIM1_RIS = 1u; /* clear timer 1 interrupt */
|
||||
timer->TIM2_RIS = 1u; /* clear timer 2 interrupt */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_start() function enables the 64-bit timer and starts its
|
||||
down-counter decrementing from the load_value specified in previous calls to
|
||||
the MSS_TIM64_load_immediate() or MSS_TIM64_load_background() functions.
|
||||
|
||||
Note: The MSS_TIM64_start() function is also used to resume the down-counter
|
||||
if previously stopped using the MSS_TIM64_stop() function.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM64_start(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM64_CTRL |= TIM64_ENABLE_MASK; /* enable timer */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_stop() function disables the 64-bit timer and stops its
|
||||
down-counter decrementing.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM64_stop(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM64_CTRL &= ~((uint32_t)TIM64_ENABLE_MASK); /* disable timer */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_get_current_value() is used to read the current value of the
|
||||
64-bit timer down-counter.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
@param load_value_u
|
||||
The load_value_u parameter is a pointer to a 32-bit variable where the upper
|
||||
32 bits of the current value of the 64-bit timer down-counter will be copied.
|
||||
|
||||
@param load_value_l
|
||||
The load_value_l parameter is a pointer to a 32-bit variable where the lower
|
||||
32 bits of the current value of the 64-bit timer down-counter will be copied.
|
||||
|
||||
Example:
|
||||
@code
|
||||
uint32_t current_value_u = 0;
|
||||
uint32_t current_value_l = 0;
|
||||
MSS_TIM64_get_current_value( ¤t_value_u, ¤t_value_l );
|
||||
@endcode
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM64_get_current_value
|
||||
(
|
||||
TIMER_TypeDef* timer,
|
||||
uint32_t * load_value_u,
|
||||
uint32_t * load_value_l
|
||||
)
|
||||
{
|
||||
*load_value_l = timer->TIM64_VAL_L;
|
||||
*load_value_u = timer->TIM64_VAL_U;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_load_immediate() function loads the values passed by the
|
||||
load_value_u and load_value_l parameters into the 64-bit timer down-counter.
|
||||
The counter will decrement immediately from the concatenated 64-bit value once
|
||||
the 64-bit timer is enabled. The MSS Timer will generate an interrupt when the
|
||||
counter reaches zero if 64-bit timer interrupts are enabled. This function is
|
||||
intended to be used when the 64-bit timer is configured for one-shot mode to
|
||||
time a single delay.
|
||||
|
||||
Note: The value passed by the load_value parameter is loaded immediately into
|
||||
the down-counter regardless of whether the 64-bit timer is operating in
|
||||
periodic or one-shot mode.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
@param load_value_u
|
||||
The load_value_u parameter specifies the upper 32 bits of the 64-bit timer
|
||||
load value from which the 64-bit timer down-counter will start decrementing.
|
||||
|
||||
@param load_value_l
|
||||
The load_value_l parameter specifies the lower 32 bits of the 64-bit timer
|
||||
load value from which the 64-bit timer down-counter will start decrementing.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM64_load_immediate
|
||||
(
|
||||
TIMER_TypeDef* timer,
|
||||
uint32_t load_value_u,
|
||||
uint32_t load_value_l
|
||||
)
|
||||
{
|
||||
timer->TIM64_LOADVAL_U = load_value_u;
|
||||
timer->TIM64_LOADVAL_L = load_value_l;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_load_background() function is used to specify the 64-bit value
|
||||
that will be reloaded into the 64-bit timer down-counter the next time the
|
||||
counter reaches zero. This function is typically used when the 64-bit timer is
|
||||
configured for periodic mode operation to select or change the delay period
|
||||
between the interrupts generated by the 64-bit timer.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
@param load_value_u
|
||||
The load_value_u parameter specifies the upper 32 bits of the 64-bit timer
|
||||
load value. The concatenated 64-bit value formed from load_value_u and
|
||||
load_value_l will be loaded into the 64-bit timer down-counter the next
|
||||
time the down-counter reaches zero. The 64-bit timer down-counter will start
|
||||
decrementing from the concatenated 64-bit value after the current count
|
||||
expires.
|
||||
|
||||
@param load_value_l
|
||||
The load_value_l parameter specifies the lower 32 bits of the 64-bit timer
|
||||
load value. The concatenated 64-bit value formed from load_value_u and
|
||||
load_value_l will be loaded into the 64-bit timer down-counter the next time
|
||||
the down-counter reaches zero. The 64-bit timer down-counter will start
|
||||
decrementing from the concatenated 64-bit value after the current count
|
||||
expires.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM64_load_background
|
||||
(
|
||||
TIMER_TypeDef* timer,
|
||||
uint32_t load_value_u,
|
||||
uint32_t load_value_l
|
||||
)
|
||||
{
|
||||
timer->TIM64_BGLOADVAL_U = load_value_u;
|
||||
timer->TIM64_BGLOADVAL_L = load_value_l;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_enable_irq() function is used to enable interrupt generation for
|
||||
the 64-bit timer. This function also enables the interrupt in the RISC-V PLIC.
|
||||
The Timer1_IRQHandler() function will be called when a 64-bit timer interrupt
|
||||
occurs.
|
||||
|
||||
Note: A Timer1_IRQHandler() default implementation is defined, with weak
|
||||
linkage, in the MPFS HAL. You must provide your own implementation of
|
||||
the Timer1_IRQHandler() function, which will override the default
|
||||
implementation, to suit your application.
|
||||
|
||||
Note: The MSS_TIM64_enable_irq() function enables and uses Timer 1 interrupts
|
||||
for the 64-bit timer. Timer 2 interrupts remain disabled.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM64_enable_irq(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM64_CTRL |= TIM64_INTEN_MASK;
|
||||
PLIC_EnableIRQ(TIMER1_PLIC);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_disable_irq() function is used to disable interrupt generation
|
||||
for the 64-bit timer. This function also disables the interrupt in the RISC-V
|
||||
PLIC.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM64_disable_irq(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM64_CTRL &= ~((uint32_t)TIM64_INTEN_MASK);
|
||||
PLIC_DisableIRQ(TIMER1_PLIC);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_clear_irq() function is used to clear a pending interrupt from
|
||||
the 64-bit timer. This function also clears the interrupt in the RISC-V PLIC.
|
||||
|
||||
Note:You must call the MSS_TIM64_clear_irq() function as part of your
|
||||
implementation of the Timer1_IRQHandler() 64-bit timer interrupt service
|
||||
routine (ISR) in order to prevent the same interrupt event retriggering
|
||||
a call to the ISR.
|
||||
|
||||
@param timer
|
||||
The timer parameter specifies the Timer block to configure.
|
||||
*/
|
||||
static inline void
|
||||
MSS_TIM64_clear_irq(TIMER_TypeDef* timer)
|
||||
{
|
||||
timer->TIM64_RIS = 1u;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*MSS_TIMER_H_*/
|
|
@ -0,0 +1,60 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Register bit offsets and masks definitions for PolarFire SoC MSS Timer
|
||||
*/
|
||||
|
||||
#ifndef MSS_TIMER_REGS_H_
|
||||
#define MSS_TIMER_REGS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*--------------------------MPFS MSS Timer register map-----------------------*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
/* Timer 1 register declaration */
|
||||
const volatile uint32_t TIM1_VAL;
|
||||
volatile uint32_t TIM1_LOADVAL;
|
||||
volatile uint32_t TIM1_BGLOADVAL;
|
||||
volatile uint32_t TIM1_CTRL;
|
||||
volatile uint32_t TIM1_RIS;
|
||||
const volatile uint32_t TIM1_MIS;
|
||||
|
||||
/* Timer 2 register declaration */
|
||||
const volatile uint32_t TIM2_VAL;
|
||||
volatile uint32_t TIM2_LOADVAL;
|
||||
volatile uint32_t TIM2_BGLOADVAL;
|
||||
volatile uint32_t TIM2_CTRL;
|
||||
volatile uint32_t TIM2_RIS;
|
||||
const volatile uint32_t TIM2_MIS;
|
||||
|
||||
/* Timer 64 register declaration */
|
||||
const volatile uint32_t TIM64_VAL_U;
|
||||
const volatile uint32_t TIM64_VAL_L;
|
||||
volatile uint32_t TIM64_LOADVAL_U;
|
||||
volatile uint32_t TIM64_LOADVAL_L;
|
||||
volatile uint32_t TIM64_BGLOADVAL_U;
|
||||
volatile uint32_t TIM64_BGLOADVAL_L;
|
||||
volatile uint32_t TIM64_CTRL;
|
||||
volatile uint32_t TIM64_RIS;
|
||||
const volatile uint32_t TIM64_MIS;
|
||||
volatile uint32_t TIM64_MODE;
|
||||
} TIMER_TypeDef;
|
||||
|
||||
/******************************************************************************/
|
||||
/* Peripheral memory map */
|
||||
/******************************************************************************/
|
||||
#define TIMER_LO_BASE 0x20125000
|
||||
#define TIMER_HI_BASE 0x28125000
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_TIMER_REGS_H_ */
|
|
@ -0,0 +1,913 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* PolarFire SoC MSS USB Driver Stack
|
||||
* USB Core Interface Layer (USB-CIFL)
|
||||
* USB-CIF driver
|
||||
*
|
||||
* USB-CIF driver implementation:
|
||||
* This source file implements MSS USB Interrupt handler functions. This file
|
||||
* also implements core interface function for the logical layer to control
|
||||
* the MSS USB core. These interface functions are independent of the USB mode.
|
||||
*
|
||||
*/
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
#include "mss_usb_common_cif.h"
|
||||
#include "mss_usb_common_reg_io.h"
|
||||
|
||||
#ifdef MSS_USB_HOST_ENABLED
|
||||
#include "mss_usb_host_cif.h"
|
||||
#include "mss_usb_host_reg_io.h"
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef MSS_USB_HOST_ENABLED
|
||||
static uint8_t MSS_USB_CIF_host_rx_errchk(mss_usb_ep_num_t ep_num);
|
||||
static uint8_t MSS_USB_CIF_host_tx_errchk(mss_usb_ep_num_t ep_num);
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
|
||||
#ifdef MSS_USB_DEVICE_ENABLED
|
||||
static uint8_t MSS_USB_CIF_device_rx_errchk(mss_usb_ep_num_t ep_num);
|
||||
static uint8_t MSS_USB_CIF_device_tx_errchk(mss_usb_ep_num_t ep_num);
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
|
||||
/***************************************************************************//**
|
||||
* Global variables shared by mss_usb_device_cif.c and mss_usb_common_cif.c
|
||||
*/
|
||||
#ifdef MSS_USB_DEVICE_ENABLED
|
||||
extern mss_usbd_cb_t g_mss_usbd_cb;
|
||||
extern volatile mss_usbd_cep_state_t cep_state;
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
|
||||
#ifdef MSS_USB_HOST_ENABLED
|
||||
extern mss_usbh_cb_t g_mss_usbh_cb;
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
|
||||
/***************************************************************************//**
|
||||
* Private functions declarations of USB-CIF.
|
||||
******************************************************************************/
|
||||
static void
|
||||
MSS_USB_CIF_handle_cep_irq
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
static void
|
||||
MSS_USB_CIF_handle_tx_ep_irq
|
||||
(
|
||||
uint16_t irq_num
|
||||
);
|
||||
|
||||
static void
|
||||
MSS_USB_CIF_handle_rx_ep_irq
|
||||
(
|
||||
uint16_t irq_num
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Main USB interrupt handler. It checks for TX/RX endpoint interrupts and USB
|
||||
* system level interrupts and calls the appropriate routine.
|
||||
*/
|
||||
uint8_t usb_mc_plic_IRQHandler
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
volatile uint8_t usb_irq;
|
||||
volatile uint16_t tx_ep_irq;
|
||||
volatile uint16_t rx_ep_irq;
|
||||
volatile uint8_t role;
|
||||
|
||||
usb_irq = MSS_USB_CIF_read_irq_reg();
|
||||
tx_ep_irq = MSS_USB_CIF_read_tx_ep_irq_reg();
|
||||
rx_ep_irq = MSS_USB_CIF_read_rx_ep_irq_reg();
|
||||
|
||||
/*
|
||||
When operating in Host mode, on detecting Disconnect event, Disconnect
|
||||
Interrupt occurs but the HostMode bit in DevCtl is also cleared.
|
||||
Hence moving Disconnect handling out of get_mode condition.
|
||||
In the event of Disconnection, The decision is made based on the B-Device
|
||||
bit(DevCtl-D7).
|
||||
*/
|
||||
if (usb_irq & DISCONNECT_IRQ_MASK)
|
||||
{
|
||||
role = MSS_USB_CIF_get_role();
|
||||
|
||||
#ifdef MSS_USB_DEVICE_ENABLED
|
||||
if (MSS_USB_DEVICE_ROLE_DEVICE_B == role)
|
||||
{
|
||||
MSS_USB_CIF_enable_usbirq(RESET_IRQ_MASK);
|
||||
g_mss_usbd_cb.usbd_disconnect();
|
||||
}
|
||||
#endif /* MSS_USB_DEVICE_ENABLED */
|
||||
|
||||
#ifdef MSS_USB_HOST_ENABLED
|
||||
if (MSS_USB_DEVICE_ROLE_DEVICE_A == role)
|
||||
{
|
||||
/*In Host mode, On removing the attached B-device the session bit
|
||||
somehow remains set.
|
||||
This bit need to be cleared otherwise RESET interrupt is not occurring
|
||||
when B-Device is connected after removing A-Device*/
|
||||
if (MSS_USB_CIF_is_session_on())
|
||||
{
|
||||
MSS_USB_CIF_stop_session();
|
||||
}
|
||||
|
||||
MSS_USBH_CIF_read_vbus_level();
|
||||
g_mss_usbh_cb.usbh_disconnect();
|
||||
}
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
}
|
||||
|
||||
#ifdef MSS_USB_DEVICE_ENABLED
|
||||
if (MSS_USB_CORE_MODE_DEVICE == MSS_USB_CIF_get_mode())
|
||||
{
|
||||
if (usb_irq & RESUME_IRQ_MASK)
|
||||
{
|
||||
g_mss_usbd_cb.usbd_resume();
|
||||
}
|
||||
if (usb_irq & SUSPEND_IRQ_MASK)
|
||||
{
|
||||
g_mss_usbd_cb.usbd_suspend();
|
||||
}
|
||||
if (usb_irq & RESET_IRQ_MASK)
|
||||
{
|
||||
MSS_USB_CIF_set_index_reg(MSS_USB_CEP);
|
||||
MSS_USB_CIF_enable_usbirq(DISCONNECT_IRQ_MASK | SUSPEND_IRQ_MASK);
|
||||
cep_state = MSS_USB_CTRL_EP_IDLE;
|
||||
MSS_USB_CIF_clr_usb_irq_reg();
|
||||
MSS_USB_CIF_cep_clr_setupend();
|
||||
MSS_USB_CIF_cep_clr_stall_sent();
|
||||
g_mss_usbd_cb.usbd_reset();
|
||||
}
|
||||
}
|
||||
#endif /* MSS_USB_DEVICE_ENABLED */
|
||||
|
||||
#ifdef MSS_USB_HOST_ENABLED
|
||||
if (MSS_USB_CORE_MODE_HOST == MSS_USB_CIF_get_mode())
|
||||
{
|
||||
role = MSS_USB_CIF_get_role();
|
||||
if (usb_irq & RESUME_IRQ_MASK)
|
||||
{
|
||||
/* Resume interrupt in Host mode means Remote Wakeup request */
|
||||
}
|
||||
|
||||
/* Vbus_err and session request interrupts are valid only in A device */
|
||||
if (MSS_USB_DEVICE_ROLE_DEVICE_A == role)
|
||||
{
|
||||
if (usb_irq & SESSION_REQUEST_IRQ_MASK)
|
||||
{
|
||||
/* This means SRP initiated by Target device. */
|
||||
}
|
||||
if (usb_irq & VBUS_ERROR_IRQ_MASK)
|
||||
{
|
||||
/* Power management */
|
||||
MSS_USBH_CIF_read_vbus_level();
|
||||
}
|
||||
}
|
||||
|
||||
if (usb_irq & CONNECT_IRQ_MASK)
|
||||
{
|
||||
MSS_USBH_CIF_handle_connect_irq();
|
||||
}
|
||||
|
||||
if (usb_irq & BABBLE_IRQ_MASK)
|
||||
{
|
||||
/* Not supported yet */
|
||||
}
|
||||
|
||||
#if 0 /* SOF interrupt is not processed */
|
||||
if (usb_irq & SOF_IRQ_MASK)
|
||||
{
|
||||
g_mss_usbd_cb.usb_device_sof(0);
|
||||
}
|
||||
#endif /* SOF interrupt is not processed */
|
||||
|
||||
}
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
|
||||
if (tx_ep_irq & 0x0001u)
|
||||
{
|
||||
/* handle EP0 IRQ */
|
||||
MSS_USB_CIF_handle_cep_irq();
|
||||
}
|
||||
|
||||
if (tx_ep_irq & 0xFFFEu) /* EP0 is handled above */
|
||||
{
|
||||
/* Handle TX EP here, pass on the EP numbers.Mask EP0 bit */
|
||||
tx_ep_irq &= 0xFFFEu;
|
||||
MSS_USB_CIF_handle_tx_ep_irq(tx_ep_irq);
|
||||
}
|
||||
|
||||
if (rx_ep_irq & 0xFFFEu) /* bit0 is not defined */
|
||||
{
|
||||
/* Handle RX EP here, pass on the EP numbers */
|
||||
MSS_USB_CIF_handle_rx_ep_irq(rx_ep_irq);
|
||||
}
|
||||
|
||||
return EXT_IRQ_KEEP_ENABLED;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Routine to handle the interrupt on Control Endpoint.(EP0)
|
||||
*/
|
||||
static void
|
||||
MSS_USB_CIF_handle_cep_irq
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
uint8_t status = 0u;
|
||||
|
||||
MSS_USB_CIF_set_index_reg(MSS_USB_CEP);
|
||||
|
||||
#ifdef MSS_USB_DEVICE_ENABLED
|
||||
if (MSS_USB_CORE_MODE_DEVICE == MSS_USB_CIF_get_mode())
|
||||
{
|
||||
if (MSS_USB_CIF_cep_is_stall_sent())
|
||||
{
|
||||
status |= CTRL_EP_STALL_ERROR;
|
||||
MSS_USB_CIF_cep_clr_stall_sent();
|
||||
g_mss_usbd_cb.usbd_cep_setup(status);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MSS_USB_CIF_cep_is_setupend())
|
||||
{
|
||||
MSS_USB_CIF_cep_clr_setupend();
|
||||
|
||||
if (!MSS_USB_CIF_cep_is_rxpktrdy())
|
||||
{
|
||||
status |= CTRL_EP_SETUP_END_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
status &= ~CTRL_EP_SETUP_END_ERROR;
|
||||
}
|
||||
|
||||
g_mss_usbd_cb.usbd_cep_setup(status);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cep_state == MSS_USB_CTRL_EP_IDLE)
|
||||
{
|
||||
if (MSS_USB_CIF_cep_is_rxpktrdy())
|
||||
{
|
||||
g_mss_usbd_cb.usbd_cep_setup(status);
|
||||
}
|
||||
}
|
||||
else if (cep_state == MSS_USB_CTRL_EP_TX)
|
||||
{
|
||||
g_mss_usbd_cb.usbd_cep_tx_complete(status);
|
||||
}
|
||||
else if (cep_state == MSS_USB_CTRL_EP_RX)
|
||||
{
|
||||
if (MSS_USB_CIF_cep_is_rxpktrdy())
|
||||
{
|
||||
g_mss_usbd_cb.usbd_cep_rx(status);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* MSS_USB_DEVICE_ENABLED */
|
||||
|
||||
#ifdef MSS_USB_HOST_ENABLED
|
||||
if (MSS_USB_CORE_MODE_HOST == MSS_USB_CIF_get_mode())
|
||||
{
|
||||
if (MSS_USBH_CIF_cep_is_rxstall_err())
|
||||
{
|
||||
status |= MSS_USB_EP_STALL_RCVD;
|
||||
MSS_USBH_CIF_cep_clr_rxstall_err();
|
||||
}
|
||||
if (MSS_USBH_CIF_cep_is_retry_err())
|
||||
{
|
||||
status |= MSS_USB_EP_NO_RESPONSE;
|
||||
MSS_USBH_CIF_cep_clr_retry_err();
|
||||
}
|
||||
if (MSS_USBH_CIF_cep_is_naktimeout_err())
|
||||
{
|
||||
status |= MSS_USB_EP_NAK_TOUT;
|
||||
MSS_USBH_CIF_cep_clr_naktimeout_err();
|
||||
}
|
||||
if (status == 0u) /* No error was found */
|
||||
{
|
||||
status = MSS_USB_EP_TXN_SUCCESS;
|
||||
}
|
||||
g_mss_usbh_cb.usbh_cep(status);
|
||||
}
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Routine to handle the interrupt on TX_EP
|
||||
*/
|
||||
static void MSS_USB_CIF_handle_tx_ep_irq
|
||||
(
|
||||
uint16_t irq_num
|
||||
)
|
||||
{
|
||||
mss_usb_ep_num_t ep_num = MSS_USB_TX_EP_1;
|
||||
uint8_t status = 0u;
|
||||
|
||||
while (irq_num)
|
||||
{
|
||||
irq_num >>= 1u; /*EP1 starts from D1*/
|
||||
|
||||
if (irq_num & MSS_USB_WORD_BIT_0_MASK)
|
||||
{
|
||||
MSS_USB_CIF_tx_ep_disable_irq(ep_num);
|
||||
#ifdef MSS_USB_DEVICE_ENABLED
|
||||
if (MSS_USB_CORE_MODE_DEVICE == MSS_USB_CIF_get_mode())
|
||||
{
|
||||
status = MSS_USB_CIF_device_tx_errchk(ep_num);
|
||||
g_mss_usbd_cb.usbd_ep_tx_complete(ep_num,status);
|
||||
}
|
||||
#endif /* MSS_USB_DEVICE_ENABLED */
|
||||
|
||||
#ifdef MSS_USB_HOST_ENABLED
|
||||
if (MSS_USB_CORE_MODE_HOST == MSS_USB_CIF_get_mode())
|
||||
{
|
||||
status = MSS_USB_CIF_host_tx_errchk(ep_num);
|
||||
g_mss_usbh_cb.usbh_tx_complete((uint8_t)ep_num, status);
|
||||
}
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
|
||||
MSS_USB_CIF_tx_ep_enable_irq(ep_num);
|
||||
}
|
||||
status = 0u; /*resetting for next EP status*/
|
||||
++ep_num;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Routine to handle the interrupt on RX EP
|
||||
*/
|
||||
static void MSS_USB_CIF_handle_rx_ep_irq
|
||||
(
|
||||
uint16_t irq_num
|
||||
)
|
||||
{
|
||||
mss_usb_ep_num_t ep_num = MSS_USB_RX_EP_1;
|
||||
uint8_t status = 0u;
|
||||
|
||||
while (irq_num)
|
||||
{
|
||||
irq_num >>= 1u; /*EP1 starts from D1*/
|
||||
|
||||
if (irq_num & MSS_USB_WORD_BIT_0_MASK)
|
||||
{
|
||||
MSS_USB_CIF_rx_ep_disable_irq(ep_num);
|
||||
#ifdef MSS_USB_DEVICE_ENABLED
|
||||
if (MSS_USB_CORE_MODE_DEVICE == MSS_USB_CIF_get_mode())
|
||||
{
|
||||
status = MSS_USB_CIF_device_rx_errchk(ep_num);
|
||||
g_mss_usbd_cb.usbd_ep_rx(ep_num, status);
|
||||
}
|
||||
#endif /* MSS_USB_DEVICE_ENABLED */
|
||||
|
||||
#ifdef MSS_USB_HOST_ENABLED
|
||||
if (MSS_USB_CORE_MODE_HOST == MSS_USB_CIF_get_mode())
|
||||
{
|
||||
status = MSS_USB_CIF_host_rx_errchk(ep_num);
|
||||
g_mss_usbh_cb.usbh_rx((uint8_t)ep_num, status);
|
||||
}
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
MSS_USB_CIF_rx_ep_enable_irq(ep_num);
|
||||
}
|
||||
status = 0u; /*resetting for next EP status*/
|
||||
++ep_num;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Handler for DMA interrupt. Checks for the DMA channel on which interrupt has
|
||||
* Occurred and corresponding EP number then calls-back to upper layer to indicate
|
||||
* the event.
|
||||
*/
|
||||
uint8_t usb_dma_plic_IRQHandler(void)
|
||||
{
|
||||
mss_usb_dma_channel_t dma_channel= MSS_USB_DMA_CHANNEL1;
|
||||
uint8_t status = 0;
|
||||
mss_usb_dma_dir_t dma_dir;
|
||||
mss_usb_ep_num_t ep_num;
|
||||
uint8_t dma_irq;
|
||||
uint32_t increamented_addr=0;
|
||||
|
||||
dma_irq = MSS_USB_CIF_dma_read_irq();
|
||||
|
||||
while (dma_irq)
|
||||
{
|
||||
if (dma_irq & MSS_USB_BYTE_BIT_0_MASK)
|
||||
{
|
||||
/* DMA Transfer for this channel is complete.Clear Start_transfer
|
||||
bit
|
||||
*/
|
||||
MSS_USB_CIF_dma_stop_xfr(dma_channel);
|
||||
|
||||
ep_num = (mss_usb_ep_num_t)MSS_USB_CIF_dma_get_epnum(dma_channel);
|
||||
dma_dir = (mss_usb_dma_dir_t)MSS_USB_CIF_dma_get_dir(dma_channel);
|
||||
|
||||
if (MSS_USB_CIF_dma_is_bus_err(dma_channel))
|
||||
{
|
||||
status |=DMA_XFR_ERROR;
|
||||
MSS_USB_CIF_dma_clr_bus_err(dma_channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
increamented_addr = MSS_USB_CIF_dma_read_addr(dma_channel);
|
||||
if (MSS_USB_DMA_READ == dma_dir) /*TX EP*/
|
||||
{
|
||||
if (MSS_USB_CIF_tx_ep_is_dma_enabled(ep_num))
|
||||
{
|
||||
MSS_USB_CIF_tx_ep_disable_dma(ep_num);
|
||||
}
|
||||
}
|
||||
#ifdef MSS_USB_HOST_ENABLED
|
||||
if (MSS_USB_CORE_MODE_HOST == MSS_USB_CIF_get_mode())
|
||||
{
|
||||
/* Call the host mode logical layer driver callback
|
||||
function
|
||||
*/
|
||||
g_mss_usbh_cb.usbh_dma_handler(ep_num, dma_dir, status,
|
||||
increamented_addr);
|
||||
}
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
#ifdef MSS_USB_DEVICE_ENABLED
|
||||
if (MSS_USB_CORE_MODE_DEVICE == MSS_USB_CIF_get_mode())
|
||||
{
|
||||
/* Call the device mode logical layer driver callback
|
||||
function
|
||||
*/
|
||||
g_mss_usbd_cb.usbd_dma_handler(ep_num, dma_dir, status,
|
||||
increamented_addr);
|
||||
}
|
||||
#endif /* MSS_USB_DEVICE_ENABLED */
|
||||
|
||||
}
|
||||
}
|
||||
dma_channel++;
|
||||
dma_irq >>= 1u;
|
||||
}
|
||||
|
||||
return EXT_IRQ_KEEP_ENABLED;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Prepares the RX EP for receiving data as per parameters provided by upper layer
|
||||
*/
|
||||
void
|
||||
MSS_USB_CIF_rx_ep_read_prepare
|
||||
(
|
||||
mss_usb_ep_num_t ep_num,
|
||||
uint8_t* buf_addr,
|
||||
uint8_t dma_enable,
|
||||
mss_usb_dma_channel_t dma_channel,
|
||||
mss_usb_xfr_type_t xfr_type,
|
||||
uint32_t xfr_length
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Fixed Buffer overwriting issue found with printer driver and issue with
|
||||
* interrupt transfer with DMA by moving the location of interrupt enable
|
||||
* function.
|
||||
*/
|
||||
if (DMA_ENABLE == dma_enable)
|
||||
{
|
||||
/* Make sure that address is Modulo-4.Bits D0-D1 are read only.*/
|
||||
ASSERT(!(((uint32_t)buf_addr) & 0x00000002U));
|
||||
|
||||
MSS_USB_CIF_dma_write_addr(dma_channel, (uint32_t)buf_addr);
|
||||
|
||||
/*
|
||||
* DMA Count register will be loaded after receive interrupt occurs.
|
||||
* Mode need to be set every time since M1 to M0 transition might have
|
||||
* happened for "short packet".
|
||||
*/
|
||||
if (MSS_USB_XFR_BULK == xfr_type)
|
||||
{
|
||||
MSS_USB_CIF_rx_ep_set_dma_mode1(ep_num);
|
||||
MSS_USB_CIF_rx_ep_set_autoclr(ep_num);
|
||||
MSS_USB_CIF_rx_ep_enable_dma(ep_num);
|
||||
|
||||
MSS_USB_CIF_dma_write_count(dma_channel,
|
||||
xfr_length);
|
||||
|
||||
/* Handling single NULL packet reception */
|
||||
if (0u != xfr_length )
|
||||
{
|
||||
MSS_USB_CIF_dma_start_xfr(dma_channel);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MSS_USB_CIF_rx_ep_clr_autoclr(ep_num);
|
||||
MSS_USB_CIF_rx_ep_set_dma_mode0(ep_num);
|
||||
MSS_USB_CIF_rx_ep_disable_dma(ep_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Writes packet on TX EP
|
||||
*/
|
||||
void
|
||||
MSS_USB_CIF_ep_write_pkt
|
||||
(
|
||||
mss_usb_ep_num_t ep_num,
|
||||
uint8_t* buf_addr,
|
||||
uint8_t dma_enable,
|
||||
mss_usb_dma_channel_t dma_channel,
|
||||
mss_usb_xfr_type_t xfr_type,
|
||||
uint32_t xfr_length,
|
||||
uint32_t txn_length
|
||||
)
|
||||
{
|
||||
if (ep_num && (buf_addr != 0))
|
||||
{
|
||||
if (DMA_ENABLE == dma_enable)
|
||||
{
|
||||
/* Make sure that address is Modulo-4.Bits D0-D1 are read only.*/
|
||||
ASSERT(!(((uint32_t)buf_addr) & 0x00000002u));
|
||||
|
||||
MSS_USB_CIF_dma_write_addr(dma_channel,(uint32_t)(buf_addr));
|
||||
|
||||
if (MSS_USB_XFR_BULK == xfr_type)
|
||||
{
|
||||
MSS_USB_CIF_tx_ep_enable_dma(ep_num);
|
||||
|
||||
/*
|
||||
* DMA-m1 will take care of transferring 'xfr_length' data
|
||||
* as IN packets arrive.
|
||||
* DMA interrupt will occur when all TxMaxPkt size packets
|
||||
* are transferred.
|
||||
*/
|
||||
MSS_USB_CIF_dma_write_count(dma_channel, xfr_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* DMA Enable bit in TxCSR is not needed. If set,TX EP
|
||||
* Interrupt will not occur.
|
||||
*/
|
||||
MSS_USB_CIF_tx_ep_disable_dma(ep_num);
|
||||
|
||||
/* Transfer only one packet with DMA-m0 */
|
||||
MSS_USB_CIF_dma_write_count(dma_channel, txn_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* This will start DMA transfer.
|
||||
* TODO: For Null transfer DMA is not needed, but not setting
|
||||
* TxPktRdy bit here, is not invoking EP interrupt.
|
||||
* EP interrupt does get called when Null DMA transfer is done.
|
||||
*/
|
||||
MSS_USB_CIF_dma_start_xfr(dma_channel);
|
||||
|
||||
|
||||
/*
|
||||
* DMA interrupt will occur when all bytes are written to FIFO
|
||||
* TxPktRdy should be set when the DMA interrupt occurs.
|
||||
*/
|
||||
}
|
||||
else /* no DMA */
|
||||
{
|
||||
MSS_USB_CIF_load_tx_fifo(ep_num,
|
||||
buf_addr,
|
||||
txn_length);
|
||||
MSS_USB_CIF_tx_ep_set_txpktrdy(ep_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configures DMA for data transfer operations.
|
||||
*/
|
||||
void
|
||||
MSS_USB_CIF_configure_ep_dma
|
||||
(
|
||||
mss_usb_dma_channel_t dma_channel,
|
||||
mss_usb_dma_dir_t dma_dir,
|
||||
mss_usb_dma_mode_t dma_mode,
|
||||
mss_usb_dma_burst_mode_t burst_mode,
|
||||
mss_usb_ep_num_t ep_num,
|
||||
uint32_t buf_addr
|
||||
)
|
||||
{
|
||||
MSS_USB_CIF_dma_assign_to_epnum(dma_channel, ep_num);
|
||||
MSS_USB_CIF_dma_set_dir(dma_channel, dma_dir);
|
||||
MSS_USB_CIF_dma_set_mode(dma_channel, dma_mode);
|
||||
MSS_USB_CIF_dma_set_burst_mode(dma_channel, burst_mode);
|
||||
MSS_USB_CIF_dma_write_addr(dma_channel, buf_addr);
|
||||
MSS_USB_CIF_dma_enable_irq(dma_channel);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configures the TX EP for data transfer operations as per the parameters
|
||||
* provided by upper layer.
|
||||
*/
|
||||
void
|
||||
MSS_USB_CIF_tx_ep_configure
|
||||
|
||||
(
|
||||
mss_usb_ep_t* core_ep
|
||||
)
|
||||
{
|
||||
uint8_t dpb = 1u;
|
||||
mss_usb_dma_mode_t mode;
|
||||
|
||||
if (DPB_ENABLE == core_ep->dpb_enable)
|
||||
{
|
||||
dpb = 2u;
|
||||
}
|
||||
|
||||
MSS_USB_CIF_tx_ep_set_fifo_size(core_ep->num,
|
||||
((core_ep->fifo_size) / dpb),
|
||||
core_ep->dpb_enable);
|
||||
|
||||
MSS_USB_CIF_tx_ep_set_fifo_addr(core_ep->num, core_ep->fifo_addr);
|
||||
|
||||
if (DPB_ENABLE == core_ep->dpb_enable)
|
||||
{
|
||||
MSS_USB_enable_tx_ep_dpb(core_ep->num);
|
||||
}
|
||||
else if (DPB_DISABLE == core_ep->dpb_enable)
|
||||
{
|
||||
MSS_USB_disable_tx_ep_dpb(core_ep->num);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
MSS_USB_CIF_tx_ep_set_max_pkt(core_ep->num,
|
||||
core_ep->xfr_type,
|
||||
core_ep->max_pkt_size,
|
||||
core_ep->num_usb_pkt);
|
||||
|
||||
MSS_USB_CIF_tx_ep_clr_data_tog(core_ep->num);
|
||||
|
||||
if (DMA_ENABLE == core_ep->dma_enable)
|
||||
{
|
||||
if (MSS_USB_XFR_BULK == core_ep->xfr_type )
|
||||
{
|
||||
MSS_USB_CIF_tx_ep_set_dma_mode1(core_ep->num);
|
||||
MSS_USB_CIF_tx_ep_enable_dma(core_ep->num);
|
||||
mode = MSS_USB_DMA_MODE1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* DMA_ENable bit in TXCSRL is not required to be set for m0. if it
|
||||
* is set TX interrupt would not occur.
|
||||
*/
|
||||
MSS_USB_CIF_tx_ep_set_dma_mode0(core_ep->num);
|
||||
MSS_USB_CIF_tx_ep_disable_dma(core_ep->num);
|
||||
mode = MSS_USB_DMA_MODE0;
|
||||
}
|
||||
|
||||
MSS_USB_CIF_configure_ep_dma(core_ep->dma_channel,
|
||||
MSS_USB_DMA_READ,
|
||||
mode,
|
||||
MSS_USB_DMA_BURST_MODE3,
|
||||
core_ep->num,
|
||||
(uint32_t)(core_ep->buf_addr));
|
||||
}
|
||||
|
||||
MSS_USB_CIF_tx_ep_enable_irq(core_ep->num);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configures the RX EP for data transfer operations as per the parameters
|
||||
* provided by upper layer.
|
||||
*/
|
||||
void
|
||||
MSS_USB_CIF_rx_ep_configure
|
||||
|
||||
(
|
||||
mss_usb_ep_t* core_ep
|
||||
)
|
||||
{
|
||||
uint8_t dpb = 1u;
|
||||
mss_usb_dma_mode_t mode;
|
||||
|
||||
if (DPB_ENABLE == core_ep->dpb_enable)
|
||||
{
|
||||
dpb = 2u;
|
||||
}
|
||||
|
||||
MSS_USB_CIF_rx_ep_set_fifo_size(core_ep->num,
|
||||
((core_ep->fifo_size) / dpb),
|
||||
core_ep->dpb_enable);
|
||||
|
||||
MSS_USB_CIF_rx_ep_set_fifo_addr(core_ep->num,
|
||||
core_ep->fifo_addr);
|
||||
|
||||
if (DPB_ENABLE == core_ep->dpb_enable)
|
||||
{
|
||||
MSS_USB_CIF_enable_rx_ep_dpb(core_ep->num);
|
||||
}
|
||||
else if (DPB_DISABLE == core_ep->dpb_enable)
|
||||
{
|
||||
MSS_USB_CIF_disable_rx_ep_dpb(core_ep->num);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
MSS_USB_CIF_rx_ep_set_max_pkt(core_ep->num,
|
||||
core_ep->xfr_type,
|
||||
core_ep->max_pkt_size,
|
||||
core_ep->num_usb_pkt);
|
||||
|
||||
MSS_USB_CIF_rx_ep_clr_data_tog(core_ep->num);
|
||||
MSS_USB_CIF_rx_ep_clr_rxpktrdy(core_ep->num);
|
||||
|
||||
if (DMA_ENABLE == core_ep->dma_enable)
|
||||
{
|
||||
if (MSS_USB_XFR_BULK == core_ep->xfr_type)
|
||||
{
|
||||
MSS_USB_CIF_rx_ep_set_dma_mode1(core_ep->num);
|
||||
MSS_USB_CIF_rx_ep_enable_dma(core_ep->num);
|
||||
mode = MSS_USB_DMA_MODE1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* DMA_ENable bit in RXCSRL is not required to be set in m0. if it is
|
||||
* set RX interrupt would not occur.
|
||||
*/
|
||||
MSS_USB_CIF_rx_ep_set_dma_mode0(core_ep->num);
|
||||
MSS_USB_CIF_rx_ep_disable_dma(core_ep->num);
|
||||
mode = MSS_USB_DMA_MODE0;
|
||||
}
|
||||
|
||||
MSS_USB_CIF_configure_ep_dma(core_ep->dma_channel,
|
||||
MSS_USB_DMA_WRITE,
|
||||
mode,
|
||||
MSS_USB_DMA_BURST_MODE3,
|
||||
core_ep->num,
|
||||
(uint32_t)(core_ep->buf_addr));
|
||||
}
|
||||
|
||||
MSS_USB_CIF_rx_ep_enable_irq(core_ep->num);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Starts sending Test packet as specified in the USB2.0
|
||||
* This is USB-IF certification requirement.
|
||||
*/
|
||||
void MSS_USB_CIF_start_testpacket(void)
|
||||
{
|
||||
uint8_t test_pkt[53] =
|
||||
{
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0xAAU, 0xAAU, 0xAAU, 0xAAU, 0xAAU, 0xAAU, 0xAAU, 0xAAU, 0xEEU,
|
||||
0xEEU, 0xEEU, 0xEEU, 0xEEU, 0xEEU, 0xEEU, 0xEEU, 0xFEU, 0xFFU,
|
||||
0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU,
|
||||
0xFFU, 0x7FU, 0xBFU, 0xDFU, 0xEFU, 0xF7U, 0xFBU, 0xFDU, 0xFCU,
|
||||
0x7EU, 0xBFU, 0xDFU, 0xEFU, 0xF7U, 0xFBU, 0xFDU, 0x7EU
|
||||
};
|
||||
MSS_USB_CIF_load_tx_fifo(MSS_USB_CEP, test_pkt, 53u);
|
||||
MSS_USB_CIF_start_testpacket_bit();
|
||||
MSS_USB_CIF_cep_set_txpktrdy();
|
||||
MSS_USB_CIF_cep_disable_irq();
|
||||
}
|
||||
|
||||
#ifdef MSS_USB_HOST_ENABLED
|
||||
static uint8_t MSS_USB_CIF_host_rx_errchk(mss_usb_ep_num_t ep_num)
|
||||
{
|
||||
uint8_t status = 0u;
|
||||
|
||||
if (MSS_USBH_CIF_rx_ep_is_rxpktrdy(ep_num))
|
||||
{
|
||||
status = 0u;
|
||||
}
|
||||
if (MSS_USBH_CIF_rx_ep_is_rxstall_err(ep_num))
|
||||
{
|
||||
status |= MSS_USB_EP_STALL_RCVD;
|
||||
MSS_USBH_CIF_rx_ep_clr_rxstall_err(ep_num);
|
||||
}
|
||||
if (MSS_USBH_CIF_rx_ep_is_naktimeout_err(ep_num))
|
||||
{
|
||||
status |= MSS_USB_EP_NAK_TOUT;
|
||||
/* Not clearing NAKTIMEOUT error here. Application may want to abort
|
||||
* transfer. Clearing it here makes Scheduler keep trying the transfer
|
||||
*/
|
||||
}
|
||||
if (MSS_USBH_CIF_rx_ep_is_retry_err(ep_num))
|
||||
{
|
||||
status |= MSS_USB_EP_NO_RESPONSE;
|
||||
MSS_USBH_CIF_rx_ep_clr_retry_err(ep_num);
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
static uint8_t MSS_USB_CIF_host_tx_errchk(mss_usb_ep_num_t ep_num)
|
||||
{
|
||||
uint8_t status = 0;
|
||||
|
||||
if (MSS_USBH_CIF_tx_ep_is_retry_err(ep_num))
|
||||
{
|
||||
status |= MSS_USB_EP_NO_RESPONSE;
|
||||
MSS_USBH_CIF_tx_ep_clr_retry_err(ep_num);
|
||||
}
|
||||
if (MSS_USBH_CIF_tx_ep_is_rxstall_err(ep_num))
|
||||
{
|
||||
status |= MSS_USB_EP_STALL_RCVD;
|
||||
MSS_USBH_CIF_tx_ep_clr_rxstall_err(ep_num);
|
||||
}
|
||||
if (MSS_USBH_CIF_tx_ep_is_naktimeout_err(ep_num))
|
||||
{
|
||||
status |= MSS_USB_EP_NAK_TOUT;
|
||||
/* Not clearing NAKTIMEOUT error here. Application may want to abort
|
||||
* transfer. Clearing it here makes Scheduler keep trying the transfer
|
||||
*/
|
||||
}
|
||||
|
||||
return(status);
|
||||
}
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
|
||||
#ifdef MSS_USB_DEVICE_ENABLED
|
||||
static uint8_t MSS_USB_CIF_device_rx_errchk(mss_usb_ep_num_t ep_num)
|
||||
{
|
||||
uint8_t status = 0u;
|
||||
|
||||
if (MSS_USB_CIF_rx_ep_is_overrun(ep_num))
|
||||
{
|
||||
status |= RX_EP_OVER_RUN_ERROR;
|
||||
MSS_USB_CIF_rx_ep_clr_overrun(ep_num);
|
||||
}
|
||||
if (MSS_USB_CIF_rx_ep_is_stall_sent_bit(ep_num))
|
||||
{
|
||||
status |= RX_EP_STALL_ERROR;
|
||||
/*
|
||||
* "sent stall" bit should be cleared."Send Stall" bit is still set.
|
||||
* it should be cleared via Clear feature command or reset"
|
||||
*/
|
||||
MSS_USB_CIF_rx_ep_clr_stall_sent_bit(ep_num);
|
||||
}
|
||||
if (MSS_USB_CIF_rx_ep_is_dataerr(ep_num))
|
||||
{
|
||||
/* This error will be cleared when RxPktRdy bit is cleared.
|
||||
*/
|
||||
status |= RX_EP_DATA_ERROR;
|
||||
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
* PID error and INCOMP error should be checked only in ISO transfers.
|
||||
* This should be moved to logical layer
|
||||
*/
|
||||
if (MSS_USB_CIF_rx_ep_is_piderr(ep_num))
|
||||
{
|
||||
status |= RX_EP_PID_ERROR;
|
||||
/* Data sheet doesn't mention about how this error bit is cleared
|
||||
* Assuming that this will be cleared when RxPKTRdy is cleared.*/
|
||||
}
|
||||
if (MSS_USB_CIF_rx_ep_is_isoincomp(ep_num))
|
||||
{
|
||||
status |= RX_EP_ISO_INCOMP_ERROR;
|
||||
/* This error will be cleared when RxPktRdy bit is cleared.*/
|
||||
}
|
||||
#endif /* if 0 */
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
static uint8_t MSS_USB_CIF_device_tx_errchk(mss_usb_ep_num_t ep_num)
|
||||
{
|
||||
uint8_t status = 0u;
|
||||
|
||||
if (MSS_USB_CIF_tx_ep_is_underrun(ep_num))
|
||||
{
|
||||
/* Under-run errors should happen only for ISO endpoints.*/
|
||||
status |= TX_EP_UNDER_RUN_ERROR;
|
||||
MSS_USB_CIF_tx_ep_clr_underrun(ep_num);
|
||||
}
|
||||
if (MSS_USB_CIF_tx_ep_is_stall_sent_bit(ep_num))
|
||||
{
|
||||
status |= TX_EP_STALL_ERROR;
|
||||
MSS_USB_CIF_tx_ep_clr_stall_sent_bit(ep_num);
|
||||
}
|
||||
|
||||
return(status);
|
||||
}
|
||||
#endif /* MSS_USB_DEVICE_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,542 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* PolarFire SoC MSS USB Driver Stack
|
||||
* USB Core Interface Layer (USB-CIFL)
|
||||
* USB-CIF driver
|
||||
*
|
||||
* USB-CIF driver public API.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MSS_USB_COMMON_CIF_H_
|
||||
#define __MSS_USB_COMMON_CIF_H_
|
||||
|
||||
#include "mss_usb_config.h"
|
||||
#include "mss_usb_core_regs.h"
|
||||
|
||||
#define __INLINE inline
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Constant values internally used by the driver.
|
||||
*/
|
||||
#define CEP_MAX_PKT_SIZE 64u
|
||||
#define SETUP_PKT_SIZE 8u
|
||||
|
||||
#define DPB_DISABLE 0u
|
||||
#define DPB_ENABLE 1u
|
||||
|
||||
#ifdef MSS_USB_HOST_ENABLED
|
||||
#define SUSPENDM_DISABLE 0x0000u
|
||||
#define SUSPENDM_ENABLE 0x0001u
|
||||
#endif
|
||||
|
||||
#define MSS_USB_WORD_BIT_0_MASK 0x0001u
|
||||
#define MSS_USB_BYTE_BIT_0_MASK 0x01u
|
||||
|
||||
#define MSS_USB_BOOLEAN_FALSE 0x00u
|
||||
#define MSS_USB_BOOLEAN_TRUE 0x01u
|
||||
|
||||
#define TX_EP_UNDER_RUN_ERROR 0x01u
|
||||
#define TX_EP_STALL_ERROR 0x02u
|
||||
|
||||
#define RX_EP_OVER_RUN_ERROR 0x01u
|
||||
#define RX_EP_STALL_ERROR 0x02u
|
||||
#define RX_EP_DATA_ERROR 0x04u
|
||||
#define RX_EP_PID_ERROR 0x06u
|
||||
#define RX_EP_ISO_INCOMP_ERROR 0x08u
|
||||
|
||||
#define CTRL_EP_SETUP_END_ERROR 0x01u
|
||||
#define CTRL_EP_STALL_ERROR 0x02u
|
||||
|
||||
#define DMA_XFR_ERROR 0x40u
|
||||
|
||||
#define MIN_EP_FIFO_SZ 0x0008u
|
||||
#define EP_FIFO_ADDR_STEP 0x0008u
|
||||
|
||||
#define DMA_DISABLE 0u
|
||||
#define DMA_ENABLE 1u
|
||||
|
||||
#define NO_ZLP_TO_XFR 0u
|
||||
#define ADD_ZLP_TO_XFR 1u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
INTRUSBE register - USB interrupts masks
|
||||
*/
|
||||
#define SUSPEND_IRQ_MASK 0x01u
|
||||
#define RESUME_IRQ_MASK 0x02u
|
||||
#define RESET_IRQ_MASK 0x04u /*Device mode*/
|
||||
#define BABBLE_IRQ_MASK 0x04u /*Host mode*/
|
||||
#define SOF_IRQ_MASK 0x08u
|
||||
#define CONNECT_IRQ_MASK 0x10u
|
||||
#define DISCONNECT_IRQ_MASK 0x20u
|
||||
#define SESSION_REQUEST_IRQ_MASK 0x40u
|
||||
#define VBUS_ERROR_IRQ_MASK 0x80u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Types which can be used by LDL layer or the application.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
MSS_USB_XFR_CONTROL,
|
||||
MSS_USB_XFR_ISO,
|
||||
MSS_USB_XFR_BULK,
|
||||
MSS_USB_XFR_INTERRUPT,
|
||||
MSS_USB_XFR_HB_INTERRUPT,
|
||||
MSS_USB_XFR_HB_ISO
|
||||
} mss_usb_xfr_type_t;
|
||||
|
||||
typedef enum {
|
||||
MSS_USB_DEVICE_HS,
|
||||
MSS_USB_DEVICE_FS,
|
||||
MSS_USB_DEVICE_LS
|
||||
} mss_usb_device_speed_t;
|
||||
|
||||
typedef enum {
|
||||
MSS_USB_CEP = 0,
|
||||
MSS_USB_TX_EP_1,
|
||||
MSS_USB_TX_EP_2,
|
||||
MSS_USB_TX_EP_3,
|
||||
MSS_USB_TX_EP_4,
|
||||
|
||||
MSS_USB_RX_EP_1 = 1,
|
||||
MSS_USB_RX_EP_2,
|
||||
MSS_USB_RX_EP_3,
|
||||
MSS_USB_RX_EP_4
|
||||
} mss_usb_ep_num_t;
|
||||
|
||||
typedef enum {
|
||||
MSS_USB_DMA_CHANNEL1,
|
||||
MSS_USB_DMA_CHANNEL2,
|
||||
MSS_USB_DMA_CHANNEL3,
|
||||
MSS_USB_DMA_CHANNEL4,
|
||||
MSS_USB_DMA_CHANNEL_NA
|
||||
} mss_usb_dma_channel_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Types which are used internally by the driver.
|
||||
*/
|
||||
|
||||
/* Device mode: states of the device */
|
||||
typedef enum {
|
||||
MSS_USB_NOT_ATTACHED_STATE,
|
||||
MSS_USB_ATTACHED_STATE,
|
||||
MSS_USB_POWERED_STATE,
|
||||
MSS_USB_DEFAULT_STATE,
|
||||
MSS_USB_ADDRESS_STATE,
|
||||
MSS_USB_CONFIGURED_STATE,
|
||||
MSS_USB_SUSPENDED_STATE
|
||||
} mss_usb_state_t;
|
||||
|
||||
typedef enum {
|
||||
MSS_USB_CORE_MODE_HOST,
|
||||
MSS_USB_CORE_MODE_DEVICE
|
||||
} mss_usb_core_mode_t;
|
||||
|
||||
typedef enum {
|
||||
MSS_USB_EP_VALID = 0u,
|
||||
MSS_USB_EP_STALLED,
|
||||
MSS_USB_EP_NAK,
|
||||
MSS_USB_EP_NYET,
|
||||
MSS_USB_CEP_IDLE,
|
||||
MSS_USB_CEP_SETUP,
|
||||
MSS_USB_CEP_TX,
|
||||
MSS_USB_CEP_RX,
|
||||
|
||||
#ifdef MSS_USB_HOST_ENABLED
|
||||
MSS_USB_CEP_STATUS_AFTER_IN,
|
||||
MSS_USB_CEP_STATUS_AFTER_OUT,
|
||||
MSS_USB_EP_TXN_SUCCESS,
|
||||
MSS_USB_EP_NAK_TOUT,
|
||||
MSS_USB_EP_NO_RESPONSE,
|
||||
MSS_USB_EP_STALL_RCVD,
|
||||
MSS_USB_EP_XFR_SUCCESS,
|
||||
MSS_USB_EP_ABORTED
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
|
||||
} mss_usb_ep_state_t;
|
||||
|
||||
typedef enum mss_usb_pkt_type {
|
||||
MSS_USB_SETUP_PKT,
|
||||
MSS_USB_IN_DATA_PKT,
|
||||
MSS_USB_OUT_DATA_PKT,
|
||||
MSS_USB_STATUS_PKT_AFTER_IN,
|
||||
MSS_USB_STATUS_PKT_AFTER_OUT
|
||||
}mss_usb_pkt_type_t;
|
||||
|
||||
/*
|
||||
Type of device - Detected through DevCTL.D7 register bit depending
|
||||
on the type of connector connected to on-board receptacle.
|
||||
*/
|
||||
typedef enum mss_usb_device_role {
|
||||
MSS_USB_DEVICE_ROLE_DEVICE_A,
|
||||
MSS_USB_DEVICE_ROLE_DEVICE_B
|
||||
} mss_usb_device_role_t;
|
||||
|
||||
typedef enum {
|
||||
MSS_USB_DMA_WRITE,
|
||||
MSS_USB_DMA_READ
|
||||
} mss_usb_dma_dir_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MSS_USB_DMA_MODE0=0,
|
||||
MSS_USB_DMA_MODE1=1
|
||||
} mss_usb_dma_mode_t;
|
||||
|
||||
typedef enum {
|
||||
MSS_USB_DMA_BURST_MODE0 = 0,
|
||||
MSS_USB_DMA_BURST_MODE1,
|
||||
MSS_USB_DMA_BURST_MODE2,
|
||||
MSS_USB_DMA_BURST_MODE3
|
||||
} mss_usb_dma_burst_mode_t;
|
||||
|
||||
typedef enum {
|
||||
VBUS_BLOW_SESSIONEND,
|
||||
VBUS_ABV_SESSIONEND_BLOW_AVALID,
|
||||
VBUS_ABV_AVALID_BLOW_VB_VALID,
|
||||
VBUS_ABV_VB_VALID
|
||||
} mss_usb_vbus_level_t;
|
||||
|
||||
#ifdef MSS_USB_DEVICE_ENABLED
|
||||
typedef enum {
|
||||
MSS_USB_CTRL_EP_IDLE,
|
||||
MSS_USB_CTRL_EP_TX,
|
||||
MSS_USB_CTRL_EP_RX
|
||||
} mss_usbd_cep_state_t;
|
||||
#endif /* MSS_USB_DEVICE_ENABLED */
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Data structures of USB-CIFL which are shared with USB-LL.
|
||||
*/
|
||||
typedef struct {
|
||||
/*EP configuration info*/
|
||||
mss_usb_ep_num_t num;
|
||||
|
||||
uint8_t dpb_enable; /*0 or 1*/
|
||||
uint16_t fifo_size; /*number of bytes*/
|
||||
uint16_t fifo_addr; /*number of bytes*/
|
||||
uint8_t dma_enable;
|
||||
mss_usb_dma_channel_t dma_channel;
|
||||
uint16_t max_pkt_size; /*Maxpktsize register value*/
|
||||
|
||||
uint8_t stall;
|
||||
mss_usb_ep_state_t state;
|
||||
|
||||
/*EP data Transfer related info*/
|
||||
mss_usb_xfr_type_t xfr_type;
|
||||
uint32_t add_zlp;
|
||||
|
||||
/*
|
||||
Number of pkts in one uFrame in case of Interrupt/ISO HB transfers. Number
|
||||
of split packets in case of Bulk transfers.Should always be more than 0.
|
||||
*/
|
||||
uint8_t num_usb_pkt;
|
||||
uint8_t* buf_addr;
|
||||
|
||||
/*
|
||||
Transfer level info, used mainly for control transfer where the
|
||||
total length of data transfer is prior know through setup transaction
|
||||
In case of bulk transfer with Autospliting/amalgamation, this value is used
|
||||
when length of transfer is bigger than one amalgamated packet.
|
||||
*/
|
||||
uint32_t xfr_length;
|
||||
uint32_t xfr_count;
|
||||
|
||||
/*
|
||||
Single packet Transaction level info
|
||||
In case of bulk transfer with Autospliting/amalgamation, this value
|
||||
represents the amalgamated packet.
|
||||
*/
|
||||
uint32_t txn_length;
|
||||
uint32_t txn_count;
|
||||
|
||||
#ifdef MSS_USB_HOST_ENABLED
|
||||
/*
|
||||
Manual toggle enable is required only when dynamic switching of EP is supported.
|
||||
We don't support it.
|
||||
HubAddr and HubPortNum registers are needed for talking to LS/FS devices
|
||||
connected through Hub - We don't support hub connected devices yet.
|
||||
LS/FS device directly connected to SF2 is supported though.
|
||||
*/
|
||||
uint8_t cep_data_dir;
|
||||
uint8_t* cep_cmd_addr;
|
||||
uint8_t disable_ping; /*Depends on target speed*/
|
||||
uint32_t req_pkt_n; /*No of IN packets*/
|
||||
/*
|
||||
Interval Must be in terms of frame/uframe. Indicates NAKLIMIT0 register value
|
||||
for EP0. TX/RXInterval register value for TX/RX EP.
|
||||
*/
|
||||
uint32_t interval;
|
||||
/*This index will be used to choose a particular connected device out of the
|
||||
Multiple connected devices when Multiple devices are supported.
|
||||
Currently we support only one device hence this will always evaluate to 0*/
|
||||
uint8_t tdev_idx;
|
||||
|
||||
#endif /* MSS_USB_HOST_ENABLED */
|
||||
|
||||
}mss_usb_ep_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Data structures which are used internally by the driver.
|
||||
*/
|
||||
/*Device mode configuration information*/
|
||||
typedef struct {
|
||||
uint8_t device_addr;
|
||||
uint8_t device_total_interfaces;
|
||||
uint8_t device_total_ep;
|
||||
mss_usb_state_t device_state;
|
||||
mss_usb_state_t device_state_at_suspend;
|
||||
uint8_t device_status;
|
||||
mss_usb_device_speed_t device_speed; /*USB speed in Device mode*/
|
||||
uint8_t active_config_num; /*SetConfig command*/
|
||||
uint8_t active_interface_num;/*SetInterface command*/
|
||||
uint16_t config_feature_status;
|
||||
uint8_t remote_wakeup;
|
||||
} mss_usbd_dev_conf_t;
|
||||
|
||||
/* Device mode call-back function called from CIF layer */
|
||||
typedef struct {
|
||||
void (*usbd_ep_rx)( mss_usb_ep_num_t num, uint8_t status );
|
||||
void (*usbd_ep_tx_complete)( mss_usb_ep_num_t num, uint8_t status );
|
||||
|
||||
void (*usbd_cep_setup)( uint8_t status );
|
||||
void (*usbd_cep_rx)( uint8_t status );
|
||||
void (*usbd_cep_tx_complete)( uint8_t status );
|
||||
|
||||
void (*usbd_sof)( uint8_t status );
|
||||
void (*usbd_reset)( void );
|
||||
void (*usbd_suspend)( void );
|
||||
void (*usbd_resume)( void );
|
||||
void (*usbd_disconnect)( void );
|
||||
void (*usbd_dma_handler)(mss_usb_ep_num_t ep_num, mss_usb_dma_dir_t dma_dir,
|
||||
uint8_t status, uint32_t dma_addr_val);
|
||||
} mss_usbd_cb_t;
|
||||
|
||||
/* MSS USB Hardware core information. This is read-only */
|
||||
typedef struct {
|
||||
uint8_t core_max_nbr_of_tx_ep;
|
||||
uint8_t core_max_nbr_of_rx_ep;
|
||||
uint8_t core_max_nbr_of_dma_chan;
|
||||
uint8_t core_ram_bus_width;
|
||||
uint8_t core_WTCON;
|
||||
uint8_t core_WTID;
|
||||
uint8_t core_VPLEN;
|
||||
uint8_t core_HS_EOF1;
|
||||
uint8_t core_FS_EOF1;
|
||||
uint8_t core_LS_EOF1;
|
||||
uint8_t core_configdata;
|
||||
} mss_usb_core_info_t;
|
||||
|
||||
/* Internal DMA Configuration data */
|
||||
typedef struct {
|
||||
uint8_t dma_channel;
|
||||
uint8_t dma_dir;
|
||||
uint8_t dma_assigned_ep;
|
||||
uint8_t dma_mode;
|
||||
uint8_t dma_burst_mode;
|
||||
uint8_t dma_status;
|
||||
} mss_usb_dma_t;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*_------------------------USB-CIF Public APIs--------------------------------*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
*/
|
||||
static __INLINE void MSS_USB_CIF_cep_flush_fifo(void)
|
||||
{
|
||||
USB->INDEXED_CSR.DEVICE_EP0.CSR0 |= CSR0H_DEV_FLUSH_FIFO_MASK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
*/
|
||||
static __INLINE void MSS_USB_CIF_tx_ep_flush_fifo(mss_usb_ep_num_t ep_num)
|
||||
{
|
||||
USB->ENDPOINT[ep_num].TX_CSR |= TxCSRL_REG_EPN_FLUSH_FIFO_MASK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
*/
|
||||
static __INLINE void MSS_USB_CIF_rx_ep_flush_fifo(mss_usb_ep_num_t ep_num)
|
||||
{
|
||||
USB->ENDPOINT[ep_num].RX_CSR |= RxCSRL_REG_EPN_FLUSH_FIFO_MASK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
*/
|
||||
static __INLINE uint8_t MSS_USB_CIF_rx_ep_is_fifo_full(mss_usb_ep_num_t ep_num)
|
||||
{
|
||||
return(((USB->ENDPOINT[ep_num].RX_CSR & RxCSRL_REG_EPN_RX_FIFO_FULL_MASK) ?
|
||||
MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Enables USB interrupts.
|
||||
*/
|
||||
static __INLINE void MSS_USB_CIF_enable_usbirq(uint8_t irq_mask)
|
||||
{
|
||||
USB->USB_ENABLE |= (irq_mask);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Disables USB interrupts.
|
||||
*/
|
||||
static __INLINE void MSS_USB_CIF_disable_usbirq(uint8_t irq_mask)
|
||||
{
|
||||
USB->USB_ENABLE &= ~(irq_mask);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Indicates that there is at least one byte available to be transmitted from
|
||||
TX FIFO
|
||||
*/
|
||||
static __INLINE uint8_t MSS_USB_CIF_is_txepfifo_notempty(mss_usb_ep_num_t ep_num)
|
||||
{
|
||||
return(((USB->ENDPOINT[ep_num].TX_CSR & TxCSRL_REG_EPN_TX_FIFO_NE_MASK)
|
||||
? 1u : 0u));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
*/
|
||||
static __INLINE void
|
||||
MSS_USB_CIF_cep_enable_irq
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
USB->TX_IRQ_ENABLE |= (uint16_t)(TX_IRQ_ENABLE_REG_CEP_MASK);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
*/
|
||||
static __INLINE void
|
||||
MSS_USB_CIF_cep_disable_irq
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
USB->TX_IRQ_ENABLE &= (uint16_t)(~TX_IRQ_ENABLE_REG_CEP_MASK);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
INDEX register related APIs
|
||||
*/
|
||||
static __INLINE void
|
||||
MSS_USB_CIF_set_index_reg
|
||||
(
|
||||
uint8_t index
|
||||
)
|
||||
{
|
||||
USB->INDEX = index;
|
||||
}
|
||||
|
||||
static __INLINE void MSS_USB_CIF_start_testse0nak(void)
|
||||
{
|
||||
USB->TEST_MODE = TESTMODE_SE0NAK_MASK;
|
||||
}
|
||||
|
||||
static __INLINE void MSS_USB_CIF_start_testj(void)
|
||||
{
|
||||
USB->TEST_MODE = TESTMODE_TESTJ_MASK;
|
||||
}
|
||||
|
||||
static __INLINE void MSS_USB_CIF_start_testk(void)
|
||||
{
|
||||
USB->TEST_MODE = TESTMODE_TESTK_MASK;
|
||||
}
|
||||
|
||||
static __INLINE void MSS_USB_CIF_start_testpacket_bit(void)
|
||||
{
|
||||
USB->TEST_MODE = TESTMODE_TESTPACKET_MASK;
|
||||
}
|
||||
|
||||
static __INLINE void MSS_USB_CIF_start_forcehost_ena(void)
|
||||
{
|
||||
USB->TEST_MODE = TESTMODE_FORCEHOST_MASK | TESTMODE_FORCEHS_MASK;
|
||||
}
|
||||
|
||||
static __INLINE void MSS_USB_CIF_end_testmode(void)
|
||||
{
|
||||
USB->TEST_MODE = 0x00U;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
*/
|
||||
void
|
||||
MSS_USB_CIF_configure_ep_dma
|
||||
(
|
||||
mss_usb_dma_channel_t channel,
|
||||
mss_usb_dma_dir_t dir,
|
||||
mss_usb_dma_mode_t dma_mode,
|
||||
mss_usb_dma_burst_mode_t burst_mode,
|
||||
mss_usb_ep_num_t ep_num,
|
||||
uint32_t buf_addr
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
*/
|
||||
void
|
||||
MSS_USB_CIF_tx_ep_configure
|
||||
(
|
||||
mss_usb_ep_t* core_ep
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
*/
|
||||
void
|
||||
MSS_USB_CIF_rx_ep_configure
|
||||
(
|
||||
mss_usb_ep_t* core_ep
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Prepares the RX EP for receiving data as per parameters provided by upper
|
||||
layer
|
||||
*/
|
||||
void
|
||||
MSS_USB_CIF_rx_ep_read_prepare
|
||||
(
|
||||
mss_usb_ep_num_t ep_num,
|
||||
uint8_t* buf_addr,
|
||||
uint8_t dma_enable,
|
||||
mss_usb_dma_channel_t dma_channel,
|
||||
mss_usb_xfr_type_t xfr_type,
|
||||
uint32_t xfr_length
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
*/
|
||||
void
|
||||
MSS_USB_CIF_ep_write_pkt
|
||||
(
|
||||
mss_usb_ep_num_t ep_num,
|
||||
uint8_t* buf_addr,
|
||||
uint8_t dma_enable,
|
||||
mss_usb_dma_channel_t dma_channel,
|
||||
mss_usb_xfr_type_t xfr_type,
|
||||
uint32_t xfr_length,
|
||||
uint32_t txn_length
|
||||
);
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
USB2.0 test mode functions
|
||||
*/
|
||||
void
|
||||
MSS_USB_CIF_start_testpacket
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__MSS_USB_COMMON_CIF_H_*/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,64 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* PolarFire SoC MSS USB Driver Stack
|
||||
*
|
||||
* MSS USB Driver stack configuration parameters.
|
||||
* User must choose the constant definitions in this file to select the mode of
|
||||
* operation.
|
||||
* The constants defined in this file are used by MSS USB driver stack to
|
||||
* function as per configuration.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MSS_USB_CONFIG_H_
|
||||
#define __MSS_USB_CONFIG_H_
|
||||
|
||||
#include "mpfs_hal/mss_hal.h"
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Definitions Internally generated for use in the Core and logical layer.
|
||||
*/
|
||||
#ifdef MSS_USB_OTG_DUAL_ROLE_MODE
|
||||
#define MSS_USB_HOST_ENABLED
|
||||
#define MSS_USB_DEVICE_ENABLED
|
||||
#define MSS_USB_OTG_SRP_ENABLED
|
||||
#define MSS_USB_OTG_HNP_ENABLED
|
||||
#endif
|
||||
|
||||
#ifdef MSS_USB_OTG_PERIPHERAL_MODE
|
||||
#define MSS_USB_DEVICE_ENABLED
|
||||
#define MSS_USB_OTG_SRP_ENABLED
|
||||
#endif
|
||||
|
||||
#ifdef MSS_USB_PERIPHERAL_MODE
|
||||
#define MSS_USB_DEVICE_ENABLED
|
||||
#define MSS_USB_DEVICE_PRINTER
|
||||
#endif
|
||||
|
||||
#ifdef MSS_USB_OTG_HOST_MODE
|
||||
#define MSS_USB_HOST_ENABLED
|
||||
#define MSS_USB_OTG_SRP_ENABLED
|
||||
#endif
|
||||
|
||||
#endif /* __MSS_USB_CONFIG_H_ */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue