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
>= 0
90 && gpio_config
->chip_num
< AM335XGPIO_NUM_GPIO_CHIPS
91 && gpio_config
->gpio_num
>= 0
92 && gpio_config
->gpio_num
< AM335XGPIO_NUM_GPIO_PER_CHIP
;
95 static int get_gpio_value(const struct adapter_gpio_config
*gpio_config
)
97 unsigned int shift
= gpio_config
->gpio_num
;
98 uint32_t value
= AM335XGPIO_READ_REG(gpio_config
->chip_num
, AM335XGPIO_GPIO_DATAIN_OFFSET
);
99 value
= (value
>> shift
) & 1;
100 return value
^ (gpio_config
->active_low
? 1 : 0);
103 static void set_gpio_value(const struct adapter_gpio_config
*gpio_config
, int value
)
105 value
= value
^ (gpio_config
->active_low
? 1 : 0);
106 switch (gpio_config
->drive
) {
107 case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL
:
109 AM335XGPIO_SET_HIGH(gpio_config
);
111 AM335XGPIO_SET_LOW(gpio_config
);
112 /* For performance reasons assume the GPIO is already set as an output
113 * and therefore the call can be omitted here.
116 case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN
:
118 AM335XGPIO_SET_INPUT(gpio_config
);
120 AM335XGPIO_SET_LOW(gpio_config
);
121 AM335XGPIO_SET_OUTPUT(gpio_config
);
124 case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE
:
126 AM335XGPIO_SET_HIGH(gpio_config
);
127 AM335XGPIO_SET_OUTPUT(gpio_config
);
129 AM335XGPIO_SET_INPUT(gpio_config
);
135 static enum amx335gpio_initial_gpio_mode
get_gpio_mode(const struct adapter_gpio_config
*gpio_config
)
137 if (AM335XGPIO_READ_REG(gpio_config
->chip_num
, AM335XGPIO_GPIO_OE_OFFSET
) & BIT(gpio_config
->gpio_num
))
138 return AM335XGPIO_GPIO_MODE_INPUT
;
140 /* Return output level too so that pin mode can be fully restored */
141 if (AM335XGPIO_READ_REG(gpio_config
->chip_num
, AM335XGPIO_GPIO_DATAOUT_OFFSET
) & BIT(gpio_config
->gpio_num
))
142 return AM335XGPIO_GPIO_MODE_OUTPUT_HIGH
;
143 return AM335XGPIO_GPIO_MODE_OUTPUT_LOW
;
146 static const char *get_gpio_mode_name(enum amx335gpio_initial_gpio_mode gpio_mode
)
149 case AM335XGPIO_GPIO_MODE_INPUT
:
151 case AM335XGPIO_GPIO_MODE_OUTPUT_LOW
:
152 return "output (low)";
153 case AM335XGPIO_GPIO_MODE_OUTPUT_HIGH
:
154 return "output (high)";
159 static void initialize_gpio(enum adapter_gpio_config_index idx
)
161 if (!is_gpio_config_valid(&adapter_gpio_config
[idx
]))
164 initial_gpio_mode
[idx
] = get_gpio_mode(&adapter_gpio_config
[idx
]);
165 LOG_DEBUG("saved GPIO mode for %s (GPIO %d %d): %s",
166 adapter_gpio_get_name(idx
), adapter_gpio_config
[idx
].chip_num
, adapter_gpio_config
[idx
].gpio_num
,
167 get_gpio_mode_name(initial_gpio_mode
[idx
]));
169 if (adapter_gpio_config
[idx
].pull
!= ADAPTER_GPIO_PULL_NONE
) {
170 LOG_WARNING("am335xgpio does not support pull-up or pull-down settings (signal %s)",
171 adapter_gpio_get_name(idx
));
174 switch (adapter_gpio_config
[idx
].init_state
) {
175 case ADAPTER_GPIO_INIT_STATE_INACTIVE
:
176 set_gpio_value(&adapter_gpio_config
[idx
], 0);
178 case ADAPTER_GPIO_INIT_STATE_ACTIVE
:
179 set_gpio_value(&adapter_gpio_config
[idx
], 1);
181 case ADAPTER_GPIO_INIT_STATE_INPUT
:
182 AM335XGPIO_SET_INPUT(&adapter_gpio_config
[idx
]);
186 /* Direction for non push-pull is already set by set_gpio_value() */
187 if (adapter_gpio_config
[idx
].drive
== ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL
188 && adapter_gpio_config
[idx
].init_state
!= ADAPTER_GPIO_INIT_STATE_INPUT
)
189 AM335XGPIO_SET_OUTPUT(&adapter_gpio_config
[idx
]);
192 static void restore_gpio(enum adapter_gpio_config_index idx
)
194 if (is_gpio_config_valid(&adapter_gpio_config
[idx
])) {
195 switch (initial_gpio_mode
[idx
]) {
196 case AM335XGPIO_GPIO_MODE_INPUT
:
197 AM335XGPIO_SET_INPUT(&adapter_gpio_config
[idx
]);
199 case AM335XGPIO_GPIO_MODE_OUTPUT_LOW
:
200 AM335XGPIO_SET_LOW(&adapter_gpio_config
[idx
]);
201 AM335XGPIO_SET_OUTPUT(&adapter_gpio_config
[idx
]);
203 case AM335XGPIO_GPIO_MODE_OUTPUT_HIGH
:
204 AM335XGPIO_SET_HIGH(&adapter_gpio_config
[idx
]);
205 AM335XGPIO_SET_OUTPUT(&adapter_gpio_config
[idx
]);
211 static bb_value_t
am335xgpio_read(void)
213 return get_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TDO
]) ? BB_HIGH
: BB_LOW
;
216 static int am335xgpio_write(int tck
, int tms
, int tdi
)
218 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TDI
], tdi
);
219 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TMS
], tms
);
220 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TCK
], tck
); /* Write clock last */
222 for (unsigned int i
= 0; i
< jtag_delay
; ++i
)
228 static int am335xgpio_swd_write(int swclk
, int swdio
)
230 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
], swdio
);
231 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWCLK
], swclk
); /* Write clock last */
233 for (unsigned int i
= 0; i
< jtag_delay
; ++i
)
239 /* (1) assert or (0) deassert reset lines */
240 static int am335xgpio_reset(int trst
, int srst
)
242 /* As the "adapter reset_config" command keeps the srst and trst gpio drive
243 * mode settings in sync we can use our standard set_gpio_value() function
244 * that honours drive mode and active low.
246 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SRST
]))
247 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SRST
], srst
);
249 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TRST
]))
250 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TRST
], trst
);
252 LOG_DEBUG("am335xgpio_reset(%d, %d), trst_gpio: %d %d, srst_gpio: %d %d",
254 adapter_gpio_config
[ADAPTER_GPIO_IDX_TRST
].chip_num
, adapter_gpio_config
[ADAPTER_GPIO_IDX_TRST
].gpio_num
,
255 adapter_gpio_config
[ADAPTER_GPIO_IDX_SRST
].chip_num
, adapter_gpio_config
[ADAPTER_GPIO_IDX_SRST
].gpio_num
);
259 static void am335xgpio_swdio_drive(bool is_output
)
262 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO_DIR
]))
263 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO_DIR
], 1);
264 AM335XGPIO_SET_OUTPUT(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]);
266 AM335XGPIO_SET_INPUT(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]);
267 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO_DIR
]))
268 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO_DIR
], 0);
272 static int am335xgpio_swdio_read(void)
274 return get_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]);
277 static int am335xgpio_blink(int on
)
279 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_LED
]))
280 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_LED
], on
);
285 static struct bitbang_interface am335xgpio_bitbang
= {
286 .read
= am335xgpio_read
,
287 .write
= am335xgpio_write
,
288 .swdio_read
= am335xgpio_swdio_read
,
289 .swdio_drive
= am335xgpio_swdio_drive
,
290 .swd_write
= am335xgpio_swd_write
,
291 .blink
= am335xgpio_blink
294 static int am335xgpio_khz(int khz
, int *jtag_speed
)
297 LOG_DEBUG("RCLK not supported");
300 *jtag_speed
= speed_coeff
/ khz
- speed_offset
;
306 static int am335xgpio_speed_div(int speed
, int *khz
)
308 *khz
= speed_coeff
/ (speed
+ speed_offset
);
312 static int am335xgpio_speed(int speed
)
318 COMMAND_HANDLER(am335xgpio_handle_speed_coeffs
)
321 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], speed_coeff
);
322 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], speed_offset
);
325 command_print(CMD
, "AM335x GPIO config: speed_coeffs = %d, speed_offset = %d",
326 speed_coeff
, speed_offset
);
330 static const struct command_registration am335xgpio_subcommand_handlers
[] = {
332 .name
= "speed_coeffs",
333 .handler
= am335xgpio_handle_speed_coeffs
,
334 .mode
= COMMAND_CONFIG
,
335 .help
= "SPEED_COEFF and SPEED_OFFSET for delay calculations.",
336 .usage
= "[SPEED_COEFF SPEED_OFFSET]",
338 COMMAND_REGISTRATION_DONE
341 static const struct command_registration am335xgpio_command_handlers
[] = {
343 .name
= "am335xgpio",
345 .help
= "perform am335xgpio management",
346 .chain
= am335xgpio_subcommand_handlers
,
349 COMMAND_REGISTRATION_DONE
352 static const char * const am335xgpio_transports
[] = { "jtag", "swd", NULL
};
354 static struct jtag_interface am335xgpio_interface
= {
355 .supported
= DEBUG_CAP_TMS_SEQ
,
356 .execute_queue
= bitbang_execute_queue
,
359 static bool am335xgpio_jtag_mode_possible(void)
361 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TCK
]))
363 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TMS
]))
365 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TDI
]))
367 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TDO
]))
372 static bool am335xgpio_swd_mode_possible(void)
374 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWCLK
]))
376 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]))
381 static void am335xgpio_munmap(void)
383 for (unsigned int i
= 0; i
< AM335XGPIO_NUM_GPIO_CHIPS
&& am335xgpio_gpio_chip_mmap_addr
[i
] != MAP_FAILED
; ++i
)
384 if (munmap((void *)am335xgpio_gpio_chip_mmap_addr
[i
], sysconf(_SC_PAGE_SIZE
)) < 0)
385 LOG_ERROR("Cannot unmap GPIO memory for chip %d: %s", i
, strerror(errno
));
388 static int am335xgpio_init(void)
390 LOG_INFO("AM335x GPIO JTAG/SWD bitbang driver");
392 bitbang_interface
= &am335xgpio_bitbang
;
393 adapter_gpio_config
= adapter_gpio_get_config();
395 if (transport_is_jtag() && !am335xgpio_jtag_mode_possible()) {
396 LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
397 return ERROR_JTAG_INIT_FAILED
;
400 if (transport_is_swd() && !am335xgpio_swd_mode_possible()) {
401 LOG_ERROR("Require swclk and swdio gpio for SWD mode");
402 return ERROR_JTAG_INIT_FAILED
;
405 dev_mem_fd
= open("/dev/gpiomem", O_RDWR
| O_SYNC
);
406 if (dev_mem_fd
< 0) {
407 LOG_DEBUG("Cannot open /dev/gpiomem, fallback to /dev/mem");
408 dev_mem_fd
= open("/dev/mem", O_RDWR
| O_SYNC
);
410 if (dev_mem_fd
< 0) {
411 LOG_ERROR("open: %s", strerror(errno
));
412 return ERROR_JTAG_INIT_FAILED
;
415 for (unsigned int i
= 0; i
< AM335XGPIO_NUM_GPIO_CHIPS
; ++i
) {
416 am335xgpio_gpio_chip_mmap_addr
[i
] = mmap(NULL
, sysconf(_SC_PAGE_SIZE
), PROT_READ
| PROT_WRITE
,
417 MAP_SHARED
, dev_mem_fd
, am335xgpio_gpio_chip_hw_addr
[i
]);
419 if (am335xgpio_gpio_chip_mmap_addr
[i
] == MAP_FAILED
) {
420 LOG_ERROR("mmap: %s", strerror(errno
));
423 return ERROR_JTAG_INIT_FAILED
;
428 /* Configure JTAG/SWD signals. Default directions and initial states are handled
429 * by adapter.c and "adapter gpio" command.
431 if (transport_is_jtag()) {
432 initialize_gpio(ADAPTER_GPIO_IDX_TDO
);
433 initialize_gpio(ADAPTER_GPIO_IDX_TDI
);
434 initialize_gpio(ADAPTER_GPIO_IDX_TMS
);
435 initialize_gpio(ADAPTER_GPIO_IDX_TCK
);
436 initialize_gpio(ADAPTER_GPIO_IDX_TRST
);
439 if (transport_is_swd()) {
440 /* swdio and its buffer should be initialized in the order that prevents
441 * two outputs from being connected together. This will occur if the
442 * swdio GPIO of the AM335x is configured as an output while its
443 * external buffer is configured to send the swdio signal from the
444 * target to the AM335x.
446 if (adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
].init_state
== ADAPTER_GPIO_INIT_STATE_INPUT
) {
447 initialize_gpio(ADAPTER_GPIO_IDX_SWDIO
);
448 initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR
);
450 initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR
);
451 initialize_gpio(ADAPTER_GPIO_IDX_SWDIO
);
454 initialize_gpio(ADAPTER_GPIO_IDX_SWCLK
);
457 initialize_gpio(ADAPTER_GPIO_IDX_SRST
);
458 initialize_gpio(ADAPTER_GPIO_IDX_LED
);
463 static int am335xgpio_quit(void)
465 if (transport_is_jtag()) {
466 restore_gpio(ADAPTER_GPIO_IDX_TDO
);
467 restore_gpio(ADAPTER_GPIO_IDX_TDI
);
468 restore_gpio(ADAPTER_GPIO_IDX_TMS
);
469 restore_gpio(ADAPTER_GPIO_IDX_TCK
);
470 restore_gpio(ADAPTER_GPIO_IDX_TRST
);
473 if (transport_is_swd()) {
474 /* Restore swdio/swdio_dir to their initial modes, even if that means
475 * connecting two outputs. Begin by making swdio an input so that the
476 * current and final states of swdio and swdio_dir do not have to be
477 * considered to calculate the safe restoration order.
479 AM335XGPIO_SET_INPUT(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]);
480 restore_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR
);
481 restore_gpio(ADAPTER_GPIO_IDX_SWDIO
);
483 restore_gpio(ADAPTER_GPIO_IDX_SWCLK
);
486 restore_gpio(ADAPTER_GPIO_IDX_SRST
);
487 restore_gpio(ADAPTER_GPIO_IDX_LED
);
494 struct adapter_driver am335xgpio_adapter_driver
= {
495 .name
= "am335xgpio",
496 .transports
= am335xgpio_transports
,
497 .commands
= am335xgpio_command_handlers
,
499 .init
= am335xgpio_init
,
500 .quit
= am335xgpio_quit
,
501 .reset
= am335xgpio_reset
,
502 .speed
= am335xgpio_speed
,
503 .khz
= am335xgpio_khz
,
504 .speed_div
= am335xgpio_speed_div
,
506 .jtag_ops
= &am335xgpio_interface
,
507 .swd_ops
= &bitbang_swd
,