xref: /qemu/tests/qtest/xlnx-canfd-test.c (revision 822cb97cefe2416ce61fe8007ad69904bbe24502)
18976fd2bSVikram Garhwal /*
28976fd2bSVikram Garhwal  * SPDX-License-Identifier: MIT
38976fd2bSVikram Garhwal  *
48976fd2bSVikram Garhwal  * QTests for the Xilinx Versal CANFD controller.
58976fd2bSVikram Garhwal  *
68976fd2bSVikram Garhwal  * Copyright (c) 2022 AMD Inc.
78976fd2bSVikram Garhwal  *
88976fd2bSVikram Garhwal  * Written-by: Vikram Garhwal<vikram.garhwal@amd.com>
98976fd2bSVikram Garhwal  *
108976fd2bSVikram Garhwal  * Permission is hereby granted, free of charge, to any person obtaining a copy
118976fd2bSVikram Garhwal  * of this software and associated documentation files (the "Software"), to deal
128976fd2bSVikram Garhwal  * in the Software without restriction, including without limitation the rights
138976fd2bSVikram Garhwal  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
148976fd2bSVikram Garhwal  * copies of the Software, and to permit persons to whom the Software is
158976fd2bSVikram Garhwal  * furnished to do so, subject to the following conditions:
168976fd2bSVikram Garhwal  *
178976fd2bSVikram Garhwal  * The above copyright notice and this permission notice shall be included in
188976fd2bSVikram Garhwal  * all copies or substantial portions of the Software.
198976fd2bSVikram Garhwal  *
208976fd2bSVikram Garhwal  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
218976fd2bSVikram Garhwal  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
228976fd2bSVikram Garhwal  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
238976fd2bSVikram Garhwal  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
248976fd2bSVikram Garhwal  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
258976fd2bSVikram Garhwal  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
268976fd2bSVikram Garhwal  * THE SOFTWARE.
278976fd2bSVikram Garhwal  */
288976fd2bSVikram Garhwal 
298976fd2bSVikram Garhwal #include "qemu/osdep.h"
308976fd2bSVikram Garhwal #include "libqtest.h"
318976fd2bSVikram Garhwal 
328976fd2bSVikram Garhwal /* Base address. */
338976fd2bSVikram Garhwal #define CANFD0_BASE_ADDR                0xff060000
348976fd2bSVikram Garhwal #define CANFD1_BASE_ADDR                0xff070000
358976fd2bSVikram Garhwal 
368976fd2bSVikram Garhwal /* Register addresses. */
378976fd2bSVikram Garhwal #define R_SRR_OFFSET                    0x00
388976fd2bSVikram Garhwal #define R_MSR_OFFSET                    0x04
398976fd2bSVikram Garhwal #define R_FILTER_CONTROL_REGISTER       0xe0
408976fd2bSVikram Garhwal #define R_SR_OFFSET                     0x18
418976fd2bSVikram Garhwal #define R_ISR_OFFSET                    0x1c
428976fd2bSVikram Garhwal #define R_IER_OFFSET                    0x20
438976fd2bSVikram Garhwal #define R_ICR_OFFSET                    0x24
448976fd2bSVikram Garhwal #define R_TX_READY_REQ_REGISTER         0x90
458976fd2bSVikram Garhwal #define RX_FIFO_STATUS_REGISTER         0xe8
468976fd2bSVikram Garhwal #define R_TXID_OFFSET                   0x100
478976fd2bSVikram Garhwal #define R_TXDLC_OFFSET                  0x104
488976fd2bSVikram Garhwal #define R_TXDATA1_OFFSET                0x108
498976fd2bSVikram Garhwal #define R_TXDATA2_OFFSET                0x10c
508976fd2bSVikram Garhwal #define R_AFMR_REGISTER0                0xa00
518976fd2bSVikram Garhwal #define R_AFIR_REGISTER0                0xa04
528976fd2bSVikram Garhwal #define R_RX0_ID_OFFSET                 0x2100
538976fd2bSVikram Garhwal #define R_RX0_DLC_OFFSET                0x2104
548976fd2bSVikram Garhwal #define R_RX0_DATA1_OFFSET              0x2108
558976fd2bSVikram Garhwal #define R_RX0_DATA2_OFFSET              0x210c
568976fd2bSVikram Garhwal 
578976fd2bSVikram Garhwal /* CANFD modes. */
588976fd2bSVikram Garhwal #define SRR_CONFIG_MODE                 0x00
598976fd2bSVikram Garhwal #define MSR_NORMAL_MODE                 0x00
608976fd2bSVikram Garhwal #define MSR_LOOPBACK_MODE               (1 << 1)
618976fd2bSVikram Garhwal #define ENABLE_CANFD                    (1 << 1)
628976fd2bSVikram Garhwal 
638976fd2bSVikram Garhwal /* CANFD status. */
648976fd2bSVikram Garhwal #define STATUS_CONFIG_MODE              (1 << 0)
658976fd2bSVikram Garhwal #define STATUS_NORMAL_MODE              (1 << 3)
668976fd2bSVikram Garhwal #define STATUS_LOOPBACK_MODE            (1 << 1)
678976fd2bSVikram Garhwal #define ISR_TXOK                        (1 << 1)
688976fd2bSVikram Garhwal #define ISR_RXOK                        (1 << 4)
698976fd2bSVikram Garhwal 
708976fd2bSVikram Garhwal #define ENABLE_ALL_FILTERS              0xffffffff
718976fd2bSVikram Garhwal #define ENABLE_ALL_INTERRUPTS           0xffffffff
728976fd2bSVikram Garhwal 
738976fd2bSVikram Garhwal /* We are sending one canfd message. */
748976fd2bSVikram Garhwal #define TX_READY_REG_VAL                0x1
758976fd2bSVikram Garhwal 
768976fd2bSVikram Garhwal #define FIRST_RX_STORE_INDEX            0x1
778976fd2bSVikram Garhwal #define STATUS_REG_MASK                 0xf
788976fd2bSVikram Garhwal #define DLC_FD_BIT_SHIFT                0x1b
798976fd2bSVikram Garhwal #define DLC_FD_BIT_MASK                 0xf8000000
808976fd2bSVikram Garhwal #define FIFO_STATUS_READ_INDEX_MASK     0x3f
818976fd2bSVikram Garhwal #define FIFO_STATUS_FILL_LEVEL_MASK     0x7f00
828976fd2bSVikram Garhwal #define FILL_LEVEL_SHIFT                0x8
838976fd2bSVikram Garhwal 
848976fd2bSVikram Garhwal /* CANFD frame size ID, DLC and 16 DATA word. */
858976fd2bSVikram Garhwal #define CANFD_FRAME_SIZE        18
868976fd2bSVikram Garhwal /* CAN frame size ID, DLC and 2 DATA word. */
878976fd2bSVikram Garhwal #define CAN_FRAME_SIZE          4
888976fd2bSVikram Garhwal 
898976fd2bSVikram Garhwal /* Set the filters for CANFD controller. */
enable_filters(QTestState * qts)908976fd2bSVikram Garhwal static void enable_filters(QTestState *qts)
918976fd2bSVikram Garhwal {
928976fd2bSVikram Garhwal      const uint32_t arr_afmr[32] = { 0xb423deaa, 0xa2a40bdc, 0x1b64f486,
938976fd2bSVikram Garhwal                                      0x95c0d4ee, 0xe0c44528, 0x4b407904,
948976fd2bSVikram Garhwal                                      0xd2673f46, 0x9fc638d6, 0x8844f3d8,
958976fd2bSVikram Garhwal                                      0xa607d1e8, 0x67871bf4, 0xc2557dc,
968976fd2bSVikram Garhwal                                      0x9ea5b53e, 0x3643c0cc, 0x5a05ea8e,
978976fd2bSVikram Garhwal                                      0x83a46d84, 0x4a25c2b8, 0x93a66008,
988976fd2bSVikram Garhwal                                      0x2e467470, 0xedc66118, 0x9086f9f2,
998976fd2bSVikram Garhwal                                      0xfa23dd36, 0xb6654b90, 0xb221b8ca,
1008976fd2bSVikram Garhwal                                      0x3467d1e2, 0xa3a55542, 0x5b26a012,
1018976fd2bSVikram Garhwal                                      0x2281ea7e, 0xcea0ece8, 0xdc61e588,
1028976fd2bSVikram Garhwal                                      0x2e5676a,  0x16821320 };
1038976fd2bSVikram Garhwal 
1048976fd2bSVikram Garhwal     const uint32_t arr_afir[32] = { 0xa833dfa1, 0x255a477e, 0x3a4bb1c5,
1058976fd2bSVikram Garhwal                                     0x8f560a6c, 0x27f38903, 0x2fecec4d,
1068976fd2bSVikram Garhwal                                     0xa014c66d, 0xec289b8,  0x7e52dead,
1078976fd2bSVikram Garhwal                                     0x82e94f3c, 0xcf3e3c5c, 0x66059871,
1088976fd2bSVikram Garhwal                                     0x3f213df4, 0x25ac3959, 0xa12e9bef,
1098976fd2bSVikram Garhwal                                     0xa3ad3af,  0xbafd7fe,  0xb3cb40fd,
1108976fd2bSVikram Garhwal                                     0x5d9caa81, 0x2ed61902, 0x7cd64a0,
1118976fd2bSVikram Garhwal                                     0x4b1fa538, 0x9b5ced8c, 0x150de059,
1128976fd2bSVikram Garhwal                                     0xd2794227, 0x635e820a, 0xbb6b02cf,
1138976fd2bSVikram Garhwal                                     0xbb58176,  0x570025bb, 0xa78d9658,
1148976fd2bSVikram Garhwal                                     0x49d735df, 0xe5399d2f };
1158976fd2bSVikram Garhwal 
1168976fd2bSVikram Garhwal     /* Passing the respective array values to all the AFMR and AFIR pairs. */
1178976fd2bSVikram Garhwal     for (int i = 0; i < 32; i++) {
1188976fd2bSVikram Garhwal         /* For CANFD0. */
1198976fd2bSVikram Garhwal        qtest_writel(qts, CANFD0_BASE_ADDR + R_AFMR_REGISTER0 + 8 * i,
1208976fd2bSVikram Garhwal                     arr_afmr[i]);
1218976fd2bSVikram Garhwal        qtest_writel(qts, CANFD0_BASE_ADDR + R_AFIR_REGISTER0 + 8 * i,
1228976fd2bSVikram Garhwal                     arr_afir[i]);
1238976fd2bSVikram Garhwal 
1248976fd2bSVikram Garhwal         /* For CANFD1. */
1258976fd2bSVikram Garhwal        qtest_writel(qts, CANFD1_BASE_ADDR + R_AFMR_REGISTER0 + 8 * i,
1268976fd2bSVikram Garhwal                     arr_afmr[i]);
1278976fd2bSVikram Garhwal        qtest_writel(qts, CANFD1_BASE_ADDR + R_AFIR_REGISTER0 + 8 * i,
1288976fd2bSVikram Garhwal                     arr_afir[i]);
1298976fd2bSVikram Garhwal     }
1308976fd2bSVikram Garhwal 
1318976fd2bSVikram Garhwal     /* Enable all the pairs from AFR register. */
1328976fd2bSVikram Garhwal     qtest_writel(qts, CANFD0_BASE_ADDR + R_FILTER_CONTROL_REGISTER,
1338976fd2bSVikram Garhwal                  ENABLE_ALL_FILTERS);
1348976fd2bSVikram Garhwal     qtest_writel(qts, CANFD1_BASE_ADDR + R_FILTER_CONTROL_REGISTER,
1358976fd2bSVikram Garhwal                  ENABLE_ALL_FILTERS);
1368976fd2bSVikram Garhwal }
1378976fd2bSVikram Garhwal 
configure_canfd(QTestState * qts,uint8_t mode)1388976fd2bSVikram Garhwal static void configure_canfd(QTestState *qts, uint8_t mode)
1398976fd2bSVikram Garhwal {
1408976fd2bSVikram Garhwal     uint32_t status = 0;
1418976fd2bSVikram Garhwal 
1428976fd2bSVikram Garhwal     /* Put CANFD0 and CANFD1 in config mode. */
1438976fd2bSVikram Garhwal     qtest_writel(qts, CANFD0_BASE_ADDR + R_SRR_OFFSET, SRR_CONFIG_MODE);
1448976fd2bSVikram Garhwal     qtest_writel(qts, CANFD1_BASE_ADDR + R_SRR_OFFSET, SRR_CONFIG_MODE);
1458976fd2bSVikram Garhwal 
1468976fd2bSVikram Garhwal     /* Write mode of operation in Mode select register. */
1478976fd2bSVikram Garhwal     qtest_writel(qts, CANFD0_BASE_ADDR + R_MSR_OFFSET, mode);
1488976fd2bSVikram Garhwal     qtest_writel(qts, CANFD1_BASE_ADDR + R_MSR_OFFSET, mode);
1498976fd2bSVikram Garhwal 
1508976fd2bSVikram Garhwal     enable_filters(qts);
1518976fd2bSVikram Garhwal 
1528976fd2bSVikram Garhwal     /* Check here if CANFD0 and CANFD1 are in config mode. */
1538976fd2bSVikram Garhwal     status = qtest_readl(qts, CANFD0_BASE_ADDR + R_SR_OFFSET);
1548976fd2bSVikram Garhwal     status = status & STATUS_REG_MASK;
1558976fd2bSVikram Garhwal     g_assert_cmpint(status, ==, STATUS_CONFIG_MODE);
1568976fd2bSVikram Garhwal 
1578976fd2bSVikram Garhwal     status = qtest_readl(qts, CANFD1_BASE_ADDR + R_SR_OFFSET);
1588976fd2bSVikram Garhwal     status = status & STATUS_REG_MASK;
1598976fd2bSVikram Garhwal     g_assert_cmpint(status, ==, STATUS_CONFIG_MODE);
1608976fd2bSVikram Garhwal 
1618976fd2bSVikram Garhwal     qtest_writel(qts, CANFD1_BASE_ADDR + R_IER_OFFSET, ENABLE_ALL_INTERRUPTS);
1628976fd2bSVikram Garhwal     qtest_writel(qts, CANFD1_BASE_ADDR + R_IER_OFFSET, ENABLE_ALL_INTERRUPTS);
1638976fd2bSVikram Garhwal 
1648976fd2bSVikram Garhwal     qtest_writel(qts, CANFD0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CANFD);
1658976fd2bSVikram Garhwal     qtest_writel(qts, CANFD1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CANFD);
1668976fd2bSVikram Garhwal }
1678976fd2bSVikram Garhwal 
generate_random_data(uint32_t * buf_tx,bool is_canfd_frame)1688976fd2bSVikram Garhwal static void generate_random_data(uint32_t *buf_tx, bool is_canfd_frame)
1698976fd2bSVikram Garhwal {
1708976fd2bSVikram Garhwal     /* Generate random TX data for CANFD frame. */
1718976fd2bSVikram Garhwal     if (is_canfd_frame) {
1728976fd2bSVikram Garhwal         for (int i = 0; i < CANFD_FRAME_SIZE - 2; i++) {
173*b52aa865SVikram Garhwal             buf_tx[2 + i] = g_random_int();
1748976fd2bSVikram Garhwal         }
1758976fd2bSVikram Garhwal     } else {
1768976fd2bSVikram Garhwal         /* Generate random TX data for CAN frame. */
1778976fd2bSVikram Garhwal         for (int i = 0; i < CAN_FRAME_SIZE - 2; i++) {
178*b52aa865SVikram Garhwal             buf_tx[2 + i] = g_random_int();
1798976fd2bSVikram Garhwal         }
1808976fd2bSVikram Garhwal     }
1818976fd2bSVikram Garhwal }
1828976fd2bSVikram Garhwal 
read_data(QTestState * qts,uint64_t can_base_addr,uint32_t * buf_rx,uint32_t frame_size)183*b52aa865SVikram Garhwal static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx,
184*b52aa865SVikram Garhwal                       uint32_t frame_size)
1858976fd2bSVikram Garhwal {
1868976fd2bSVikram Garhwal     uint32_t int_status;
1878976fd2bSVikram Garhwal     uint32_t fifo_status_reg_value;
1888976fd2bSVikram Garhwal     /* At which RX FIFO the received data is stored. */
1898976fd2bSVikram Garhwal     uint8_t store_ind = 0;
1908976fd2bSVikram Garhwal 
1918976fd2bSVikram Garhwal     /* Read the interrupt on CANFD rx. */
1928976fd2bSVikram Garhwal     int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_RXOK;
1938976fd2bSVikram Garhwal 
1948976fd2bSVikram Garhwal     g_assert_cmpint(int_status, ==, ISR_RXOK);
1958976fd2bSVikram Garhwal 
1968976fd2bSVikram Garhwal     /* Find the fill level and read index. */
1978976fd2bSVikram Garhwal     fifo_status_reg_value = qtest_readl(qts, can_base_addr +
1988976fd2bSVikram Garhwal                                         RX_FIFO_STATUS_REGISTER);
1998976fd2bSVikram Garhwal 
2008976fd2bSVikram Garhwal     store_ind = (fifo_status_reg_value & FIFO_STATUS_READ_INDEX_MASK) +
2018976fd2bSVikram Garhwal                 ((fifo_status_reg_value & FIFO_STATUS_FILL_LEVEL_MASK) >>
2028976fd2bSVikram Garhwal                   FILL_LEVEL_SHIFT);
2038976fd2bSVikram Garhwal 
2048976fd2bSVikram Garhwal     g_assert_cmpint(store_ind, ==, FIRST_RX_STORE_INDEX);
2058976fd2bSVikram Garhwal 
2068976fd2bSVikram Garhwal     /* Read the RX register data for CANFD. */
2078976fd2bSVikram Garhwal     buf_rx[0] = qtest_readl(qts, can_base_addr + R_RX0_ID_OFFSET);
2088976fd2bSVikram Garhwal     buf_rx[1] = qtest_readl(qts, can_base_addr + R_RX0_DLC_OFFSET);
2098976fd2bSVikram Garhwal 
210*b52aa865SVikram Garhwal     for (int i = 0; i < frame_size - 2; i++) {
2118976fd2bSVikram Garhwal         buf_rx[i + 2] = qtest_readl(qts,
2128976fd2bSVikram Garhwal                                 can_base_addr + R_RX0_DATA1_OFFSET + 4 * i);
2138976fd2bSVikram Garhwal     }
2148976fd2bSVikram Garhwal 
2158976fd2bSVikram Garhwal     /* Clear the RX interrupt. */
2168976fd2bSVikram Garhwal     qtest_writel(qts, CANFD1_BASE_ADDR + R_ICR_OFFSET, ISR_RXOK);
2178976fd2bSVikram Garhwal }
2188976fd2bSVikram Garhwal 
write_data(QTestState * qts,uint64_t can_base_addr,const uint32_t * buf_tx,bool is_canfd_frame)2198976fd2bSVikram Garhwal static void write_data(QTestState *qts, uint64_t can_base_addr,
2208976fd2bSVikram Garhwal                        const uint32_t *buf_tx, bool is_canfd_frame)
2218976fd2bSVikram Garhwal {
2228976fd2bSVikram Garhwal     /* Write the TX register data for CANFD. */
2238976fd2bSVikram Garhwal     qtest_writel(qts, can_base_addr + R_TXID_OFFSET, buf_tx[0]);
2248976fd2bSVikram Garhwal     qtest_writel(qts, can_base_addr + R_TXDLC_OFFSET, buf_tx[1]);
2258976fd2bSVikram Garhwal 
2268976fd2bSVikram Garhwal     if (is_canfd_frame) {
2278976fd2bSVikram Garhwal         for (int i = 0; i < CANFD_FRAME_SIZE - 2; i++) {
2288976fd2bSVikram Garhwal             qtest_writel(qts, can_base_addr + R_TXDATA1_OFFSET + 4 * i,
2298976fd2bSVikram Garhwal                          buf_tx[2 + i]);
2308976fd2bSVikram Garhwal         }
2318976fd2bSVikram Garhwal     } else {
2328976fd2bSVikram Garhwal         qtest_writel(qts, can_base_addr + R_TXDATA1_OFFSET, buf_tx[2]);
2338976fd2bSVikram Garhwal         qtest_writel(qts, can_base_addr + R_TXDATA2_OFFSET, buf_tx[3]);
2348976fd2bSVikram Garhwal     }
2358976fd2bSVikram Garhwal }
2368976fd2bSVikram Garhwal 
send_data(QTestState * qts,uint64_t can_base_addr)2378976fd2bSVikram Garhwal static void send_data(QTestState *qts, uint64_t can_base_addr)
2388976fd2bSVikram Garhwal {
2398976fd2bSVikram Garhwal     uint32_t int_status;
2408976fd2bSVikram Garhwal 
2418976fd2bSVikram Garhwal     qtest_writel(qts, can_base_addr + R_TX_READY_REQ_REGISTER,
2428976fd2bSVikram Garhwal                  TX_READY_REG_VAL);
2438976fd2bSVikram Garhwal 
2448976fd2bSVikram Garhwal     /* Read the interrupt on CANFD for tx. */
2458976fd2bSVikram Garhwal     int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_TXOK;
2468976fd2bSVikram Garhwal 
2478976fd2bSVikram Garhwal     g_assert_cmpint(int_status, ==, ISR_TXOK);
2488976fd2bSVikram Garhwal 
2498976fd2bSVikram Garhwal     /* Clear the interrupt for tx. */
2508976fd2bSVikram Garhwal     qtest_writel(qts, CANFD0_BASE_ADDR + R_ICR_OFFSET, ISR_TXOK);
2518976fd2bSVikram Garhwal }
2528976fd2bSVikram Garhwal 
match_rx_tx_data(const uint32_t * buf_tx,const uint32_t * buf_rx,bool is_canfd_frame)2538976fd2bSVikram Garhwal static void match_rx_tx_data(const uint32_t *buf_tx, const uint32_t *buf_rx,
2548976fd2bSVikram Garhwal                              bool is_canfd_frame)
2558976fd2bSVikram Garhwal {
2568976fd2bSVikram Garhwal     uint16_t size = 0;
2578976fd2bSVikram Garhwal     uint8_t len = CAN_FRAME_SIZE;
2588976fd2bSVikram Garhwal 
2598976fd2bSVikram Garhwal     if (is_canfd_frame) {
2608976fd2bSVikram Garhwal         len = CANFD_FRAME_SIZE;
2618976fd2bSVikram Garhwal     }
2628976fd2bSVikram Garhwal 
2638976fd2bSVikram Garhwal     while (size < len) {
2648976fd2bSVikram Garhwal         if (R_RX0_ID_OFFSET + 4 * size == R_RX0_DLC_OFFSET)  {
2658976fd2bSVikram Garhwal             g_assert_cmpint((buf_rx[size] & DLC_FD_BIT_MASK), ==,
2668976fd2bSVikram Garhwal                             (buf_tx[size] & DLC_FD_BIT_MASK));
2678976fd2bSVikram Garhwal         } else {
2688976fd2bSVikram Garhwal             g_assert_cmpint(buf_rx[size], ==, buf_tx[size]);
2698976fd2bSVikram Garhwal         }
2708976fd2bSVikram Garhwal 
2718976fd2bSVikram Garhwal         size++;
2728976fd2bSVikram Garhwal     }
2738976fd2bSVikram Garhwal }
2748976fd2bSVikram Garhwal /*
2758976fd2bSVikram Garhwal  * Xilinx CANFD supports both CAN and CANFD frames. This test will be
2768976fd2bSVikram Garhwal  * transferring CAN frame i.e. 8 bytes of data from CANFD0 and CANFD1 through
2778976fd2bSVikram Garhwal  * canbus. CANFD0 initiate the data transfer to can-bus, CANFD1 receives the
2788976fd2bSVikram Garhwal  * data. Test compares the can frame data sent from CANFD0 and received on
2798976fd2bSVikram Garhwal  * CANFD1.
2808976fd2bSVikram Garhwal  */
test_can_data_transfer(void)2818976fd2bSVikram Garhwal static void test_can_data_transfer(void)
2828976fd2bSVikram Garhwal {
2838976fd2bSVikram Garhwal     uint32_t buf_tx[CAN_FRAME_SIZE] = { 0x5a5bb9a4, 0x80000000,
2848976fd2bSVikram Garhwal                                         0x12345678, 0x87654321 };
2858976fd2bSVikram Garhwal     uint32_t buf_rx[CAN_FRAME_SIZE] = { 0x00, 0x00, 0x00, 0x00 };
2868976fd2bSVikram Garhwal     uint32_t status = 0;
2878976fd2bSVikram Garhwal 
2888976fd2bSVikram Garhwal     generate_random_data(buf_tx, false);
2898976fd2bSVikram Garhwal 
2908976fd2bSVikram Garhwal     QTestState *qts = qtest_init("-machine xlnx-versal-virt"
2918976fd2bSVikram Garhwal                 " -object can-bus,id=canbus"
2928976fd2bSVikram Garhwal                 " -machine canbus0=canbus"
2938976fd2bSVikram Garhwal                 " -machine canbus1=canbus"
2948976fd2bSVikram Garhwal                 );
2958976fd2bSVikram Garhwal 
2968976fd2bSVikram Garhwal     configure_canfd(qts, MSR_NORMAL_MODE);
2978976fd2bSVikram Garhwal 
2988976fd2bSVikram Garhwal     /* Check if CANFD0 and CANFD1 are in Normal mode. */
2998976fd2bSVikram Garhwal     status = qtest_readl(qts, CANFD0_BASE_ADDR + R_SR_OFFSET);
3008976fd2bSVikram Garhwal     status = status & STATUS_REG_MASK;
3018976fd2bSVikram Garhwal     g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
3028976fd2bSVikram Garhwal 
3038976fd2bSVikram Garhwal     status = qtest_readl(qts, CANFD1_BASE_ADDR + R_SR_OFFSET);
3048976fd2bSVikram Garhwal     status = status & STATUS_REG_MASK;
3058976fd2bSVikram Garhwal     g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
3068976fd2bSVikram Garhwal 
3078976fd2bSVikram Garhwal     write_data(qts, CANFD0_BASE_ADDR, buf_tx, false);
3088976fd2bSVikram Garhwal 
3098976fd2bSVikram Garhwal     send_data(qts, CANFD0_BASE_ADDR);
310*b52aa865SVikram Garhwal     read_data(qts, CANFD1_BASE_ADDR, buf_rx, CAN_FRAME_SIZE);
3118976fd2bSVikram Garhwal     match_rx_tx_data(buf_tx, buf_rx, false);
3128976fd2bSVikram Garhwal 
3138976fd2bSVikram Garhwal     qtest_quit(qts);
3148976fd2bSVikram Garhwal }
3158976fd2bSVikram Garhwal 
3168976fd2bSVikram Garhwal /*
3178976fd2bSVikram Garhwal  * This test will be transferring CANFD frame i.e. 64 bytes of data from CANFD0
3188976fd2bSVikram Garhwal  * and CANFD1 through canbus. CANFD0 initiate the data transfer to can-bus,
3198976fd2bSVikram Garhwal  * CANFD1 receives the data. Test compares the CANFD frame data sent from CANFD0
3208976fd2bSVikram Garhwal  * with received on CANFD1.
3218976fd2bSVikram Garhwal  */
test_canfd_data_transfer(void)3228976fd2bSVikram Garhwal static void test_canfd_data_transfer(void)
3238976fd2bSVikram Garhwal {
3248976fd2bSVikram Garhwal     uint32_t buf_tx[CANFD_FRAME_SIZE] = { 0x5a5bb9a4, 0xf8000000 };
3258976fd2bSVikram Garhwal     uint32_t buf_rx[CANFD_FRAME_SIZE] = { 0x00, 0x00, 0x00, 0x00 };
3268976fd2bSVikram Garhwal     uint32_t status = 0;
3278976fd2bSVikram Garhwal 
3288976fd2bSVikram Garhwal     generate_random_data(buf_tx, true);
3298976fd2bSVikram Garhwal 
3308976fd2bSVikram Garhwal     QTestState *qts = qtest_init("-machine xlnx-versal-virt"
3318976fd2bSVikram Garhwal                 " -object can-bus,id=canbus"
3328976fd2bSVikram Garhwal                 " -machine canbus0=canbus"
3338976fd2bSVikram Garhwal                 " -machine canbus1=canbus"
3348976fd2bSVikram Garhwal                 );
3358976fd2bSVikram Garhwal 
3368976fd2bSVikram Garhwal     configure_canfd(qts, MSR_NORMAL_MODE);
3378976fd2bSVikram Garhwal 
3388976fd2bSVikram Garhwal     /* Check if CANFD0 and CANFD1 are in Normal mode. */
3398976fd2bSVikram Garhwal     status = qtest_readl(qts, CANFD0_BASE_ADDR + R_SR_OFFSET);
3408976fd2bSVikram Garhwal     status = status & STATUS_REG_MASK;
3418976fd2bSVikram Garhwal     g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
3428976fd2bSVikram Garhwal 
3438976fd2bSVikram Garhwal     status = qtest_readl(qts, CANFD1_BASE_ADDR + R_SR_OFFSET);
3448976fd2bSVikram Garhwal     status = status & STATUS_REG_MASK;
3458976fd2bSVikram Garhwal     g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
3468976fd2bSVikram Garhwal 
3478976fd2bSVikram Garhwal     write_data(qts, CANFD0_BASE_ADDR, buf_tx, true);
3488976fd2bSVikram Garhwal 
3498976fd2bSVikram Garhwal     send_data(qts, CANFD0_BASE_ADDR);
350*b52aa865SVikram Garhwal     read_data(qts, CANFD1_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
3518976fd2bSVikram Garhwal     match_rx_tx_data(buf_tx, buf_rx, true);
3528976fd2bSVikram Garhwal 
3538976fd2bSVikram Garhwal     qtest_quit(qts);
3548976fd2bSVikram Garhwal }
3558976fd2bSVikram Garhwal 
3568976fd2bSVikram Garhwal /*
3578976fd2bSVikram Garhwal  * This test is performing loopback mode on CANFD0 and CANFD1. Data sent from
3588976fd2bSVikram Garhwal  * TX of each CANFD0 and CANFD1 are compared with RX register data for
3598976fd2bSVikram Garhwal  * respective CANFD Controller.
3608976fd2bSVikram Garhwal  */
test_can_loopback(void)3618976fd2bSVikram Garhwal static void test_can_loopback(void)
3628976fd2bSVikram Garhwal {
3638976fd2bSVikram Garhwal     uint32_t buf_tx[CANFD_FRAME_SIZE] = { 0x5a5bb9a4, 0xf8000000 };
3648976fd2bSVikram Garhwal     uint32_t buf_rx[CANFD_FRAME_SIZE] = { 0x00, 0x00, 0x00, 0x00 };
3658976fd2bSVikram Garhwal     uint32_t status = 0;
3668976fd2bSVikram Garhwal 
3678976fd2bSVikram Garhwal     generate_random_data(buf_tx, true);
3688976fd2bSVikram Garhwal 
3698976fd2bSVikram Garhwal     QTestState *qts = qtest_init("-machine xlnx-versal-virt"
3708976fd2bSVikram Garhwal                 " -object can-bus,id=canbus"
3718976fd2bSVikram Garhwal                 " -machine canbus0=canbus"
3728976fd2bSVikram Garhwal                 " -machine canbus1=canbus"
3738976fd2bSVikram Garhwal                 );
3748976fd2bSVikram Garhwal 
3758976fd2bSVikram Garhwal     configure_canfd(qts, MSR_LOOPBACK_MODE);
3768976fd2bSVikram Garhwal 
3778976fd2bSVikram Garhwal     /* Check if CANFD0 and CANFD1 are set in correct loopback mode. */
3788976fd2bSVikram Garhwal     status = qtest_readl(qts, CANFD0_BASE_ADDR + R_SR_OFFSET);
3798976fd2bSVikram Garhwal     status = status & STATUS_REG_MASK;
3808976fd2bSVikram Garhwal     g_assert_cmpint(status, ==, STATUS_LOOPBACK_MODE);
3818976fd2bSVikram Garhwal 
3828976fd2bSVikram Garhwal     status = qtest_readl(qts, CANFD1_BASE_ADDR + R_SR_OFFSET);
3838976fd2bSVikram Garhwal     status = status & STATUS_REG_MASK;
3848976fd2bSVikram Garhwal     g_assert_cmpint(status, ==, STATUS_LOOPBACK_MODE);
3858976fd2bSVikram Garhwal 
3868976fd2bSVikram Garhwal     write_data(qts, CANFD0_BASE_ADDR, buf_tx, true);
3878976fd2bSVikram Garhwal 
3888976fd2bSVikram Garhwal     send_data(qts, CANFD0_BASE_ADDR);
389*b52aa865SVikram Garhwal     read_data(qts, CANFD0_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
3908976fd2bSVikram Garhwal     match_rx_tx_data(buf_tx, buf_rx, true);
3918976fd2bSVikram Garhwal 
3928976fd2bSVikram Garhwal     generate_random_data(buf_tx, true);
3938976fd2bSVikram Garhwal 
3948976fd2bSVikram Garhwal     write_data(qts, CANFD1_BASE_ADDR, buf_tx, true);
3958976fd2bSVikram Garhwal 
3968976fd2bSVikram Garhwal     send_data(qts, CANFD1_BASE_ADDR);
397*b52aa865SVikram Garhwal     read_data(qts, CANFD1_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
3988976fd2bSVikram Garhwal     match_rx_tx_data(buf_tx, buf_rx, true);
3998976fd2bSVikram Garhwal 
4008976fd2bSVikram Garhwal     qtest_quit(qts);
4018976fd2bSVikram Garhwal }
4028976fd2bSVikram Garhwal 
main(int argc,char ** argv)4038976fd2bSVikram Garhwal int main(int argc, char **argv)
4048976fd2bSVikram Garhwal {
4058976fd2bSVikram Garhwal     g_test_init(&argc, &argv, NULL);
4068976fd2bSVikram Garhwal 
4078976fd2bSVikram Garhwal     qtest_add_func("/net/canfd/can_data_transfer", test_can_data_transfer);
4088976fd2bSVikram Garhwal     qtest_add_func("/net/canfd/canfd_data_transfer", test_canfd_data_transfer);
4098976fd2bSVikram Garhwal     qtest_add_func("/net/canfd/can_loopback", test_can_loopback);
4108976fd2bSVikram Garhwal 
4118976fd2bSVikram Garhwal     return g_test_run();
4128976fd2bSVikram Garhwal }
413