jtag/drivers/bcm2835gpio: don't touch pad setting on /dev/gpiomem
The pads were configured at a wrong memory address if /dev/gpiomem was mapped. The pad setting registers are not accessible in mapped /dev/gpiomem, disable the pads setting if the driver doesn't open /dev/mem. While on it, do not fail the driver initialization if pad mapping fails - just emit a warning and work with unchanged pad setting. Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Change-Id: I0bce76cade8f7efd75efd9087a7d9ba6511a6239 Reviewed-on: https://review.openocd.org/c/openocd/+/7684 Tested-by: jenkins Reviewed-by: Jonathan Bell <jonathan@raspberrypi.com> Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
parent
30b0e9af8d
commit
c164906420
|
@ -3292,8 +3292,12 @@ configuration on exit.
|
||||||
GPIO numbers >= 32 can't be used for performance reasons. GPIO configuration is
|
GPIO numbers >= 32 can't be used for performance reasons. GPIO configuration is
|
||||||
handled by the generic command @ref{adapter gpio, @command{adapter gpio}}.
|
handled by the generic command @ref{adapter gpio, @command{adapter gpio}}.
|
||||||
|
|
||||||
|
/dev/gpiomem is preferred for GPIO mapping with fallback to /dev/mem.
|
||||||
|
If /dev/mem is used GPIO 0-27 pads are set to the limited
|
||||||
|
slew rate and drive strength is reduced to 4 mA (2 mA on RPi 4).
|
||||||
|
|
||||||
See @file{interface/raspberrypi-native.cfg} for a sample config and
|
See @file{interface/raspberrypi-native.cfg} for a sample config and
|
||||||
pinout.
|
@file{interface/raspberrypi-gpio-connector.cfg} for pinout.
|
||||||
|
|
||||||
@deffn {Config Command} {bcm2835gpio speed_coeffs} @var{speed_coeff} @var{speed_offset}
|
@deffn {Config Command} {bcm2835gpio speed_coeffs} @var{speed_coeff} @var{speed_offset}
|
||||||
Set SPEED_COEFF and SPEED_OFFSET for delay calculations. If unspecified,
|
Set SPEED_COEFF and SPEED_OFFSET for delay calculations. If unspecified,
|
||||||
|
|
|
@ -409,10 +409,13 @@ static int bcm2835gpio_init(void)
|
||||||
return ERROR_JTAG_INIT_FAILED;
|
return ERROR_JTAG_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool pad_mapping_possible = false;
|
||||||
|
|
||||||
dev_mem_fd = open("/dev/gpiomem", O_RDWR | O_SYNC);
|
dev_mem_fd = open("/dev/gpiomem", O_RDWR | O_SYNC);
|
||||||
if (dev_mem_fd < 0) {
|
if (dev_mem_fd < 0) {
|
||||||
LOG_DEBUG("Cannot open /dev/gpiomem, fallback to /dev/mem");
|
LOG_DEBUG("Cannot open /dev/gpiomem, fallback to /dev/mem");
|
||||||
dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
|
dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
|
||||||
|
pad_mapping_possible = true;
|
||||||
}
|
}
|
||||||
if (dev_mem_fd < 0) {
|
if (dev_mem_fd < 0) {
|
||||||
LOG_ERROR("open: %s", strerror(errno));
|
LOG_ERROR("open: %s", strerror(errno));
|
||||||
|
@ -428,21 +431,28 @@ static int bcm2835gpio_init(void)
|
||||||
return ERROR_JTAG_INIT_FAILED;
|
return ERROR_JTAG_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
pads_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
|
/* TODO: move pads config to a separate utility */
|
||||||
|
if (pad_mapping_possible) {
|
||||||
|
pads_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
|
||||||
MAP_SHARED, dev_mem_fd, BCM2835_PADS_GPIO_0_27);
|
MAP_SHARED, dev_mem_fd, BCM2835_PADS_GPIO_0_27);
|
||||||
|
|
||||||
if (pads_base == MAP_FAILED) {
|
if (pads_base == MAP_FAILED) {
|
||||||
LOG_ERROR("mmap: %s", strerror(errno));
|
LOG_ERROR("mmap pads: %s", strerror(errno));
|
||||||
bcm2835gpio_munmap();
|
LOG_WARNING("Continuing with unchanged GPIO pad settings (drive strength and slew rate)");
|
||||||
close(dev_mem_fd);
|
}
|
||||||
return ERROR_JTAG_INIT_FAILED;
|
} else {
|
||||||
|
pads_base = MAP_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(dev_mem_fd);
|
close(dev_mem_fd);
|
||||||
|
|
||||||
/* set 4mA drive strength, slew rate limited, hysteresis on */
|
if (pads_base != MAP_FAILED) {
|
||||||
initial_drive_strength_etc = pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] & 0x1f;
|
/* set 4mA drive strength, slew rate limited, hysteresis on */
|
||||||
pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1;
|
initial_drive_strength_etc = pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] & 0x1f;
|
||||||
|
LOG_INFO("initial pads conf %08x", pads_base[BCM2835_PADS_GPIO_0_27_OFFSET]);
|
||||||
|
pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1;
|
||||||
|
LOG_INFO("pads conf set to %08x", pads_base[BCM2835_PADS_GPIO_0_27_OFFSET]);
|
||||||
|
}
|
||||||
|
|
||||||
/* Configure JTAG/SWD signals. Default directions and initial states are handled
|
/* Configure JTAG/SWD signals. Default directions and initial states are handled
|
||||||
* by adapter.c and "adapter gpio" command.
|
* by adapter.c and "adapter gpio" command.
|
||||||
|
@ -513,8 +523,10 @@ static int bcm2835gpio_quit(void)
|
||||||
restore_gpio(ADAPTER_GPIO_IDX_SRST);
|
restore_gpio(ADAPTER_GPIO_IDX_SRST);
|
||||||
restore_gpio(ADAPTER_GPIO_IDX_LED);
|
restore_gpio(ADAPTER_GPIO_IDX_LED);
|
||||||
|
|
||||||
/* Restore drive strength. MSB is password ("5A") */
|
if (pads_base != MAP_FAILED) {
|
||||||
pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5A000000 | initial_drive_strength_etc;
|
/* Restore drive strength. MSB is password ("5A") */
|
||||||
|
pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5A000000 | initial_drive_strength_etc;
|
||||||
|
}
|
||||||
bcm2835gpio_munmap();
|
bcm2835gpio_munmap();
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
|
|
Loading…
Reference in New Issue