134fdd734SJamin Lin /* 234fdd734SJamin Lin * QTest testcase for the ASPEED AST2700 GPIO Controller. 334fdd734SJamin Lin * 434fdd734SJamin Lin * SPDX-License-Identifier: GPL-2.0-or-later 534fdd734SJamin Lin * Copyright (C) 2024 ASPEED Technology Inc. 634fdd734SJamin Lin */ 734fdd734SJamin Lin 834fdd734SJamin Lin #include "qemu/osdep.h" 934fdd734SJamin Lin #include "qemu/bitops.h" 1034fdd734SJamin Lin #include "qemu/timer.h" 11*407bc4bfSDaniel P. Berrangé #include "qobject/qdict.h" 1234fdd734SJamin Lin #include "libqtest-single.h" 1334fdd734SJamin Lin 1434fdd734SJamin Lin #define AST2700_GPIO_BASE 0x14C0B000 1534fdd734SJamin Lin #define GPIOA0_CONTROL 0x180 1634fdd734SJamin Lin 1734fdd734SJamin Lin static void test_output_pins(const char *machine, const uint32_t base) 1834fdd734SJamin Lin { 1934fdd734SJamin Lin QTestState *s = qtest_init(machine); 2034fdd734SJamin Lin uint32_t offset = 0; 2134fdd734SJamin Lin uint32_t value = 0; 2234fdd734SJamin Lin uint32_t pin = 0; 2334fdd734SJamin Lin 2434fdd734SJamin Lin for (char c = 'A'; c <= 'D'; c++) { 2534fdd734SJamin Lin for (int i = 0; i < 8; i++) { 2634fdd734SJamin Lin offset = base + (pin * 4); 2734fdd734SJamin Lin 2834fdd734SJamin Lin /* output direction and output hi */ 2934fdd734SJamin Lin qtest_writel(s, offset, 0x00000003); 3034fdd734SJamin Lin value = qtest_readl(s, offset); 3134fdd734SJamin Lin g_assert_cmphex(value, ==, 0x00000003); 3234fdd734SJamin Lin 3334fdd734SJamin Lin /* output direction and output low */ 3434fdd734SJamin Lin qtest_writel(s, offset, 0x00000002); 3534fdd734SJamin Lin value = qtest_readl(s, offset); 3634fdd734SJamin Lin g_assert_cmphex(value, ==, 0x00000002); 3734fdd734SJamin Lin pin++; 3834fdd734SJamin Lin } 3934fdd734SJamin Lin } 4034fdd734SJamin Lin 4134fdd734SJamin Lin qtest_quit(s); 4234fdd734SJamin Lin } 4334fdd734SJamin Lin 4434fdd734SJamin Lin static void test_input_pins(const char *machine, const uint32_t base) 4534fdd734SJamin Lin { 4634fdd734SJamin Lin QTestState *s = qtest_init(machine); 4734fdd734SJamin Lin char name[16]; 4834fdd734SJamin Lin uint32_t offset = 0; 4934fdd734SJamin Lin uint32_t value = 0; 5034fdd734SJamin Lin uint32_t pin = 0; 5134fdd734SJamin Lin 5234fdd734SJamin Lin for (char c = 'A'; c <= 'D'; c++) { 5334fdd734SJamin Lin for (int i = 0; i < 8; i++) { 5434fdd734SJamin Lin sprintf(name, "gpio%c%d", c, i); 5534fdd734SJamin Lin offset = base + (pin * 4); 5634fdd734SJamin Lin /* input direction */ 5734fdd734SJamin Lin qtest_writel(s, offset, 0); 5834fdd734SJamin Lin 5934fdd734SJamin Lin /* set input */ 6034fdd734SJamin Lin qtest_qom_set_bool(s, "/machine/soc/gpio", name, true); 6134fdd734SJamin Lin value = qtest_readl(s, offset); 6234fdd734SJamin Lin g_assert_cmphex(value, ==, 0x00002000); 6334fdd734SJamin Lin 6434fdd734SJamin Lin /* clear input */ 6534fdd734SJamin Lin qtest_qom_set_bool(s, "/machine/soc/gpio", name, false); 6634fdd734SJamin Lin value = qtest_readl(s, offset); 6734fdd734SJamin Lin g_assert_cmphex(value, ==, 0); 6834fdd734SJamin Lin pin++; 6934fdd734SJamin Lin } 7034fdd734SJamin Lin } 7134fdd734SJamin Lin 7234fdd734SJamin Lin qtest_quit(s); 7334fdd734SJamin Lin } 7434fdd734SJamin Lin 7534fdd734SJamin Lin static void test_2700_input_pins(void) 7634fdd734SJamin Lin { 7734fdd734SJamin Lin test_input_pins("-machine ast2700-evb", 7834fdd734SJamin Lin AST2700_GPIO_BASE + GPIOA0_CONTROL); 7934fdd734SJamin Lin } 8034fdd734SJamin Lin 8134fdd734SJamin Lin static void test_2700_output_pins(void) 8234fdd734SJamin Lin { 8334fdd734SJamin Lin test_output_pins("-machine ast2700-evb", 8434fdd734SJamin Lin AST2700_GPIO_BASE + GPIOA0_CONTROL); 8534fdd734SJamin Lin } 8634fdd734SJamin Lin 8734fdd734SJamin Lin int main(int argc, char **argv) 8834fdd734SJamin Lin { 8934fdd734SJamin Lin g_test_init(&argc, &argv, NULL); 9034fdd734SJamin Lin 9134fdd734SJamin Lin qtest_add_func("/ast2700/gpio/input_pins", test_2700_input_pins); 9234fdd734SJamin Lin qtest_add_func("/ast2700/gpio/output_pins", test_2700_output_pins); 9334fdd734SJamin Lin 9434fdd734SJamin Lin return g_test_run(); 9534fdd734SJamin Lin } 96