Lines Matching +full:reset +full:- +full:gpio

4  * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
5 * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
8 * See the COPYING file in the top-level directory.
12 #include "libqtest-single.h"
84 #define GPIO_ADDR_MASK (~(GPIO_SIZE - 1))
94 static uint32_t gpio_readl(unsigned int gpio, unsigned int offset) in gpio_readl() argument
96 return readl(gpio + offset); in gpio_readl()
99 static void gpio_writel(unsigned int gpio, unsigned int offset, uint32_t value) in gpio_writel() argument
101 writel(gpio + offset, value); in gpio_writel()
104 static void gpio_set_bit(unsigned int gpio, unsigned int reg, in gpio_set_bit() argument
108 gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << pin); in gpio_set_bit()
111 static void gpio_set_2bits(unsigned int gpio, unsigned int reg, in gpio_set_2bits() argument
116 gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << offset); in gpio_set_2bits()
121 return (gpio_addr - GPIO_BASE_ADDR) / GPIO_SIZE; in get_gpio_id()
124 static void gpio_set_irq(unsigned int gpio, int num, int level) in gpio_set_irq() argument
126 g_autofree char *name = g_strdup_printf("/machine/soc/gpio%c", in gpio_set_irq()
127 get_gpio_id(gpio) + 'a'); in gpio_set_irq()
131 static void disconnect_all_pins(unsigned int gpio) in disconnect_all_pins() argument
133 g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c", in disconnect_all_pins()
134 get_gpio_id(gpio) + 'a'); in disconnect_all_pins()
137 r = qtest_qmp(global_qtest, "{ 'execute': 'qom-set', 'arguments': " in disconnect_all_pins()
138 "{ 'path': %s, 'property': 'disconnected-pins', 'value': %d } }", in disconnect_all_pins()
144 static uint32_t get_disconnected_pins(unsigned int gpio) in get_disconnected_pins() argument
146 g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c", in get_disconnected_pins()
147 get_gpio_id(gpio) + 'a'); in get_disconnected_pins()
151 r = qtest_qmp(global_qtest, "{ 'execute': 'qom-get', 'arguments':" in get_disconnected_pins()
152 " { 'path': %s, 'property': 'disconnected-pins'} }", path); in get_disconnected_pins()
159 static uint32_t reset(uint32_t gpio, unsigned int offset) in reset() function
163 return moder_reset[get_gpio_id(gpio)]; in reset()
165 return pupdr_reset[get_gpio_id(gpio)]; in reset()
167 return idr_reset[get_gpio_id(gpio)]; in reset()
176 * after reset are correct, and that the value in IDR is in test_idr_reset_value()
178 * Since AF and analog modes aren't implemented, IDR reset in test_idr_reset_value()
181 * Register IDR contains the actual values of all GPIO pins. in test_idr_reset_value()
183 * (intput/output/analog : register MODER, push-pull/open-drain : in test_idr_reset_value()
184 * register OTYPER, pull-up/pull-down/none : register PUPDR) in test_idr_reset_value()
218 g_assert_cmphex(moder, ==, reset(GPIO_A, MODER)); in test_idr_reset_value()
219 g_assert_cmphex(odr, ==, reset(GPIO_A, ODR)); in test_idr_reset_value()
220 g_assert_cmphex(otyper, ==, reset(GPIO_A, OTYPER)); in test_idr_reset_value()
221 /* 15: pull-up, 14: pull-down, 13: pull-up, 12: neither ... */ in test_idr_reset_value()
222 g_assert_cmphex(pupdr, ==, reset(GPIO_A, PUPDR)); in test_idr_reset_value()
223 /* 15 : 1, 14: 0, 13: 1, 12 : reset value ... */ in test_idr_reset_value()
224 g_assert_cmphex(idr, ==, reset(GPIO_A, IDR)); in test_idr_reset_value()
233 g_assert_cmphex(moder, ==, reset(GPIO_B, MODER)); in test_idr_reset_value()
234 g_assert_cmphex(odr, ==, reset(GPIO_B, ODR)); in test_idr_reset_value()
235 g_assert_cmphex(otyper, ==, reset(GPIO_B, OTYPER)); in test_idr_reset_value()
236 /* ... 5: neither, 4: pull-up, 3: neither ... */ in test_idr_reset_value()
237 g_assert_cmphex(pupdr, ==, reset(GPIO_B, PUPDR)); in test_idr_reset_value()
238 /* ... 5 : reset value, 4 : 1, 3 : reset value ... */ in test_idr_reset_value()
239 g_assert_cmphex(idr, ==, reset(GPIO_B, IDR)); in test_idr_reset_value()
247 g_assert_cmphex(moder, ==, reset(GPIO_C, MODER)); in test_idr_reset_value()
248 g_assert_cmphex(odr, ==, reset(GPIO_C, ODR)); in test_idr_reset_value()
249 g_assert_cmphex(otyper, ==, reset(GPIO_C, OTYPER)); in test_idr_reset_value()
250 /* no pull-up or pull-down */ in test_idr_reset_value()
251 g_assert_cmphex(pupdr, ==, reset(GPIO_C, PUPDR)); in test_idr_reset_value()
252 /* reset value */ in test_idr_reset_value()
253 g_assert_cmphex(idr, ==, reset(GPIO_C, IDR)); in test_idr_reset_value()
261 g_assert_cmphex(moder, ==, reset(GPIO_H, MODER)); in test_idr_reset_value()
262 g_assert_cmphex(odr, ==, reset(GPIO_H, ODR)); in test_idr_reset_value()
263 g_assert_cmphex(otyper, ==, reset(GPIO_H, OTYPER)); in test_idr_reset_value()
264 /* no pull-up or pull-down */ in test_idr_reset_value()
265 g_assert_cmphex(pupdr, ==, reset(GPIO_H, PUPDR)); in test_idr_reset_value()
266 /* reset value */ in test_idr_reset_value()
267 g_assert_cmphex(idr, ==, reset(GPIO_H, IDR)); in test_idr_reset_value()
274 * GPIO line high : it should set the right bit in IDR in test_gpio_output_mode()
280 uint32_t gpio = test_gpio_addr(data); in test_gpio_output_mode() local
281 unsigned int gpio_id = get_gpio_id(gpio); in test_gpio_output_mode()
286 gpio_set_bit(gpio, ODR, pin, 1); in test_gpio_output_mode()
287 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); in test_gpio_output_mode()
291 gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT); in test_gpio_output_mode()
292 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin)); in test_gpio_output_mode()
295 /* Reset the bit in ODR and check the pin is low */ in test_gpio_output_mode()
296 gpio_set_bit(gpio, ODR, pin, 0); in test_gpio_output_mode()
297 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); in test_gpio_output_mode()
301 gpio_writel(gpio, ODR, reset(gpio, ODR)); in test_gpio_output_mode()
302 gpio_writel(gpio, MODER, reset(gpio, MODER)); in test_gpio_output_mode()
303 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); in test_gpio_output_mode()
311 * corresponding GPIO line high/low : it should set the in test_gpio_input_mode()
315 uint32_t gpio = test_gpio_addr(data); in test_gpio_input_mode() local
316 unsigned int gpio_id = get_gpio_id(gpio); in test_gpio_input_mode()
321 gpio_set_2bits(gpio, MODER, pin, MODER_INPUT); in test_gpio_input_mode()
322 gpio_set_irq(gpio, pin, 1); in test_gpio_input_mode()
323 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin)); in test_gpio_input_mode()
327 gpio_set_irq(gpio, pin, 0); in test_gpio_input_mode()
328 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); in test_gpio_input_mode()
332 gpio_writel(gpio, MODER, reset(gpio, MODER)); in test_gpio_input_mode()
333 disconnect_all_pins(gpio); in test_gpio_input_mode()
334 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); in test_gpio_input_mode()
340 * Test that a floating pin with pull-up sets the pin in test_pull_up_pull_down()
341 * high and vice-versa. in test_pull_up_pull_down()
344 uint32_t gpio = test_gpio_addr(data); in test_pull_up_pull_down() local
345 unsigned int gpio_id = get_gpio_id(gpio); in test_pull_up_pull_down()
349 /* Configure a line as input with pull-up, check the line is set high */ in test_pull_up_pull_down()
350 gpio_set_2bits(gpio, MODER, pin, MODER_INPUT); in test_pull_up_pull_down()
351 gpio_set_2bits(gpio, PUPDR, pin, PUPDR_PULLUP); in test_pull_up_pull_down()
352 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin)); in test_pull_up_pull_down()
355 /* Configure the line with pull-down, check the line is low */ in test_pull_up_pull_down()
356 gpio_set_2bits(gpio, PUPDR, pin, PUPDR_PULLDOWN); in test_pull_up_pull_down()
357 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); in test_pull_up_pull_down()
361 gpio_writel(gpio, MODER, reset(gpio, MODER)); in test_pull_up_pull_down()
362 gpio_writel(gpio, PUPDR, reset(gpio, PUPDR)); in test_pull_up_pull_down()
363 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); in test_pull_up_pull_down()
369 * Test that configuring a line in push-pull output mode in test_push_pull()
370 * disconnects the pin, that the pin can't be set or reset in test_push_pull()
374 uint32_t gpio = test_gpio_addr(data); in test_push_pull() local
375 uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio); in test_push_pull()
379 /* Setting a line high externally, configuring it in push-pull output */ in test_push_pull()
381 gpio_set_irq(gpio, pin, 1); in test_push_pull()
382 gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT); in test_push_pull()
383 g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF); in test_push_pull()
384 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); in test_push_pull()
386 /* Setting a line low externally, configuring it in push-pull output */ in test_push_pull()
392 g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR) | (1 << pin)); in test_push_pull()
394 /* Trying to set a push-pull output pin, checking it doesn't work */ in test_push_pull()
395 gpio_set_irq(gpio, pin, 1); in test_push_pull()
396 g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF); in test_push_pull()
397 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); in test_push_pull()
399 /* Trying to reset a push-pull output pin, checking it doesn't work */ in test_push_pull()
402 g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR) | (1 << pin)); in test_push_pull()
405 gpio_writel(gpio, MODER, reset(gpio, MODER)); in test_push_pull()
406 gpio_writel(gpio2, ODR, reset(gpio2, ODR)); in test_push_pull()
407 gpio_writel(gpio2, MODER, reset(gpio2, MODER)); in test_push_pull()
413 * Test that configuring a line in open-drain output mode in test_open_drain()
415 * can't be set high externally while configured in open-drain. in test_open_drain()
418 * and it can be set low externally when in open-drain mode. in test_open_drain()
421 uint32_t gpio = test_gpio_addr(data); in test_open_drain() local
422 uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio); in test_open_drain()
426 /* Setting a line high externally, configuring it in open-drain output */ in test_open_drain()
428 gpio_set_irq(gpio, pin, 1); in test_open_drain()
429 gpio_set_bit(gpio, OTYPER, pin, OTYPER_OPEN_DRAIN); in test_open_drain()
430 gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT); in test_open_drain()
431 g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF); in test_open_drain()
432 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); in test_open_drain()
434 /* Setting a line low externally, configuring it in open-drain output */ in test_open_drain()
442 reset(gpio2, IDR) & ~(1 << pin)); in test_open_drain()
444 /* Trying to set a open-drain output pin, checking it doesn't work */ in test_open_drain()
445 gpio_set_irq(gpio, pin, 1); in test_open_drain()
446 g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF); in test_open_drain()
447 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); in test_open_drain()
449 /* Trying to reset a open-drain output pin, checking it works */ in test_open_drain()
450 gpio_set_bit(gpio, ODR, pin, 1); in test_open_drain()
451 gpio_set_irq(gpio, pin, 0); in test_open_drain()
454 reset(gpio2, IDR) & ~(1 << pin)); in test_open_drain()
458 gpio_writel(gpio2, OTYPER, reset(gpio2, OTYPER)); in test_open_drain()
459 gpio_writel(gpio2, ODR, reset(gpio2, ODR)); in test_open_drain()
460 gpio_writel(gpio2, MODER, reset(gpio2, MODER)); in test_open_drain()
461 g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR)); in test_open_drain()
462 disconnect_all_pins(gpio); in test_open_drain()
463 gpio_writel(gpio, OTYPER, reset(gpio, OTYPER)); in test_open_drain()
464 gpio_writel(gpio, ODR, reset(gpio, ODR)); in test_open_drain()
465 gpio_writel(gpio, MODER, reset(gpio, MODER)); in test_open_drain()
466 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); in test_open_drain()
477 uint32_t gpio = test_gpio_addr(data); in test_bsrr_brr() local
479 gpio_writel(gpio, BSRR, (1 << pin)); in test_bsrr_brr()
480 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin)); in test_bsrr_brr()
482 gpio_writel(gpio, BSRR, (1 << (pin + NUM_GPIO_PINS))); in test_bsrr_brr()
483 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR)); in test_bsrr_brr()
485 gpio_writel(gpio, BSRR, (1 << pin)); in test_bsrr_brr()
486 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin)); in test_bsrr_brr()
488 gpio_writel(gpio, BRR, (1 << pin)); in test_bsrr_brr()
489 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR)); in test_bsrr_brr()
492 gpio_writel(gpio, BSRR, (1 << pin) | (1 << (pin + NUM_GPIO_PINS))); in test_bsrr_brr()
493 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin)); in test_bsrr_brr()
495 gpio_writel(gpio, BRR, (1 << pin)); in test_bsrr_brr()
496 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR)); in test_bsrr_brr()
498 gpio_writel(gpio, ODR, reset(gpio, ODR)); in test_bsrr_brr()
504 * For each GPIO, enable its clock in RCC in test_clock_enable()
509 for (uint32_t gpio = GPIO_A; gpio <= GPIO_H; gpio += GPIO_B - GPIO_A) { in test_clock_enable() local
510 gpio_id = get_gpio_id(gpio); in test_clock_enable()
511 g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c/clk", in test_clock_enable()
514 /* Enable the gpio clock */ in test_clock_enable()
527 qtest_add_func("stm32l4x5/gpio/test_idr_reset_value", in main()
530 * The inputs for the tests (gpio and pin) can be changed, in main()
531 * but the tests don't work for pins that are high at reset in main()
536 qtest_add_data_func("stm32l4x5/gpio/test_gpioc5_output_mode", in main()
539 qtest_add_data_func("stm32l4x5/gpio/test_gpioh3_output_mode", in main()
542 qtest_add_data_func("stm32l4x5/gpio/test_gpio_input_mode1", in main()
545 qtest_add_data_func("stm32l4x5/gpio/test_gpio_input_mode2", in main()
548 qtest_add_data_func("stm32l4x5/gpio/test_gpio_pull_up_pull_down1", in main()
551 qtest_add_data_func("stm32l4x5/gpio/test_gpio_pull_up_pull_down2", in main()
554 qtest_add_data_func("stm32l4x5/gpio/test_gpio_push_pull1", in main()
557 qtest_add_data_func("stm32l4x5/gpio/test_gpio_push_pull2", in main()
560 qtest_add_data_func("stm32l4x5/gpio/test_gpio_open_drain1", in main()
563 qtest_add_data_func("stm32l4x5/gpio/test_gpio_open_drain2", in main()
566 qtest_add_data_func("stm32l4x5/gpio/test_bsrr_brr1", in main()
569 qtest_add_data_func("stm32l4x5/gpio/test_bsrr_brr2", in main()
572 qtest_add_func("stm32l4x5/gpio/test_clock_enable", in main()
575 qtest_start("-machine b-l475e-iot01a"); in main()