aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTomas Vanek <vanekt@fbl.cz>2022-11-15 09:47:43 +0100
committerTomas Vanek <vanekt@fbl.cz>2023-05-24 05:25:28 +0000
commitc164906420521546849d03a26977fb91838aca8e (patch)
tree1fd15d6064ca291ca8e4825ddcdf9d3bd42e575e /src
parent30b0e9af8d1e68ee051ac62dd0e27c920fb396bd (diff)
downloadriscv-openocd-c164906420521546849d03a26977fb91838aca8e.zip
riscv-openocd-c164906420521546849d03a26977fb91838aca8e.tar.gz
riscv-openocd-c164906420521546849d03a26977fb91838aca8e.tar.bz2
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>
Diffstat (limited to 'src')
-rw-r--r--src/jtag/drivers/bcm2835gpio.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c
index 879ca3c..16c76cd 100644
--- a/src/jtag/drivers/bcm2835gpio.c
+++ b/src/jtag/drivers/bcm2835gpio.c
@@ -409,10 +409,13 @@ static int bcm2835gpio_init(void)
return ERROR_JTAG_INIT_FAILED;
}
+ bool pad_mapping_possible = false;
+
dev_mem_fd = open("/dev/gpiomem", O_RDWR | O_SYNC);
if (dev_mem_fd < 0) {
LOG_DEBUG("Cannot open /dev/gpiomem, fallback to /dev/mem");
dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
+ pad_mapping_possible = true;
}
if (dev_mem_fd < 0) {
LOG_ERROR("open: %s", strerror(errno));
@@ -428,21 +431,28 @@ static int bcm2835gpio_init(void)
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);
- if (pads_base == MAP_FAILED) {
- LOG_ERROR("mmap: %s", strerror(errno));
- bcm2835gpio_munmap();
- close(dev_mem_fd);
- return ERROR_JTAG_INIT_FAILED;
+ if (pads_base == MAP_FAILED) {
+ LOG_ERROR("mmap pads: %s", strerror(errno));
+ LOG_WARNING("Continuing with unchanged GPIO pad settings (drive strength and slew rate)");
+ }
+ } else {
+ pads_base = MAP_FAILED;
}
close(dev_mem_fd);
- /* set 4mA drive strength, slew rate limited, hysteresis on */
- initial_drive_strength_etc = pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] & 0x1f;
- pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1;
+ if (pads_base != MAP_FAILED) {
+ /* set 4mA drive strength, slew rate limited, hysteresis on */
+ 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
* 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_LED);
- /* Restore drive strength. MSB is password ("5A") */
- pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5A000000 | initial_drive_strength_etc;
+ if (pads_base != MAP_FAILED) {
+ /* Restore drive strength. MSB is password ("5A") */
+ pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5A000000 | initial_drive_strength_etc;
+ }
bcm2835gpio_munmap();
return ERROR_OK;