1*a0c325c4SInès Varhol /* 2*a0c325c4SInès Varhol * QTest testcase for DM163 3*a0c325c4SInès Varhol * 4*a0c325c4SInès Varhol * Copyright (C) 2024 Samuel Tardieu <sam@rfc1149.net> 5*a0c325c4SInès Varhol * Copyright (C) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr> 6*a0c325c4SInès Varhol * Copyright (C) 2024 Inès Varhol <ines.varhol@telecom-paris.fr> 7*a0c325c4SInès Varhol * 8*a0c325c4SInès Varhol * SPDX-License-Identifier: GPL-2.0-or-later 9*a0c325c4SInès Varhol */ 10*a0c325c4SInès Varhol 11*a0c325c4SInès Varhol #include "qemu/osdep.h" 12*a0c325c4SInès Varhol #include "libqtest.h" 13*a0c325c4SInès Varhol 14*a0c325c4SInès Varhol enum DM163_INPUTS { 15*a0c325c4SInès Varhol SIN = 8, 16*a0c325c4SInès Varhol DCK = 9, 17*a0c325c4SInès Varhol RST_B = 10, 18*a0c325c4SInès Varhol LAT_B = 11, 19*a0c325c4SInès Varhol SELBK = 12, 20*a0c325c4SInès Varhol EN_B = 13 21*a0c325c4SInès Varhol }; 22*a0c325c4SInès Varhol 23*a0c325c4SInès Varhol #define DEVICE_NAME "/machine/dm163" 24*a0c325c4SInès Varhol #define GPIO_OUT(name, value) qtest_set_irq_in(qts, DEVICE_NAME, NULL, name, \ 25*a0c325c4SInès Varhol value) 26*a0c325c4SInès Varhol #define GPIO_PULSE(name) \ 27*a0c325c4SInès Varhol do { \ 28*a0c325c4SInès Varhol GPIO_OUT(name, 1); \ 29*a0c325c4SInès Varhol GPIO_OUT(name, 0); \ 30*a0c325c4SInès Varhol } while (0) 31*a0c325c4SInès Varhol 32*a0c325c4SInès Varhol 33*a0c325c4SInès Varhol static void rise_gpio_pin_dck(QTestState *qts) 34*a0c325c4SInès Varhol { 35*a0c325c4SInès Varhol /* Configure output mode for pin PB1 */ 36*a0c325c4SInès Varhol qtest_writel(qts, 0x48000400, 0xFFFFFEB7); 37*a0c325c4SInès Varhol /* Write 1 in ODR for PB1 */ 38*a0c325c4SInès Varhol qtest_writel(qts, 0x48000414, 0x00000002); 39*a0c325c4SInès Varhol } 40*a0c325c4SInès Varhol 41*a0c325c4SInès Varhol static void lower_gpio_pin_dck(QTestState *qts) 42*a0c325c4SInès Varhol { 43*a0c325c4SInès Varhol /* Configure output mode for pin PB1 */ 44*a0c325c4SInès Varhol qtest_writel(qts, 0x48000400, 0xFFFFFEB7); 45*a0c325c4SInès Varhol /* Write 0 in ODR for PB1 */ 46*a0c325c4SInès Varhol qtest_writel(qts, 0x48000414, 0x00000000); 47*a0c325c4SInès Varhol } 48*a0c325c4SInès Varhol 49*a0c325c4SInès Varhol static void rise_gpio_pin_selbk(QTestState *qts) 50*a0c325c4SInès Varhol { 51*a0c325c4SInès Varhol /* Configure output mode for pin PC5 */ 52*a0c325c4SInès Varhol qtest_writel(qts, 0x48000800, 0xFFFFF7FF); 53*a0c325c4SInès Varhol /* Write 1 in ODR for PC5 */ 54*a0c325c4SInès Varhol qtest_writel(qts, 0x48000814, 0x00000020); 55*a0c325c4SInès Varhol } 56*a0c325c4SInès Varhol 57*a0c325c4SInès Varhol static void lower_gpio_pin_selbk(QTestState *qts) 58*a0c325c4SInès Varhol { 59*a0c325c4SInès Varhol /* Configure output mode for pin PC5 */ 60*a0c325c4SInès Varhol qtest_writel(qts, 0x48000800, 0xFFFFF7FF); 61*a0c325c4SInès Varhol /* Write 0 in ODR for PC5 */ 62*a0c325c4SInès Varhol qtest_writel(qts, 0x48000814, 0x00000000); 63*a0c325c4SInès Varhol } 64*a0c325c4SInès Varhol 65*a0c325c4SInès Varhol static void rise_gpio_pin_lat_b(QTestState *qts) 66*a0c325c4SInès Varhol { 67*a0c325c4SInès Varhol /* Configure output mode for pin PC4 */ 68*a0c325c4SInès Varhol qtest_writel(qts, 0x48000800, 0xFFFFFDFF); 69*a0c325c4SInès Varhol /* Write 1 in ODR for PC4 */ 70*a0c325c4SInès Varhol qtest_writel(qts, 0x48000814, 0x00000010); 71*a0c325c4SInès Varhol } 72*a0c325c4SInès Varhol 73*a0c325c4SInès Varhol static void lower_gpio_pin_lat_b(QTestState *qts) 74*a0c325c4SInès Varhol { 75*a0c325c4SInès Varhol /* Configure output mode for pin PC4 */ 76*a0c325c4SInès Varhol qtest_writel(qts, 0x48000800, 0xFFFFFDFF); 77*a0c325c4SInès Varhol /* Write 0 in ODR for PC4 */ 78*a0c325c4SInès Varhol qtest_writel(qts, 0x48000814, 0x00000000); 79*a0c325c4SInès Varhol } 80*a0c325c4SInès Varhol 81*a0c325c4SInès Varhol static void rise_gpio_pin_rst_b(QTestState *qts) 82*a0c325c4SInès Varhol { 83*a0c325c4SInès Varhol /* Configure output mode for pin PC3 */ 84*a0c325c4SInès Varhol qtest_writel(qts, 0x48000800, 0xFFFFFF7F); 85*a0c325c4SInès Varhol /* Write 1 in ODR for PC3 */ 86*a0c325c4SInès Varhol qtest_writel(qts, 0x48000814, 0x00000008); 87*a0c325c4SInès Varhol } 88*a0c325c4SInès Varhol 89*a0c325c4SInès Varhol static void lower_gpio_pin_rst_b(QTestState *qts) 90*a0c325c4SInès Varhol { 91*a0c325c4SInès Varhol /* Configure output mode for pin PC3 */ 92*a0c325c4SInès Varhol qtest_writel(qts, 0x48000800, 0xFFFFFF7F); 93*a0c325c4SInès Varhol /* Write 0 in ODR for PC3 */ 94*a0c325c4SInès Varhol qtest_writel(qts, 0x48000814, 0x00000000); 95*a0c325c4SInès Varhol } 96*a0c325c4SInès Varhol 97*a0c325c4SInès Varhol static void rise_gpio_pin_sin(QTestState *qts) 98*a0c325c4SInès Varhol { 99*a0c325c4SInès Varhol /* Configure output mode for pin PA4 */ 100*a0c325c4SInès Varhol qtest_writel(qts, 0x48000000, 0xFFFFFDFF); 101*a0c325c4SInès Varhol /* Write 1 in ODR for PA4 */ 102*a0c325c4SInès Varhol qtest_writel(qts, 0x48000014, 0x00000010); 103*a0c325c4SInès Varhol } 104*a0c325c4SInès Varhol 105*a0c325c4SInès Varhol static void lower_gpio_pin_sin(QTestState *qts) 106*a0c325c4SInès Varhol { 107*a0c325c4SInès Varhol /* Configure output mode for pin PA4 */ 108*a0c325c4SInès Varhol qtest_writel(qts, 0x48000000, 0xFFFFFDFF); 109*a0c325c4SInès Varhol /* Write 0 in ODR for PA4 */ 110*a0c325c4SInès Varhol qtest_writel(qts, 0x48000014, 0x00000000); 111*a0c325c4SInès Varhol } 112*a0c325c4SInès Varhol 113*a0c325c4SInès Varhol static void test_dm163_bank(const void *opaque) 114*a0c325c4SInès Varhol { 115*a0c325c4SInès Varhol const unsigned bank = (uintptr_t) opaque; 116*a0c325c4SInès Varhol const int width = bank ? 192 : 144; 117*a0c325c4SInès Varhol 118*a0c325c4SInès Varhol QTestState *qts = qtest_initf("-M b-l475e-iot01a"); 119*a0c325c4SInès Varhol qtest_irq_intercept_out_named(qts, DEVICE_NAME, "sout"); 120*a0c325c4SInès Varhol GPIO_OUT(RST_B, 1); 121*a0c325c4SInès Varhol GPIO_OUT(EN_B, 0); 122*a0c325c4SInès Varhol GPIO_OUT(DCK, 0); 123*a0c325c4SInès Varhol GPIO_OUT(SELBK, bank); 124*a0c325c4SInès Varhol GPIO_OUT(LAT_B, 1); 125*a0c325c4SInès Varhol 126*a0c325c4SInès Varhol /* Fill bank with zeroes */ 127*a0c325c4SInès Varhol GPIO_OUT(SIN, 0); 128*a0c325c4SInès Varhol for (int i = 0; i < width; i++) { 129*a0c325c4SInès Varhol GPIO_PULSE(DCK); 130*a0c325c4SInès Varhol } 131*a0c325c4SInès Varhol /* Fill bank with ones, check that we get the previous zeroes */ 132*a0c325c4SInès Varhol GPIO_OUT(SIN, 1); 133*a0c325c4SInès Varhol for (int i = 0; i < width; i++) { 134*a0c325c4SInès Varhol GPIO_PULSE(DCK); 135*a0c325c4SInès Varhol g_assert(!qtest_get_irq(qts, 0)); 136*a0c325c4SInès Varhol } 137*a0c325c4SInès Varhol 138*a0c325c4SInès Varhol /* Pulse one more bit in the bank, check that we get a one */ 139*a0c325c4SInès Varhol GPIO_PULSE(DCK); 140*a0c325c4SInès Varhol g_assert(qtest_get_irq(qts, 0)); 141*a0c325c4SInès Varhol 142*a0c325c4SInès Varhol qtest_quit(qts); 143*a0c325c4SInès Varhol } 144*a0c325c4SInès Varhol 145*a0c325c4SInès Varhol static void test_dm163_gpio_connection(void) 146*a0c325c4SInès Varhol { 147*a0c325c4SInès Varhol QTestState *qts = qtest_init("-M b-l475e-iot01a"); 148*a0c325c4SInès Varhol qtest_irq_intercept_in(qts, DEVICE_NAME); 149*a0c325c4SInès Varhol 150*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, SIN)); 151*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, DCK)); 152*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, RST_B)); 153*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, LAT_B)); 154*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, SELBK)); 155*a0c325c4SInès Varhol 156*a0c325c4SInès Varhol rise_gpio_pin_dck(qts); 157*a0c325c4SInès Varhol g_assert_true(qtest_get_irq(qts, DCK)); 158*a0c325c4SInès Varhol lower_gpio_pin_dck(qts); 159*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, DCK)); 160*a0c325c4SInès Varhol 161*a0c325c4SInès Varhol rise_gpio_pin_lat_b(qts); 162*a0c325c4SInès Varhol g_assert_true(qtest_get_irq(qts, LAT_B)); 163*a0c325c4SInès Varhol lower_gpio_pin_lat_b(qts); 164*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, LAT_B)); 165*a0c325c4SInès Varhol 166*a0c325c4SInès Varhol rise_gpio_pin_selbk(qts); 167*a0c325c4SInès Varhol g_assert_true(qtest_get_irq(qts, SELBK)); 168*a0c325c4SInès Varhol lower_gpio_pin_selbk(qts); 169*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, SELBK)); 170*a0c325c4SInès Varhol 171*a0c325c4SInès Varhol rise_gpio_pin_rst_b(qts); 172*a0c325c4SInès Varhol g_assert_true(qtest_get_irq(qts, RST_B)); 173*a0c325c4SInès Varhol lower_gpio_pin_rst_b(qts); 174*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, RST_B)); 175*a0c325c4SInès Varhol 176*a0c325c4SInès Varhol rise_gpio_pin_sin(qts); 177*a0c325c4SInès Varhol g_assert_true(qtest_get_irq(qts, SIN)); 178*a0c325c4SInès Varhol lower_gpio_pin_sin(qts); 179*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, SIN)); 180*a0c325c4SInès Varhol 181*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, DCK)); 182*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, LAT_B)); 183*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, SELBK)); 184*a0c325c4SInès Varhol g_assert_false(qtest_get_irq(qts, RST_B)); 185*a0c325c4SInès Varhol } 186*a0c325c4SInès Varhol 187*a0c325c4SInès Varhol int main(int argc, char **argv) 188*a0c325c4SInès Varhol { 189*a0c325c4SInès Varhol g_test_init(&argc, &argv, NULL); 190*a0c325c4SInès Varhol qtest_add_data_func("/dm163/bank0", (void *)0, test_dm163_bank); 191*a0c325c4SInès Varhol qtest_add_data_func("/dm163/bank1", (void *)1, test_dm163_bank); 192*a0c325c4SInès Varhol qtest_add_func("/dm163/gpio_connection", test_dm163_gpio_connection); 193*a0c325c4SInès Varhol return g_test_run(); 194*a0c325c4SInès Varhol } 195