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 AM335XGPIO_SET_OUTPUT(&adapter_gpio_config
[idx
]);
191 static void restore_gpio(enum adapter_gpio_config_index idx
)
193 if (is_gpio_config_valid(&adapter_gpio_config
[idx
])) {
194 switch (initial_gpio_mode
[idx
]) {
195 case AM335XGPIO_GPIO_MODE_INPUT
:
196 AM335XGPIO_SET_INPUT(&adapter_gpio_config
[idx
]);
198 case AM335XGPIO_GPIO_MODE_OUTPUT_LOW
:
199 AM335XGPIO_SET_LOW(&adapter_gpio_config
[idx
]);
200 AM335XGPIO_SET_OUTPUT(&adapter_gpio_config
[idx
]);
202 case AM335XGPIO_GPIO_MODE_OUTPUT_HIGH
:
203 AM335XGPIO_SET_HIGH(&adapter_gpio_config
[idx
]);
204 AM335XGPIO_SET_OUTPUT(&adapter_gpio_config
[idx
]);
210 static bb_value_t
am335xgpio_read(void)
212 return get_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TDO
]) ? BB_HIGH
: BB_LOW
;
215 static int am335xgpio_write(int tck
, int tms
, int tdi
)
217 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TDI
], tdi
);
218 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TMS
], tms
);
219 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TCK
], tck
); /* Write clock last */
221 for (unsigned int i
= 0; i
< jtag_delay
; ++i
)
227 static int am335xgpio_swd_write(int swclk
, int swdio
)
229 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
], swdio
);
230 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWCLK
], swclk
); /* Write clock last */
232 for (unsigned int i
= 0; i
< jtag_delay
; ++i
)
238 /* (1) assert or (0) deassert reset lines */
239 static int am335xgpio_reset(int trst
, int srst
)
241 /* As the "adapter reset_config" command keeps the srst and trst gpio drive
242 * mode settings in sync we can use our standard set_gpio_value() function
243 * that honours drive mode and active low.
245 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SRST
]))
246 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SRST
], srst
);
248 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TRST
]))
249 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TRST
], trst
);
251 LOG_DEBUG("am335xgpio_reset(%d, %d), trst_gpio: %d %d, srst_gpio: %d %d",
253 adapter_gpio_config
[ADAPTER_GPIO_IDX_TRST
].chip_num
, adapter_gpio_config
[ADAPTER_GPIO_IDX_TRST
].gpio_num
,
254 adapter_gpio_config
[ADAPTER_GPIO_IDX_SRST
].chip_num
, adapter_gpio_config
[ADAPTER_GPIO_IDX_SRST
].gpio_num
);
258 static void am335xgpio_swdio_drive(bool is_output
)
261 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO_DIR
]))
262 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO_DIR
], 1);
263 AM335XGPIO_SET_OUTPUT(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]);
265 AM335XGPIO_SET_INPUT(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]);
266 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO_DIR
]))
267 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO_DIR
], 0);
271 static int am335xgpio_swdio_read(void)
273 return get_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]);
276 static int am335xgpio_blink(int on
)
278 if (is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_LED
]))
279 set_gpio_value(&adapter_gpio_config
[ADAPTER_GPIO_IDX_LED
], on
);
284 static struct bitbang_interface am335xgpio_bitbang
= {
285 .read
= am335xgpio_read
,
286 .write
= am335xgpio_write
,
287 .swdio_read
= am335xgpio_swdio_read
,
288 .swdio_drive
= am335xgpio_swdio_drive
,
289 .swd_write
= am335xgpio_swd_write
,
290 .blink
= am335xgpio_blink
293 static int am335xgpio_khz(int khz
, int *jtag_speed
)
296 LOG_DEBUG("RCLK not supported");
299 *jtag_speed
= speed_coeff
/ khz
- speed_offset
;
305 static int am335xgpio_speed_div(int speed
, int *khz
)
307 *khz
= speed_coeff
/ (speed
+ speed_offset
);
311 static int am335xgpio_speed(int speed
)
317 COMMAND_HANDLER(am335xgpio_handle_speed_coeffs
)
320 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], speed_coeff
);
321 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], speed_offset
);
324 command_print(CMD
, "AM335x GPIO config: speed_coeffs = %d, speed_offset = %d",
325 speed_coeff
, speed_offset
);
329 static const struct command_registration am335xgpio_subcommand_handlers
[] = {
331 .name
= "speed_coeffs",
332 .handler
= am335xgpio_handle_speed_coeffs
,
333 .mode
= COMMAND_CONFIG
,
334 .help
= "SPEED_COEFF and SPEED_OFFSET for delay calculations.",
335 .usage
= "[SPEED_COEFF SPEED_OFFSET]",
337 COMMAND_REGISTRATION_DONE
340 static const struct command_registration am335xgpio_command_handlers
[] = {
342 .name
= "am335xgpio",
344 .help
= "perform am335xgpio management",
345 .chain
= am335xgpio_subcommand_handlers
,
348 COMMAND_REGISTRATION_DONE
351 static const char * const am335xgpio_transports
[] = { "jtag", "swd", NULL
};
353 static struct jtag_interface am335xgpio_interface
= {
354 .supported
= DEBUG_CAP_TMS_SEQ
,
355 .execute_queue
= bitbang_execute_queue
,
358 static bool am335xgpio_jtag_mode_possible(void)
360 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TCK
]))
362 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TMS
]))
364 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TDI
]))
366 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_TDO
]))
371 static bool am335xgpio_swd_mode_possible(void)
373 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWCLK
]))
375 if (!is_gpio_config_valid(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]))
380 static void am335xgpio_munmap(void)
382 for (unsigned int i
= 0; i
< AM335XGPIO_NUM_GPIO_CHIPS
&& am335xgpio_gpio_chip_mmap_addr
[i
] != MAP_FAILED
; ++i
)
383 if (munmap((void *)am335xgpio_gpio_chip_mmap_addr
[i
], sysconf(_SC_PAGE_SIZE
)) < 0)
384 LOG_ERROR("Cannot unmap GPIO memory for chip %d: %s", i
, strerror(errno
));
387 static int am335xgpio_init(void)
389 LOG_INFO("AM335x GPIO JTAG/SWD bitbang driver");
391 bitbang_interface
= &am335xgpio_bitbang
;
392 adapter_gpio_config
= adapter_gpio_get_config();
394 if (transport_is_jtag() && !am335xgpio_jtag_mode_possible()) {
395 LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode");
396 return ERROR_JTAG_INIT_FAILED
;
399 if (transport_is_swd() && !am335xgpio_swd_mode_possible()) {
400 LOG_ERROR("Require swclk and swdio gpio for SWD mode");
401 return ERROR_JTAG_INIT_FAILED
;
404 dev_mem_fd
= open("/dev/gpiomem", O_RDWR
| O_SYNC
);
405 if (dev_mem_fd
< 0) {
406 LOG_DEBUG("Cannot open /dev/gpiomem, fallback to /dev/mem");
407 dev_mem_fd
= open("/dev/mem", O_RDWR
| O_SYNC
);
409 if (dev_mem_fd
< 0) {
410 LOG_ERROR("open: %s", strerror(errno
));
411 return ERROR_JTAG_INIT_FAILED
;
414 for (unsigned int i
= 0; i
< AM335XGPIO_NUM_GPIO_CHIPS
; ++i
) {
415 am335xgpio_gpio_chip_mmap_addr
[i
] = mmap(NULL
, sysconf(_SC_PAGE_SIZE
), PROT_READ
| PROT_WRITE
,
416 MAP_SHARED
, dev_mem_fd
, am335xgpio_gpio_chip_hw_addr
[i
]);
418 if (am335xgpio_gpio_chip_mmap_addr
[i
] == MAP_FAILED
) {
419 LOG_ERROR("mmap: %s", strerror(errno
));
422 return ERROR_JTAG_INIT_FAILED
;
427 /* Configure JTAG/SWD signals. Default directions and initial states are handled
428 * by adapter.c and "adapter gpio" command.
430 if (transport_is_jtag()) {
431 initialize_gpio(ADAPTER_GPIO_IDX_TDO
);
432 initialize_gpio(ADAPTER_GPIO_IDX_TDI
);
433 initialize_gpio(ADAPTER_GPIO_IDX_TMS
);
434 initialize_gpio(ADAPTER_GPIO_IDX_TCK
);
435 initialize_gpio(ADAPTER_GPIO_IDX_TRST
);
438 if (transport_is_swd()) {
439 /* swdio and its buffer should be initialized in the order that prevents
440 * two outputs from being connected together. This will occur if the
441 * swdio GPIO of the AM335x is configured as an output while its
442 * external buffer is configured to send the swdio signal from the
443 * target to the AM335x.
445 if (adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
].init_state
== ADAPTER_GPIO_INIT_STATE_INPUT
) {
446 initialize_gpio(ADAPTER_GPIO_IDX_SWDIO
);
447 initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR
);
449 initialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR
);
450 initialize_gpio(ADAPTER_GPIO_IDX_SWDIO
);
453 initialize_gpio(ADAPTER_GPIO_IDX_SWCLK
);
456 initialize_gpio(ADAPTER_GPIO_IDX_SRST
);
457 initialize_gpio(ADAPTER_GPIO_IDX_LED
);
462 static int am335xgpio_quit(void)
464 if (transport_is_jtag()) {
465 restore_gpio(ADAPTER_GPIO_IDX_TDO
);
466 restore_gpio(ADAPTER_GPIO_IDX_TDI
);
467 restore_gpio(ADAPTER_GPIO_IDX_TMS
);
468 restore_gpio(ADAPTER_GPIO_IDX_TCK
);
469 restore_gpio(ADAPTER_GPIO_IDX_TRST
);
472 if (transport_is_swd()) {
473 /* Restore swdio/swdio_dir to their initial modes, even if that means
474 * connecting two outputs. Begin by making swdio an input so that the
475 * current and final states of swdio and swdio_dir do not have to be
476 * considered to calculate the safe restoration order.
478 AM335XGPIO_SET_INPUT(&adapter_gpio_config
[ADAPTER_GPIO_IDX_SWDIO
]);
479 restore_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR
);
480 restore_gpio(ADAPTER_GPIO_IDX_SWDIO
);
482 restore_gpio(ADAPTER_GPIO_IDX_SWCLK
);
485 restore_gpio(ADAPTER_GPIO_IDX_SRST
);
486 restore_gpio(ADAPTER_GPIO_IDX_LED
);
493 struct adapter_driver am335xgpio_adapter_driver
= {
494 .name
= "am335xgpio",
495 .transports
= am335xgpio_transports
,
496 .commands
= am335xgpio_command_handlers
,
498 .init
= am335xgpio_init
,
499 .quit
= am335xgpio_quit
,
500 .reset
= am335xgpio_reset
,
501 .speed
= am335xgpio_speed
,
502 .khz
= am335xgpio_khz
,
503 .speed_div
= am335xgpio_speed_div
,
505 .jtag_ops
= &am335xgpio_interface
,
506 .swd_ops
= &bitbang_swd
,