This is an automated email from Gerrit. "Steve Marple <stevemar...@googlemail.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/6984
-- gerrit commit 9ad4a92d1276a912f4533581b34345f89f1e139e Author: Steve Marple <stevemar...@googlemail.com> Date: Tue May 17 21:51:17 2022 +0100 RFC: drivers/am335xgpio: Migrate to adapter gpio commands Use the new "adapter gpio" commands to configure the GPIOs used by the am335xgpio driver. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Publishing early with fewer changes for easier review and rework. Only the LED GPIO has been migrated. TODO * Migrate all GPIOs to use the "adapter gpio" commands. * Rename x_NEW() functions to x() when all GPIOS have been migrated. * Add documentation when interface is stable. QUESTIONS * Should all GPIOs have a drive mode? The "reset_config" allows it to be defined for SRST and TRST. How would conflicts between "reset_config srst_open_drain" and "adapter gpio srst -open-drain" be resolved? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Change-Id: I7c63c0e4763657ea51790c43fc40d32b7c3580bb Signed-off-by: Steve Marple <stevemar...@googlemail.com> diff --git a/src/jtag/drivers/am335xgpio.c b/src/jtag/drivers/am335xgpio.c index e04c44c8e4..5f4808cf86 100644 --- a/src/jtag/drivers/am335xgpio.c +++ b/src/jtag/drivers/am335xgpio.c @@ -21,6 +21,7 @@ #include "config.h" #endif +#include <jtag/adapter.h> #include <jtag/interface.h> #include <transport/transport.h> #include "bitbang.h" @@ -31,6 +32,7 @@ * GPIO register base addresses. Values taken from "AM335x and AMIC110 Sitara * Processors Technical Reference Manual", Chapter 2 Memory Map. */ +#define AM335XGPIO_NUM_GPIO_PER_PORT 32 #define AM335XGPIO_NUM_GPIO_PORTS 4 #define AM335XGPIO_GPIO0_HW_ADDR 0x44E07000 #define AM335XGPIO_GPIO1_HW_ADDR 0x4804C000 @@ -51,21 +53,21 @@ * that module. GPIOs 0 to 31 map to GPIO0, 32 to 63 to GPIO1 etc. This scheme * matches that used by Linux on the BeagleBone. */ -#define AM335XGPIO_PORT_NUM(gpio_num) ((gpio_num) / 32) -#define AM335XGPIO_BIT_NUM(gpio_num) ((gpio_num) % 32) -#define AM335XGPIO_BIT_MASK(gpio_num) BIT(AM335XGPIO_BIT_NUM(gpio_num)) +#define AM335XGPIO_PORT_NUM(gpio_num) ((gpio_num) / 32) /* TODO: remove when all GPIOs ported to adapter commands */ +#define AM335XGPIO_BIT_NUM(gpio_num) ((gpio_num) % 32) /* TODO: remove when all GPIOs ported to adapter commands */ +#define AM335XGPIO_BIT_MASK(gpio_num) BIT(AM335XGPIO_BIT_NUM(gpio_num)) /* TODO: remove when ported to adapter cmds */ -#define AM335XGPIO_READ_REG(gpio_num, offset) \ - (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset))) +#define AM335XGPIO_READ_REG(chip_num, offset) \ + (*(am335xgpio_gpio_port_mmap_addr[chip_num] + (offset))) -#define AM335XGPIO_WRITE_REG(gpio_num, offset, value) \ - (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset)) = (value)) +#define AM335XGPIO_WRITE_REG(chip_num, offset, value) \ + (*(am335xgpio_gpio_port_mmap_addr[chip_num] + (offset)) = (value)) -#define AM335XGPIO_SET_REG_BITS(gpio_num, offset, bit_mask) \ - (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset)) |= (bit_mask)) +#define AM335XGPIO_SET_REG_BITS(chip_num, offset, bit_mask) \ + (*(am335xgpio_gpio_port_mmap_addr[chip_num] + (offset)) |= (bit_mask)) -#define AM335XGPIO_CLEAR_REG_BITS(gpio_num, offset, bit_mask) \ - (*(am335xgpio_gpio_port_mmap_addr[AM335XGPIO_PORT_NUM(gpio_num)] + (offset)) &= ~(bit_mask)) +#define AM335XGPIO_CLEAR_REG_BITS(chip_num, offset, bit_mask) \ + (*(am335xgpio_gpio_port_mmap_addr[chip_num] + (offset)) &= ~(bit_mask)) enum amx335gpio_gpio_mode { AM335XGPIO_GPIO_MODE_INPUT, @@ -105,43 +107,67 @@ static int swdio_gpio = -1; static enum amx335gpio_gpio_mode swdio_gpio_mode; static int swdio_dir_gpio = -1; static enum amx335gpio_gpio_mode swdio_dir_gpio_mode; -static int led_gpio = -1; -static enum amx335gpio_gpio_mode led_gpio_mode = -1; +static enum amx335gpio_gpio_mode led_gpio_mode; static bool swdio_dir_is_active_high = true; /* Active state means output */ -static bool led_is_active_high = true; /* Transition delay coefficients */ static int speed_coeff = 600000; static int speed_offset = 575; static unsigned int jtag_delay; +static void set_gpio_value_NEW(const struct adapter_gpio_config *gpio_config, int value); + static int is_gpio_valid(int gpio_num) { return gpio_num >= 0 && gpio_num < (32 * AM335XGPIO_NUM_GPIO_PORTS); } +static bool is_gpio_config_valid(const struct adapter_gpio_config *gpio_config) +{ + return gpio_config->chip_num >= 0 + && gpio_config->chip_num < AM335XGPIO_NUM_GPIO_PORTS + && gpio_config->gpio_num >= 0 + && gpio_config->gpio_num < AM335XGPIO_NUM_GPIO_PER_PORT; +} + static int get_gpio_value(int gpio_num) { unsigned int shift = AM335XGPIO_BIT_NUM(gpio_num); - return (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_DATAIN_OFFSET) >> shift) & 1; + return (AM335XGPIO_READ_REG(AM335XGPIO_PORT_NUM(gpio_num), AM335XGPIO_GPIO_DATAIN_OFFSET) >> shift) & 1; } static void set_gpio_value(int gpio_num, int value) { if (value) - AM335XGPIO_WRITE_REG(gpio_num, AM335XGPIO_GPIO_SETDATAOUT_OFFSET, AM335XGPIO_BIT_MASK(gpio_num)); + AM335XGPIO_WRITE_REG(AM335XGPIO_PORT_NUM(gpio_num), AM335XGPIO_GPIO_SETDATAOUT_OFFSET, + AM335XGPIO_BIT_MASK(gpio_num)); else - AM335XGPIO_WRITE_REG(gpio_num, AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, AM335XGPIO_BIT_MASK(gpio_num)); + AM335XGPIO_WRITE_REG(AM335XGPIO_PORT_NUM(gpio_num), AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, + AM335XGPIO_BIT_MASK(gpio_num)); } static enum amx335gpio_gpio_mode get_gpio_mode(int gpio_num) { - if (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_OE_OFFSET) & AM335XGPIO_BIT_MASK(gpio_num)) { + if (AM335XGPIO_READ_REG(AM335XGPIO_PORT_NUM(gpio_num), AM335XGPIO_GPIO_OE_OFFSET) & AM335XGPIO_BIT_MASK(gpio_num)) { + return AM335XGPIO_GPIO_MODE_INPUT; + } else { + /* Return output level too so that pin mode can be fully restored */ + if (AM335XGPIO_READ_REG(AM335XGPIO_PORT_NUM(gpio_num), + AM335XGPIO_GPIO_DATAOUT_OFFSET) & AM335XGPIO_BIT_MASK(gpio_num)) + return AM335XGPIO_GPIO_MODE_OUTPUT_HIGH; + else + return AM335XGPIO_GPIO_MODE_OUTPUT_LOW; + } +} + +static enum amx335gpio_gpio_mode get_gpio_mode_NEW(const struct adapter_gpio_config *gpio_config) +{ + if (AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_OE_OFFSET) & BIT(gpio_config->gpio_num)) { return AM335XGPIO_GPIO_MODE_INPUT; } else { /* Return output level too so that pin mode can be fully restored */ - if (AM335XGPIO_READ_REG(gpio_num, AM335XGPIO_GPIO_DATAOUT_OFFSET) & AM335XGPIO_BIT_MASK(gpio_num)) + if (AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_DATAOUT_OFFSET) & BIT(gpio_config->gpio_num)) return AM335XGPIO_GPIO_MODE_OUTPUT_HIGH; else return AM335XGPIO_GPIO_MODE_OUTPUT_LOW; @@ -151,7 +177,8 @@ static enum amx335gpio_gpio_mode get_gpio_mode(int gpio_num) static void set_gpio_mode(int gpio_num, enum amx335gpio_gpio_mode gpio_mode) { if (gpio_mode == AM335XGPIO_GPIO_MODE_INPUT) { - AM335XGPIO_SET_REG_BITS(gpio_num, AM335XGPIO_GPIO_OE_OFFSET, AM335XGPIO_BIT_MASK(gpio_num)); + AM335XGPIO_SET_REG_BITS(AM335XGPIO_PORT_NUM(gpio_num), + AM335XGPIO_GPIO_OE_OFFSET, AM335XGPIO_BIT_MASK(gpio_num)); return; } @@ -163,7 +190,27 @@ static void set_gpio_mode(int gpio_num, enum amx335gpio_gpio_mode gpio_mode) if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT || gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_LOW || gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_HIGH) { - AM335XGPIO_CLEAR_REG_BITS(gpio_num, AM335XGPIO_GPIO_OE_OFFSET, AM335XGPIO_BIT_MASK(gpio_num)); + AM335XGPIO_CLEAR_REG_BITS(AM335XGPIO_PORT_NUM(gpio_num), + AM335XGPIO_GPIO_OE_OFFSET, AM335XGPIO_BIT_MASK(gpio_num)); + } +} + +static void set_gpio_mode_NEW(const struct adapter_gpio_config *gpio_config, enum amx335gpio_gpio_mode gpio_mode) +{ + if (gpio_mode == AM335XGPIO_GPIO_MODE_INPUT) { + AM335XGPIO_SET_REG_BITS(gpio_config->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT(gpio_config->gpio_num)); + return; + } + + if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_LOW) + set_gpio_value_NEW(gpio_config, 0); + if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_HIGH) + set_gpio_value_NEW(gpio_config, 1); + + if (gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT || + gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_LOW || + gpio_mode == AM335XGPIO_GPIO_MODE_OUTPUT_HIGH) { + AM335XGPIO_CLEAR_REG_BITS(gpio_config->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT(gpio_config->gpio_num)); } } @@ -183,6 +230,35 @@ static const char *get_gpio_mode_name(enum amx335gpio_gpio_mode gpio_mode) } } +static void set_gpio_value_NEW(const struct adapter_gpio_config *gpio_config, int value) +{ + value = value ^ gpio_config->active_low; + switch (gpio_config->drive) { + case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL: + if (value) + AM335XGPIO_WRITE_REG(gpio_config->chip_num, AM335XGPIO_GPIO_SETDATAOUT_OFFSET, + AM335XGPIO_BIT_MASK(gpio_config->gpio_num)); + else + AM335XGPIO_WRITE_REG(gpio_config->chip_num, AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, + AM335XGPIO_BIT_MASK(gpio_config->gpio_num)); + break; + case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN: + if (value) + set_gpio_mode_NEW(gpio_config, AM335XGPIO_GPIO_MODE_INPUT); + else + AM335XGPIO_WRITE_REG(gpio_config->chip_num, AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, + AM335XGPIO_BIT_MASK(gpio_config->gpio_num)); + break; + case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE: + if (value) + AM335XGPIO_WRITE_REG(gpio_config->chip_num, AM335XGPIO_GPIO_SETDATAOUT_OFFSET, + AM335XGPIO_BIT_MASK(gpio_config->gpio_num)); + else + set_gpio_mode_NEW(gpio_config, AM335XGPIO_GPIO_MODE_INPUT); + break; + } +} + static bb_value_t am335xgpio_read(void) { return get_gpio_value(tdo_gpio) ? BB_HIGH : BB_LOW; @@ -255,8 +331,9 @@ static int am335xgpio_swdio_read(void) static int am335xgpio_blink(int on) { - if (is_gpio_valid(led_gpio)) - set_gpio_value(led_gpio, (!on ^ led_is_active_high) ? 1 : 0); + const struct adapter_gpio_config *led_gpio_config = adapter_get_gpio_config(ADAPTER_GPIO_IDX_LED); + if (is_gpio_config_valid(led_gpio_config)) + set_gpio_value_NEW(led_gpio_config, (on ^ led_gpio_config->active_low) ? 1 : 0); return ERROR_OK; } @@ -414,24 +491,6 @@ COMMAND_HANDLER(am335xgpio_handle_swd_dir_output_state) return ERROR_OK; } -COMMAND_HANDLER(am335xgpio_handle_gpionum_led) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], led_gpio); - - command_print(CMD, "AM335x GPIO config: led = %d", led_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(am335xgpio_handle_led_on_state) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_BOOL(CMD_ARGV[0], led_is_active_high, "high", "low"); - - command_print(CMD, "AM335x GPIO config: led_on_state = %s", led_is_active_high ? "high" : "low"); - return ERROR_OK; -} - COMMAND_HANDLER(am335xgpio_handle_speed_coeffs) { if (CMD_ARGC == 2) { @@ -529,20 +588,6 @@ static const struct command_registration am335xgpio_subcommand_handlers[] = { .help = "gpio number for trst.", .usage = "[trst]", }, - { - .name = "led_num", - .handler = am335xgpio_handle_gpionum_led, - .mode = COMMAND_CONFIG, - .help = "gpio number for led.", - .usage = "[led]", - }, - { - .name = "led_on_state", - .handler = am335xgpio_handle_led_on_state, - .mode = COMMAND_CONFIG, - .help = "required state for led pin to turn on LED.", - .usage = "['off'|'on']", - }, { .name = "speed_coeffs", .handler = am335xgpio_handle_speed_coeffs, @@ -595,6 +640,7 @@ static bool am335xgpio_swd_mode_possible(void) static int am335xgpio_init(void) { + const struct adapter_gpio_config *led_gpio_config = adapter_get_gpio_config(ADAPTER_GPIO_IDX_LED); bitbang_interface = &am335xgpio_bitbang; LOG_INFO("AM335x GPIO JTAG/SWD bitbang driver"); @@ -677,11 +723,13 @@ static int am335xgpio_init(void) LOG_DEBUG("saved GPIO mode for srst (GPIO #%d): %s", srst_gpio, get_gpio_mode_name(srst_gpio_mode)); } - if (is_gpio_valid(led_gpio)) { - led_gpio_mode = get_gpio_mode(led_gpio); - LOG_DEBUG("saved GPIO mode for led (GPIO #%d): %s", led_gpio, get_gpio_mode_name(led_gpio_mode)); - set_gpio_mode(led_gpio, - led_is_active_high ? AM335XGPIO_GPIO_MODE_OUTPUT_LOW : AM335XGPIO_GPIO_MODE_OUTPUT_HIGH); + if (is_gpio_config_valid(led_gpio_config)) { + led_gpio_mode = get_gpio_mode_NEW(led_gpio_config); + LOG_DEBUG("saved GPIO mode for led (GPIO %d %d): %s", + led_gpio_config->chip_num, led_gpio_config->gpio_num, get_gpio_mode_name(led_gpio_mode)); + set_gpio_mode_NEW(led_gpio_config, + (led_gpio_config->active_low ^ led_gpio_config->init_active) + ? AM335XGPIO_GPIO_MODE_OUTPUT_HIGH : AM335XGPIO_GPIO_MODE_OUTPUT_LOW); } /* Set GPIO modes for TRST and SRST and make both inactive */ @@ -691,6 +739,8 @@ static int am335xgpio_init(void) static int am335xgpio_quit(void) { + const struct adapter_gpio_config *led_gpio_config = adapter_get_gpio_config(ADAPTER_GPIO_IDX_LED); + if (transport_is_jtag()) { set_gpio_mode(tdo_gpio, tdo_gpio_mode); set_gpio_mode(tdi_gpio, tdi_gpio_mode); @@ -710,8 +760,8 @@ static int am335xgpio_quit(void) if (is_gpio_valid(srst_gpio)) set_gpio_mode(srst_gpio, srst_gpio_mode); - if (is_gpio_valid(led_gpio)) - set_gpio_mode(led_gpio, led_gpio_mode); + if (is_gpio_config_valid(led_gpio_config)) + set_gpio_mode_NEW(led_gpio_config, led_gpio_mode); return ERROR_OK; } --