1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2022 by Steve Marple, stevemarple@googlemail.com *
6 * Based on bcm2835gpio.c and linuxgpiod.c *
7 ***************************************************************************/
13 #include <jtag/adapter.h>
14 #include <jtag/interface.h>
15 #include <transport/transport.h>
20 /* GPIO register base addresses. Values taken from "AM335x and AMIC110 Sitara
21 * Processors Technical Reference Manual", Chapter 2 Memory Map.
23 #define AM335XGPIO_NUM_GPIO_PER_CHIP 32
24 #define AM335XGPIO_NUM_GPIO_CHIPS 4
25 #define AM335XGPIO_GPIO0_HW_ADDR 0x44E07000
26 #define AM335XGPIO_GPIO1_HW_ADDR 0x4804C000
27 #define AM335XGPIO_GPIO2_HW_ADDR 0x481AC000
28 #define AM335XGPIO_GPIO3_HW_ADDR 0x481AE000
30 /* 32-bit offsets from GPIO chip base address. Values taken from "AM335x and
31 * AMIC110 Sitara Processors Technical Reference Manual", Chapter 25
32 * General-Purpose Input/Output.
34 #define AM335XGPIO_GPIO_OE_OFFSET (0x134 / 4)
35 #define AM335XGPIO_GPIO_DATAIN_OFFSET (0x138 / 4)
36 #define AM335XGPIO_GPIO_DATAOUT_OFFSET (0x13C / 4) /* DATAOUT register uses 0 for output, 1 for input */
37 #define AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET (0x190 / 4)
38 #define AM335XGPIO_GPIO_SETDATAOUT_OFFSET (0x194 / 4)
40 #define AM335XGPIO_READ_REG(chip_num, offset) \
41 (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)))
43 #define AM335XGPIO_WRITE_REG(chip_num, offset, value) \
44 (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) = (value))
46 #define AM335XGPIO_SET_REG_BITS(chip_num, offset, bit_mask) \
47 (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) |= (bit_mask))
49 #define AM335XGPIO_CLEAR_REG_BITS(chip_num, offset, bit_mask) \
50 (*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) &= ~(bit_mask))
52 #define AM335XGPIO_SET_INPUT(gpio_config) \
53 AM335XGPIO_SET_REG_BITS((gpio_config)->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT((gpio_config)->gpio_num))
54 #define AM335XGPIO_SET_OUTPUT(gpio_config) \
55 AM335XGPIO_CLEAR_REG_BITS((gpio_config)->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT((gpio_config)->gpio_num))
56 #define AM335XGPIO_SET_HIGH(gpio_config) \
57 AM335XGPIO_WRITE_REG((gpio_config)->chip_num, AM335XGPIO_GPIO_SETDATAOUT_OFFSET, BIT((gpio_config)->gpio_num))
58 #define AM335XGPIO_SET_LOW(gpio_config) \
59 AM335XGPIO_WRITE_REG((gpio_config)->chip_num, AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, BIT((gpio_config)->gpio_num))
61 enum amx335gpio_initial_gpio_mode
{
62 AM335XGPIO_GPIO_MODE_INPUT
,
63 AM335XGPIO_GPIO_MODE_OUTPUT_LOW
,
64 AM335XGPIO_GPIO_MODE_OUTPUT_HIGH
,
67 static const uint32_t am335xgpio_gpio_chip_hw_addr
[AM335XGPIO_NUM_GPIO_CHIPS
] = {
68 AM335XGPIO_GPIO0_HW_ADDR
,
69 AM335XGPIO_GPIO1_HW_ADDR
,
70 AM335XGPIO_GPIO2_HW_ADDR
,
71 AM335XGPIO_GPIO3_HW_ADDR
,
74 /* Memory-mapped address pointers */
75 static volatile uint32_t *am335xgpio_gpio_chip_mmap_addr
[AM335XGPIO_NUM_GPIO_CHIPS
];
77 static int dev_mem_fd
;
78 static enum amx335gpio_initial_gpio_mode initial_gpio_mode
[ADAPTER_GPIO_IDX_NUM
];
80 /* Transition delay coefficients */
81 static int speed_coeff
= 600000;
82 static int speed_offset
= 575;
83 static unsigned int jtag_delay
;
85 static const struct adapter_gpio_config
*adapter_gpio_config
;
87 static bool is_gpio_config_valid(const struct adapter_gpio_config
*gpio_config
)
89 return gpio_config
->chip_num
< AM335XGPIO_NUM_GPIO_CHIPS
90 && gpio_config
->gpio_num
< AM335XGPIO_NUM_GPIO_PER_CHIP
;
93 static int get_gpio_value(const struct adapter_gpio_config
*gpio_config
)
95 unsigned int shift
= gpio_config
->gpio_num
;
96 uint32_t value
= AM335XGPIO_READ_REG(gpio_config
->chip_num
, AM335XGPIO_GPIO_DATAIN_OFFSET
);
97 value
= (value
>> shift
) & 1;
98 return value
^ (gpio_config
->active_low
? 1 : 0);
101 static void set_gpio_value(const struct adapter_gpio_config
*gpio_config
, int value
)
103 value
= value
^ (gpio_config
->active_low
? 1 : 0);
104 switch (gpio_config
->drive
) {
105 case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL
:
107 AM335XGPIO_SET_HIGH(gpio_config
);
109 AM335XGPIO_SET_LOW(gpio_config
);
110 /* For performance reasons assume the GPIO is already set as an output
111 * and therefore the call can be omitted here.
114 case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN
:
116 AM335XGPIO_SET_INPUT(gpio_config
);
118 AM335XGPIO_SET_LOW(gpio_config
);
119 AM335XGPIO_SET_OUTPUT(gpio_config
);
122 case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE
:
124 AM335XGPIO_SET_HIGH(gpio_config
);
125 AM335XGPIO_SET_OUTPUT(gpio_config
);
127 AM335XGPIO_SET_INPUT(gpio_config
);
133 static enum amx335gpio_initial_gpio_mode
get_gpio_mode(const struct adapter_gpio_config
*gpio_config
)
135 if (AM335XGPIO_READ_REG(gpio_config
->chip_num
, AM335XGPIO_GPIO_OE_OFFSET
) & BIT(gpio_config
->gpio_num
))
136 return AM335XGPIO_GPIO_MODE_INPUT
;
138 /* Return output level too so that pin mode can be fully restored */
139 if (AM335XGPIO_READ_REG(gpio_config
->chip_num
, AM335XGPIO_GPIO_DATAOUT_OFFSET
) & BIT(gpio_config
->gpio_num
))
140 return AM335XGPIO_GPIO_MODE_OUTPUT_HIGH
;
141 return AM335XGPIO_GPIO_MODE_OUTPUT_LOW
;
144 static const char *get_gpio_mode_name(enum amx335gpio_initial_gpio_mode gpio_mode
)
147 case AM335XGPIO_GPIO_MODE_INPUT
:
149 case AM335XGPIO_GPIO_MODE_OUTPUT_LOW
:
150 return "output (low)";
151 case AM335XGPIO_GPIO_MODE_OUTPUT_HIGH
:
152 return "output (high)";
157 static void initialize_gpio(enum adapter_gpio_config_index idx
)
159 if (!is_gpio_config_valid(&adapter_gpio_config
[idx
]))
162 initial_gpio_mode
[idx
] = get_gpio_mode(&adapter_gpio_config
[idx
]);
163 LOG_DEBUG("saved GPIO mode for %s (GPIO %d %d): %s",
164 adapter_gpio_get_name(idx
), adapter_gpio_config
[idx
].chip_num
, adapter_gpio_config
[idx
].gpio_num
,
165 get_gpio_mode_name(initial_gpio_mode
[idx
]));
167 if (adapter_gpio_config
[idx
].pull
!= ADAPTER_GPIO_PULL_NONE
) {
168 LOG_WARNING("am335xgpio does not support pull-up or pull-down settings (signal %s)",
169 adapter_gpio_get_name(idx
));
172 switch (adapter_gpio_config
[idx
].init_state
) {
173 case ADAPTER_GPIO_INIT_STATE_INACTIVE
:
174 set_gpio_value(&adapter_gpio_config
[idx
], 0);
176 case ADAPTER_GPIO_INIT_STATE_ACTIVE
:
177 set_gpio_value(&adapter_gpio_config
[idx
], 1);
179 case ADAPTER_GPIO_INIT_STATE_INPUT
:
180 AM335XGPIO_SET_INPUT(&adapter_gpio_config
[idx
]);
184 /* Direction for non push-pull is already set by set_gpio_value() */
185 if (adapter_gpio_config
[idx
].drive
== ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL
186 && adapter_gpio_config
[idx
].init_state
!= ADAPTER_GPIO_INIT_STATE_INPUT
)
187 AM335XGPIO_SET_OUTPUT(&adapter_gpio_config
[idx
]);
190 static void restore_gpio(enum adapter_gpio_config_index idx
)
192 if (is_gpio_config_valid(&adapter_gpio_config
[idx
])) {
193 switch (initial_gpio_mode
[idx
]) {
194 case AM335XGPIO_GPIO_MODE_INPUT
:
195 AM335XGPIO_SET_INPUT(&adapter_gpio_config
[idx
]);
197 case AM335XGPIO_GPIO_MODE_OUTPUT_LOW
:
198 AM335XGPIO_SET_LOW(&adapter_gpio_config
[idx
]);
199 AM335XGPIO_SET_OUTPUT(&adapter_gpio_config
[idx
]);
201 case AM335XGPIO_GPIO_MODE_OUTPUT_HIGH
:
202 AM335XGPIO_SET_HIGH(&adapter_gpio_config
[idx
]);
203 AM335XGPIO_SET_OUTPUT(&adapter_gpio_config
[idx
]);
209 static bb_value_t
am335xgpio_read(void)
211 return get_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TDO
]) ? BB_HIGH
: BB_LOW
;
214 static int am335xgpio_write(int tck
, int tms
, int tdi
)
216 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TDI
], tdi
);
217 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TMS
], tms
);
218 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TCK
], tck
); /* Write clock last */
220 for (unsigned int i
= 0; i
< jtag_delay
; ++i
)
226 static int am335xgpio_swd_write(int swclk
, int swdio
)
228 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
], swdio
);
229 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWCLK
], swclk
); /* Write clock last */
231 for (unsigned int i
= 0; i
< jtag_delay
; ++i
)
237 /* (1) assert or (0) deassert reset lines */
238 static int am335xgpio_reset(int trst
, int srst
)
240 /* As the "adapter reset_config" command keeps the srst and trst gpio drive
241 * mode settings in sync we can use our standard set_gpio_value() function
242 * that honours drive mode and active low.
244 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SRST
]))
245 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SRST
], srst
);
247 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TRST
]))
248 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TRST
], trst
);
250 LOG_DEBUG("trst %d gpio: %d %d, srst %d gpio: %d %d",
252 (int)adapter_gpio_config
[ADAPTER_GPIO_IDX_TRST
].chip_num
,
253 (int)adapter_gpio_config
[ADAPTER_GPIO_IDX_TRST
].gpio_num
,
255 (int)adapter_gpio_config
[ADAPTER_GPIO_IDX_SRST
].chip_num
,
256 (int)adapter_gpio_config
[ADAPTER_GPIO_IDX_SRST
].gpio_num
);
260 static void am335xgpio_swdio_drive(bool is_output
)
263 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO_DIR
]))
264 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO_DIR
], 1);
265 AM335XGPIO_SET_OUTPUT(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]);
267 AM335XGPIO_SET_INPUT(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]);
268 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO_DIR
]))
269 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO_DIR
], 0);
273 static int am335xgpio_swdio_read(void)
275 return get_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]);
278 static int am335xgpio_blink(int on
)
280 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_LED
]))
281 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_LED
], on
);
286 static struct bitbang_interface am335xgpio_bitbang
= {
287 .read
= am335xgpio_read
,
288 .write
= am335xgpio_write
,
289 .swdio_read
= am335xgpio_swdio_read
,
290 .swdio_drive
= am335xgpio_swdio_drive
,
291 .swd_write
= am335xgpio_swd_write
,
292 .blink
= am335xgpio_blink
295 static int am335xgpio_khz(int khz
, int *jtag_speed
)
298 LOG_DEBUG("RCLK not supported");
301 *jtag_speed
= speed_coeff
/ khz
- speed_offset
;
307 static int am335xgpio_speed_div(int speed
, int *khz
)
309 *khz
= speed_coeff
/ (speed
+ speed_offset
);
313 static int am335xgpio_speed(int speed
)
319 COMMAND_HANDLER(am335xgpio_handle_speed_coeffs
)
322 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], speed_coeff
);
323 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], speed_offset
);
326 command_print(CMD
, "AM335x GPIO config: speed_coeffs = %d, speed_offset = %d",
327 speed_coeff
, speed_offset
);
331 static const struct command_registration am335xgpio_subcommand_handlers
[] = {
333 .name
= "speed_coeffs",
334 .handler
= am335xgpio_handle_speed_coeffs
,
335 .mode
= COMMAND_CONFIG
,
336 .help
= "SPEED_COEFF and SPEED_OFFSET for delay calculations.",
337 .usage
= "[SPEED_COEFF SPEED_OFFSET]",
339 COMMAND_REGISTRATION_DONE
342 static const struct command_registration am335xgpio_command_handlers
[] = {
344 .name
= "am335xgpio",
346 .help
= "perform am335xgpio management",
347 .chain
= am335xgpio_subcommand_handlers
,
350 COMMAND_REGISTRATION_DONE
353 static const char * const am335xgpio_transports
[] = { "jtag", "swd", NULL
};
355 static struct jtag_interface am335xgpio_interface
= {
356 .supported
= DEBUG_CAP_TMS_SEQ
,
357 .execute_queue
= bitbang_execute_queue
,
360 static bool am335xgpio_jtag_mode_possible(void)
362 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TCK
]))
364 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TMS
]))
366 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TDI
]))
368 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TDO
]))
373 static bool am335xgpio_swd_mode_possible(void)
375 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWCLK
]))
377 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]))
382 static void am335xgpio_munmap(void)
384 for (unsigned int i
= 0; i
< AM335XGPIO_NUM_GPIO_CHIPS
&& am335xgpio_gpio_chip_mmap_addr
[i
] != MAP_FAILED
; ++i
)
385 if (munmap((void *)am335xgpio_gpio_chip_mmap_addr
[i
], sysconf(_SC_PAGE_SIZE
)) < 0)
386 LOG_ERROR("Cannot unmap GPIO memory for chip %d: %s", i
, strerror(errno
));
389 static int am335xgpio_init(void)
391 LOG_INFO("AM335x GPIO JTAG/SWD bitbang driver");
393 bitbang_interface
= &am335xgpio_bitbang
;
394 adapter_gpio_config
= adapter_gpio_get_config();
396 if (transport_is_jtag() && !am335xgpio_jtag_mode_possible()) {
397 LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
398 return ERROR_JTAG_INIT_FAILED
;
401 if (transport_is_swd() && !am335xgpio_swd_mode_possible()) {
402 LOG_ERROR("Require swclk and swdio gpio for SWD mode");
403 return ERROR_JTAG_INIT_FAILED
;
406 dev_mem_fd
= open("/dev/gpiomem", O_RDWR
| O_SYNC
);
407 if (dev_mem_fd
< 0) {
408 LOG_DEBUG("Cannot open /dev/gpiomem, fallback to /dev/mem");
409 dev_mem_fd
= open("/dev/mem", O_RDWR
| O_SYNC
);
411 if (dev_mem_fd
< 0) {
412 LOG_ERROR("open: %s", strerror(errno
));
413 return ERROR_JTAG_INIT_FAILED
;
416 for (unsigned int i
= 0; i
< AM335XGPIO_NUM_GPIO_CHIPS
; ++i
) {
417 am335xgpio_gpio_chip_mmap_addr
[i
] = mmap(NULL
, sysconf(_SC_PAGE_SIZE
), PROT_READ
| PROT_WRITE
,
418 MAP_SHARED
, dev_mem_fd
, am335xgpio_gpio_chip_hw_addr
[i
]);
420 if (am335xgpio_gpio_chip_mmap_addr
[i
] == MAP_FAILED
) {
421 LOG_ERROR("mmap: %s", strerror(errno
));
424 return ERROR_JTAG_INIT_FAILED
;
429 /* Configure JTAG/SWD signals. Default directions and initial states are handled
430 * by adapter.c and "adapter gpio" command.
432 if (transport_is_jtag()) {
433 initialize_gpio(ADAPTER_GPIO_IDX_TDO
);
434 initialize_gpio(ADAPTER_GPIO_IDX_TDI
);
435 initialize_gpio(ADAPTER_GPIO_IDX_TMS
);
436 initialize_gpio(ADAPTER_GPIO_IDX_TCK
);
437 initialize_gpio(ADAPTER_GPIO_IDX_TRST
);
440 if (transport_is_swd()) {
441 /* swdio and its buffer should be initialized in the order that prevents
442 * two outputs from being connected together. This will occur if the
443 * swdio GPIO of the AM335x is configured as an output while its
444 * external buffer is configured to send the swdio signal from the
445 * target to the AM335x.
447 if (adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
].init_state
== ADAPTER_GPIO_INIT_STATE_INPUT
) {
448 initialize_gpio(ADAPTER_GPIO_IDX_SWDIO
);
449 initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR
);
451 initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR
);
452 initialize_gpio(ADAPTER_GPIO_IDX_SWDIO
);
455 initialize_gpio(ADAPTER_GPIO_IDX_SWCLK
);
458 initialize_gpio(ADAPTER_GPIO_IDX_SRST
);
459 initialize_gpio(ADAPTER_GPIO_IDX_LED
);
464 static int am335xgpio_quit(void)
466 if (transport_is_jtag()) {
467 restore_gpio(ADAPTER_GPIO_IDX_TDO
);
468 restore_gpio(ADAPTER_GPIO_IDX_TDI
);
469 restore_gpio(ADAPTER_GPIO_IDX_TMS
);
470 restore_gpio(ADAPTER_GPIO_IDX_TCK
);
471 restore_gpio(ADAPTER_GPIO_IDX_TRST
);
474 if (transport_is_swd()) {
475 /* Restore swdio/swdio_dir to their initial modes, even if that means
476 * connecting two outputs. Begin by making swdio an input so that the
477 * current and final states of swdio and swdio_dir do not have to be
478 * considered to calculate the safe restoration order.
480 AM335XGPIO_SET_INPUT(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]);
481 restore_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR
);
482 restore_gpio(ADAPTER_GPIO_IDX_SWDIO
);
484 restore_gpio(ADAPTER_GPIO_IDX_SWCLK
);
487 restore_gpio(ADAPTER_GPIO_IDX_SRST
);
488 restore_gpio(ADAPTER_GPIO_IDX_LED
);
495 struct adapter_driver am335xgpio_adapter_driver
= {
496 .name
= "am335xgpio",
497 .transports
= am335xgpio_transports
,
498 .commands
= am335xgpio_command_handlers
,
500 .init
= am335xgpio_init
,
501 .quit
= am335xgpio_quit
,
502 .reset
= am335xgpio_reset
,
503 .speed
= am335xgpio_speed
,
504 .khz
= am335xgpio_khz
,
505 .speed_div
= am335xgpio_speed_div
,
507 .jtag_ops
= &am335xgpio_interface
,
508 .swd_ops
= &bitbang_swd
,