summaryrefslogtreecommitdiff
path: root/FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/mpfs_hal/common/mss_axiswitch.c
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/mpfs_hal/common/mss_axiswitch.c')
-rw-r--r--FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/mpfs_hal/common/mss_axiswitch.c266
1 files changed, 266 insertions, 0 deletions
diff --git a/FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/mpfs_hal/common/mss_axiswitch.c b/FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/mpfs_hal/common/mss_axiswitch.c
new file mode 100644
index 000000000..c324cdbdd
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/mpfs_hal/common/mss_axiswitch.c
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ * @file mss_axiswitch.c
+ * @author Microchip-FPGA Embedded Systems Solutions
+ * @brief PolarFire SoC MSS AXI switch configuration
+ *
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include "mpfs_hal/mss_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*Returns the value of AXI_HW_CFG_REG register*/
+uint32_t MSS_AXISW_get_hwcfg(void)
+{
+ return (AXISW->HWCFG);
+}
+
+/*Returns the value of AXI_VERSION_ID_REG register*/
+uint32_t MSS_AXISW_get_vid(void)
+{
+ return (AXISW->VID);
+}
+
+/*Performs write operation on the AXI SWITCH APB interface,
+ * Parameters:
+ * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
+
+
+ Note: QoS values are programmable through registers only for AXI3 configurations.
+ We have AXI4 so the QoS value programming should not be attempted.
+ IF you try to write/read QoS value you will get return value =1 (AXI_ERR_BIT)
+
+ Burstiness peak rate and transaction rate can be configured using other APIs.
+
+ data: QoS value to be programmed
+ return value: As received form AXI_ERR_BIT in CMD register.
+
+ * */
+uint32_t MSS_AXISW_write_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t data)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+
+ AXISW->DATA = data & AXISW_DATA_QOSVAL_MASK; /*only valid values of bits[3:0]*/
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ MSS_AXISW_QOS_VAL |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/*Performs read operation on the AXI SWITCH APB interface,
+ * Parameters:
+ * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
+ *
+ * Note: QoS values are programmable through registers only for AXI3 configurations.
+ We have AXI4 so the QoS value programming should not be attempted.
+ IF you try to write/read QoS value you will get return value =1 (AXI_ERR_BIT)
+ *
+ * returns the data returned by AXI SWITCH read operation for QoS command
+ *
+ * return value: As received form AXI_ERR_BIT in CMD register.
+ */
+uint32_t MSS_AXISW_read_qos_val(mss_axisw_mport_t master_port_num,
+ uint32_t* rd_data)
+{
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) | (MSS_AXISW_QOS_VAL) | AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ *rd_data = AXISW->DATA & AXISW_DATA_QOSVAL_MASK;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Programs the peak rate and transaction rate value for the given master port
+ read/write address channel
+
+ NOTE: Peak rate and transaction rate are programmed simultaneously in one command.
+ So we must make sure that both desired valid values must be provided.
+
+* return value: As received form AXI_ERR_BIT in CMD register.
+
+*/
+uint32_t MSS_AXISW_write_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t peak_rate,
+ mss_axisw_rate_t xct_rate)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+ AXISW->DATA = ((peak_rate) << AXISW_DATA_PEAKRT) | ((xct_rate) << AXISW_DATA_XCTRT) ;
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_PEAKRT_XCTRT) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Reads the peak rate and transaction rate value for the given master port
+read/write address channel
+peak_rate: returns the value of peak rate
+xct_rate: returns the value of transaction rate
+return value: As received form AXI_ERR_BIT in CMD register.
+
+*/
+uint32_t MSS_AXISW_read_rate(mss_axisw_mport_t master_port_num,
+ mss_axisw_rate_t* peak_rate,
+ mss_axisw_rate_t* xct_rate)
+{
+ uint32_t temp = 0u;
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write and command EN bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_PEAKRT_XCTRT) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ temp = AXISW->DATA;
+
+ *peak_rate = (temp & AXISW_DATA_PEAKRT_MASK) >> AXISW_DATA_PEAKRT;
+ *xct_rate = (temp & AXISW_DATA_XCTRT_MASK) >> AXISW_DATA_XCTRT;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Programs the burstiness value for the given master port read/write address channel
+
+burstiness_val: burstiness value to be programmed
+NOTE: Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1
+
+regulator_en: QoS regulator Enable 1= enable, 0 = disable
+
+* return value: As received form AXI_ERR_BIT in CMD register.
+*/
+int32_t MSS_AXISW_write_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t burstiness_val,
+ uint32_t regulator_en)
+{
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+
+ /*Write burstiness value and enable burstiness regulator.
+ * Burstiness_val=0 is not valid.
+ Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1*/
+
+ if(burstiness_val == 0)
+ {
+ return -1;
+ }
+ else
+ {
+ AXISW->DATA = ((burstiness_val - 1u) << AXISW_DATA_BURSTI) | (regulator_en & 0x01);
+ }
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_BURSTINESS_EN) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/* Reads the burstiness value for the given master port read/write address channel
+
+burstiness_val: Return parameter bit 23:16 shows the burstiness value.
+NOTE: Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1
+
+* return value: As received form AXI_ERR_BIT in CMD register.
+*/
+uint32_t MSS_AXISW_read_burstiness(mss_axisw_mport_t master_port_num,
+ uint32_t* burstiness_val)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write and command EN bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_BURSTINESS_EN) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ *burstiness_val = ((AXISW->DATA & AXISW_DATA_BURSTI_MASK) >> AXISW_DATA_BURSTI) + 1u;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+uint32_t MSS_AXISW_write_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t slave_ready_en)
+{
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
+
+ AXISW->DATA = slave_ready_en & 0x01; /*only valid value of bit0*/
+
+ AXISW->CMD = (AXISW_CMD_RW_MASK |
+ (master_port_num << AXISW_CMD_RWCHAN) |
+ MSS_AXISW_SLV_RDY |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+/*Performs read operation on the AXI SWITCH APB interface,
+ * Parameters:
+ * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
+ *
+ *
+ * slave_ready_en: returns the data returned by AXI SWITCH read operation for slave ready command
+ * return value: As received form AXI_ERR_BIT in CMD register.
+ *
+ */
+uint32_t MSS_AXISW_read_slave_ready(mss_axisw_mport_t master_port_num,
+ uint8_t* slave_ready_en)
+{
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write bit*/
+
+ AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
+ (MSS_AXISW_SLV_RDY) |
+ AXISW_CMD_EN_MASK);
+
+ while(AXISW->CMD & AXISW_CMD_EN_MASK);
+
+ *slave_ready_en = AXISW->DATA & 0x01;
+
+ return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+