diff --git a/boards/arm/npcm400f_evb/npcm400f_evb.dts b/boards/arm/npcm400f_evb/npcm400f_evb.dts index 0fb11dfbaf01c9..f405d70154525b 100644 --- a/boards/arm/npcm400f_evb/npcm400f_evb.dts +++ b/boards/arm/npcm400f_evb/npcm400f_evb.dts @@ -220,3 +220,11 @@ &usbd0 { status = "okay"; }; + +&jtag1 { + tck-gpios = <&gpiof 0 (GPIO_PUSH_PULL | GPIO_ACTIVE_HIGH)>; + tdi-gpios = <&gpiof 1 (GPIO_PUSH_PULL | GPIO_ACTIVE_HIGH)>; + tdo-gpios = <&gpiof 2 (GPIO_ACTIVE_HIGH)>; + tms-gpios = <&gpiof 3 (GPIO_PUSH_PULL | GPIO_ACTIVE_HIGH)>; + status = "okay"; +}; diff --git a/boards/arm/npcm400f_evb/npcm400f_evb_defconfig b/boards/arm/npcm400f_evb/npcm400f_evb_defconfig index 8315b1adc6f5db..32b29a354859a5 100644 --- a/boards/arm/npcm400f_evb/npcm400f_evb_defconfig +++ b/boards/arm/npcm400f_evb/npcm400f_evb_defconfig @@ -99,3 +99,8 @@ CONFIG_SPIP_NPCM4XX=y # USB Driver CONFIG_USB=y CONFIG_USB_DC_NPCM4XX=y + +# JTAG Driver +CONFIG_JTAG=y +CONFIG_JTAG_SHELL=y +CONFIG_JTAG_NPCM4XX=y diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index ebda184a653edf..90de8a7a7fcfca 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -59,3 +59,4 @@ add_subdirectory_ifdef(CONFIG_NEURAL_NET_ACCEL neural_net) add_subdirectory_ifdef(CONFIG_PTP_CLOCK ptp_clock) add_subdirectory_ifdef(CONFIG_EDAC edac) add_subdirectory_ifdef(CONFIG_CACHE_MANAGEMENT cache) +add_subdirectory_ifdef(CONFIG_JTAG jtag) diff --git a/drivers/Kconfig b/drivers/Kconfig index 10e898056dae03..a796df776bc652 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -119,4 +119,6 @@ source "drivers/disk/Kconfig" source "drivers/cache/Kconfig" +source "drivers/jtag/Kconfig" + endmenu diff --git a/drivers/jtag/CMakeLists.txt b/drivers/jtag/CMakeLists.txt new file mode 100644 index 00000000000000..00f4bbe12c0925 --- /dev/null +++ b/drivers/jtag/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_JTAG_SHELL jtag_shell.c) +zephyr_library_sources_ifdef(CONFIG_JTAG_NPCM4XX jtag_npcm4xx.c) diff --git a/drivers/jtag/Kconfig b/drivers/jtag/Kconfig new file mode 100644 index 00000000000000..efaaffe88c7529 --- /dev/null +++ b/drivers/jtag/Kconfig @@ -0,0 +1,29 @@ +# JTAG configuration options + +# Copyright (c) 2023 Zephyr +# SPDX-License-Identifier: Apache-2.0 + +# +# JTAG options +# +menuconfig JTAG + bool "JTAG drivers" + help + Enable JTAG driver configuration. + +if JTAG + +config JTAG_SHELL + bool "Enable JTAG Shell" + default y + depends on SHELL + help + Enable JTAG Shell for testing. + +module = JTAG +module-str = JTAG +source "subsys/logging/Kconfig.template.log_config" + +source "drivers/jtag/Kconfig.npcm4xx" + +endif diff --git a/drivers/jtag/Kconfig.npcm4xx b/drivers/jtag/Kconfig.npcm4xx new file mode 100644 index 00000000000000..50ee19f9844c85 --- /dev/null +++ b/drivers/jtag/Kconfig.npcm4xx @@ -0,0 +1,12 @@ +# NPCM4XX JTAG driver configuration options + +# Copyright (c) 2023 Nuvoton Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config JTAG_NPCM4XX + bool "NPCM4XX JTAG driver" + depends on SOC_FAMILY_NPCM4XX + help + This option enables the JTAG driver for NPCM4XX family of + processors. + Say y if you wish to use JTAG channels on NPCM4XX MCU. diff --git a/drivers/jtag/jtag_npcm4xx.c b/drivers/jtag/jtag_npcm4xx.c new file mode 100644 index 00000000000000..d8dad63188300c --- /dev/null +++ b/drivers/jtag/jtag_npcm4xx.c @@ -0,0 +1,618 @@ +/* + * Copyright (c) 2023 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nuvoton_npcm4xx_jtag + +#include +#include +#include +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_JTAG_LOG_LEVEL +#include +LOG_MODULE_REGISTER(jtag_npcm4xx); +#include "jtag_npcm4xx.h" +#include +#include + +struct jtag_info { + enum jtag_npcm4xx_tap_states tap_state; +}; + +static struct jtag_info gjtag; + +struct npcm4xx_jtag_gpio { + const char *port; + gpio_pin_t pin; + gpio_dt_flags_t flags; +}; + +struct jtag_npcm4xx_cfg { + struct npcm4xx_jtag_gpio gpio_tck; + struct npcm4xx_jtag_gpio gpio_tdi; + struct npcm4xx_jtag_gpio gpio_tdo; + struct npcm4xx_jtag_gpio gpio_tms; + uint8_t use_spi; +}; + +#define DEV_CFG(dev) ((const struct jtag_npcm4xx_cfg *const)(dev)->config) +#define DEV_DATA(dev) ((struct jtag_npcm4xx_data *)(dev)->data) + +#define NPCM4XX_JTAG_TCK_GPIO_ELEM(idx, inst) \ + { \ + DT_INST_GPIO_LABEL_BY_IDX(inst, tck_gpios, idx), \ + DT_INST_GPIO_PIN_BY_IDX(inst, tck_gpios, idx), \ + DT_INST_GPIO_FLAGS_BY_IDX(inst, tck_gpios, idx), \ + } + +#define NPCM4XX_JTAG_TDI_GPIO_ELEM(idx, inst) \ + { \ + DT_INST_GPIO_LABEL_BY_IDX(inst, tdi_gpios, idx), \ + DT_INST_GPIO_PIN_BY_IDX(inst, tdi_gpios, idx), \ + DT_INST_GPIO_FLAGS_BY_IDX(inst, tdi_gpios, idx), \ + } + +#define NPCM4XX_JTAG_TDO_GPIO_ELEM(idx, inst) \ + { \ + DT_INST_GPIO_LABEL_BY_IDX(inst, tdo_gpios, idx), \ + DT_INST_GPIO_PIN_BY_IDX(inst, tdo_gpios, idx), \ + DT_INST_GPIO_FLAGS_BY_IDX(inst, tdo_gpios, idx), \ + } + +#define NPCM4XX_JTAG_TMS_GPIO_ELEM(idx, inst) \ + { \ + DT_INST_GPIO_LABEL_BY_IDX(inst, tms_gpios, idx), \ + DT_INST_GPIO_PIN_BY_IDX(inst, tms_gpios, idx), \ + DT_INST_GPIO_FLAGS_BY_IDX(inst, tms_gpios, idx), \ + } + +const struct device *tck_dev = NULL; +const struct device *tdi_dev = NULL; +const struct device *tdo_dev = NULL; +const struct device *tms_dev = NULL; +gpio_pin_t tck_pin = 0; +gpio_pin_t tdi_pin = 0; +gpio_pin_t tdo_pin = 0; +gpio_pin_t tms_pin = 0; + +/* return value: tdo */ +static inline uint8_t jtag_npcm4xx_tck_cycle(uint8_t tms, uint8_t tdi) +{ + gpio_port_value_t ret_tdo; + + /* TCK = 0 */ + gpio_port_clear_bits_raw(tck_dev, BIT(tck_pin)); + gpio_port_set_masked_raw(tdi_dev, BIT(tdi_pin), (tdi << tdi_pin)); + gpio_port_set_masked_raw(tms_dev, BIT(tms_pin), (tms << tms_pin)); + + /* TCK = 1 */ + gpio_port_set_bits_raw(tck_dev, BIT(tck_pin)); + gpio_port_get_raw(tdo_dev, &ret_tdo); + gpio_port_clear_bits_raw(tck_dev, BIT(tck_pin)); + + return ((ret_tdo & BIT(tdo_pin)) >> tdo_pin); +} + +static void jtag_npcm4xx_set_tap_state(enum jtag_npcm4xx_tap_states from, enum jtag_npcm4xx_tap_states to) +{ + uint8_t i; + uint8_t tmsbits; + uint8_t count; + + if (from == to) { + return; + } + if (from == NPCM4XX_TAP_CURRENT_STATE) { + from = gjtag.tap_state; + } + + if (from > NPCM4XX_TAP_CURRENT_STATE || to > NPCM4XX_TAP_CURRENT_STATE) { + return; + } + + /* Reset to Test-Logic Reset state: + * Also notice that in whatever state the TAP controller may be at, + * it will goes back to this state if TMS is set to 1 for 5 consecutive TCK cycles. + */ + if (to == NPCM4XX_TAP_RESET) { + for (i = 0; i < 9; i++) { + jtag_npcm4xx_tck_cycle(1, 0); + } + gjtag.tap_state = NPCM4XX_TAP_RESET; + return; + } + + tmsbits = _tms_cycle_lookup[from][to].tms_bits; + count = _tms_cycle_lookup[from][to].count; + + if (count == 0) { + return; + } + + for (i = 0; i < count; i++) { + jtag_npcm4xx_tck_cycle((tmsbits & 1), 1); + tmsbits >>= 1; + } + + gjtag.tap_state = to; +} + +static enum jtag_npcm4xx_tap_states jtag_npcm4xx_get_tap_state(void) +{ + return gjtag.tap_state; +} + +static void jtag_npcm4xx_xfer_spi(uint32_t out_bytes_len, const uint8_t *out_data, + uint32_t in_byte_len, uint8_t *in_data) +{ + +} + +static void jtag_npcm4xx_xfer_gpio(uint32_t out_bits_len, const uint8_t *out_data, + uint32_t in_bits_len, uint8_t *in_data, uint8_t last_data) +{ + uint32_t bits_len; + uint32_t bits_idx = 0; + uint8_t tdi, tms; + + bits_len = (out_bits_len > in_bits_len) ? out_bits_len : in_bits_len; + + tms = 0; + + /* clear first byte, others bytes will clear in while loop */ + if (in_data) + *in_data = 0x0; + + while (bits_idx < bits_len) { + if (out_bits_len) { + tdi = (*out_data & BIT(bits_idx)) >> bits_idx; + } else { + tdi = 0; + } + + if (bits_idx == bits_len - 1) { /* last bit */ + if (last_data) { + tms = 1; + } + } + + if (in_bits_len) { + *in_data |= (jtag_npcm4xx_tck_cycle(tms, tdi) << bits_idx); + } else { + jtag_npcm4xx_tck_cycle(tms, tdi); + } + + out_bits_len = (out_bits_len) ? (out_bits_len - 1) : 0; + in_bits_len = (in_bits_len) ? (in_bits_len - 1) : 0; + + if (++bits_idx == 8) { + bits_idx = 0; + bits_len -= 8; + out_data++; + if (in_bits_len) { + *(++in_data) = 0; + } + } + } +} + +static void jtag_npcm4xx_readwrite_scan(const struct device *dev, int bits_len, const uint8_t *out_data, + uint8_t *in_data, enum jtag_npcm4xx_tap_states end_state) +{ + const struct jtag_npcm4xx_cfg *config = DEV_CFG(dev); + uint32_t remain_bits = bits_len; + uint32_t spi_xfer_bytes = 0; + + if (config->use_spi) + spi_xfer_bytes = (bits_len / 8) - 1; + + if (spi_xfer_bytes) { + jtag_npcm4xx_xfer_spi(spi_xfer_bytes, out_data, spi_xfer_bytes, in_data); + remain_bits -= spi_xfer_bytes * 8; + } + + if (remain_bits) { + if (end_state != NPCM4XX_TAP_SHIFT_DR && end_state != NPCM4XX_TAP_SHIFT_IR && + end_state != NPCM4XX_TAP_CURRENT_STATE) { + jtag_npcm4xx_xfer_gpio(remain_bits, out_data + spi_xfer_bytes, + remain_bits, in_data + spi_xfer_bytes, 1); + gjtag.tap_state = (gjtag.tap_state == NPCM4XX_TAP_SHIFT_DR) ? + NPCM4XX_TAP_EXIT1_DR : NPCM4XX_TAP_EXIT1_IR; + } else { + jtag_npcm4xx_xfer_gpio(remain_bits, out_data + spi_xfer_bytes, + remain_bits, in_data + spi_xfer_bytes, 0); + } + } + + jtag_npcm4xx_set_tap_state(NPCM4XX_TAP_CURRENT_STATE, end_state); +} + +static void jtag_npcm4xx_ir_scan(const struct device *dev, int bits_len, const uint8_t *out_data, + uint8_t *in_data, enum jtag_npcm4xx_tap_states end_state) +{ + if (bits_len == 0) { + return; + } + + jtag_npcm4xx_set_tap_state(NPCM4XX_TAP_CURRENT_STATE, NPCM4XX_TAP_SHIFT_IR); + + jtag_npcm4xx_readwrite_scan(dev, bits_len, out_data, in_data, end_state); + +} + +static void jtag_npcm4xx_dr_scan(const struct device *dev, int bits_len, const uint8_t *out_data, + uint8_t *in_data, enum jtag_npcm4xx_tap_states end_state) +{ + if (bits_len == 0) { + return; + } + + jtag_npcm4xx_set_tap_state(NPCM4XX_TAP_CURRENT_STATE, NPCM4XX_TAP_SHIFT_DR); + + jtag_npcm4xx_readwrite_scan(dev, bits_len, out_data, in_data, end_state); + +} + +#if 0 +/* ============= (reference) hal for Open BIC ============= */ +void jtag_set_tap(uint8_t data, uint8_t bitlength) +{ + uint8_t tms, index; + + for (index = 0; index < bitlength; index++) { + tms = data & 0x01; + jtag_npcm4xx_tck_cycle(tms, 0); + data = data >> 1; + } +} + +void jtag_shift_data(uint16_t Wbit, uint8_t *Wdate, + uint16_t Rbit, uint8_t *Rdate, + uint8_t lastidx) +{ + jtag_npcm4xx_xfer_gpio(Wbit, Wdate, Rbit, Rdate, lastidx); +} +#endif + +/* implement general function for device API */ + +static enum jtag_npcm4xx_tap_states jtag_npcm4xx_covert_tap_state(enum tap_state state) +{ + enum jtag_npcm4xx_tap_states npcm4xx_state = NPCM4XX_TAP_CURRENT_STATE; + + switch(state) { + case TAP_INVALID: + npcm4xx_state = NPCM4XX_TAP_CURRENT_STATE; + break; + case TAP_DREXIT2: + npcm4xx_state = NPCM4XX_TAP_EXIT2_DR; + break; + case TAP_DREXIT1: + npcm4xx_state = NPCM4XX_TAP_EXIT1_DR; + break; + case TAP_DRSHIFT: + npcm4xx_state = NPCM4XX_TAP_SHIFT_DR; + break; + case TAP_DRPAUSE: + npcm4xx_state = NPCM4XX_TAP_PAUSE_DR; + break; + case TAP_IRSELECT: + npcm4xx_state = NPCM4XX_TAP_SELECT_IR; + break; + case TAP_DRUPDATE: + npcm4xx_state = NPCM4XX_TAP_UPDATE_DR; + break; + case TAP_DRCAPTURE: + npcm4xx_state = NPCM4XX_TAP_CAPTURE_DR; + break; + case TAP_DRSELECT: + npcm4xx_state = NPCM4XX_TAP_SELECT_DR; + break; + case TAP_IREXIT2: + npcm4xx_state = NPCM4XX_TAP_EXIT2_IR; + break; + case TAP_IREXIT1: + npcm4xx_state = NPCM4XX_TAP_EXIT1_IR; + break; + case TAP_IRSHIFT: + npcm4xx_state = NPCM4XX_TAP_SHIFT_IR; + break; + case TAP_IRPAUSE: + npcm4xx_state = NPCM4XX_TAP_PAUSE_IR; + break; + case TAP_IDLE: + npcm4xx_state = NPCM4XX_TAP_IDLE; + break; + case TAP_IRUPDATE: + npcm4xx_state = NPCM4XX_TAP_UPDATE_IR; + break; + case TAP_IRCAPTURE: + npcm4xx_state = NPCM4XX_TAP_CAPTURE_IR; + break; + case TAP_RESET: + npcm4xx_state = NPCM4XX_TAP_RESET; + break; + default: + npcm4xx_state = NPCM4XX_TAP_CURRENT_STATE; + break; + } + + return npcm4xx_state; +} + +static enum tap_state jtag_npcm4xx_covert_npcm4xx_tap_state(enum jtag_npcm4xx_tap_states npcm4xx_tap_state) +{ + enum tap_state state = TAP_INVALID; + + switch(npcm4xx_tap_state) { + case NPCM4XX_TAP_RESET: + state = TAP_RESET; + break; + case NPCM4XX_TAP_IDLE: + state = TAP_IDLE; + break; + case NPCM4XX_TAP_SELECT_DR: + state = TAP_DRSELECT; + break; + case NPCM4XX_TAP_CAPTURE_DR: + state = TAP_DRCAPTURE; + break; + case NPCM4XX_TAP_SHIFT_DR: + state = TAP_DRSHIFT; + break; + case NPCM4XX_TAP_EXIT1_DR: + state = TAP_DREXIT1; + break; + case NPCM4XX_TAP_PAUSE_DR: + state = TAP_DRPAUSE; + break; + case NPCM4XX_TAP_EXIT2_DR: + state = TAP_DREXIT2; + break; + case NPCM4XX_TAP_UPDATE_DR: + state = TAP_DRUPDATE; + break; + case NPCM4XX_TAP_SELECT_IR: + state = TAP_IRSELECT; + break; + case NPCM4XX_TAP_CAPTURE_IR: + state = TAP_IRCAPTURE; + break; + case NPCM4XX_TAP_SHIFT_IR: + state = TAP_IRSHIFT; + break; + case NPCM4XX_TAP_EXIT1_IR: + state = TAP_IREXIT1; + break; + case NPCM4XX_TAP_PAUSE_IR: + state = TAP_IRPAUSE; + break; + case NPCM4XX_TAP_EXIT2_IR: + state = TAP_IREXIT2; + break; + case NPCM4XX_TAP_UPDATE_IR: + state = TAP_IRUPDATE; + break; + default: + state = TAP_INVALID; + break; + } + + return state; +} + +int jtag_npcm4xx_freq_get(const struct device *dev, uint32_t *freq) +{ + return -ENOTSUP; +} + +int jtag_npcm4xx_freq_set(const struct device *dev, uint32_t freq) +{ + return -ENOTSUP; +} + +int jtag_npcm4xx_tap_get(const struct device *dev, enum tap_state *state) +{ + *state = jtag_npcm4xx_covert_npcm4xx_tap_state(jtag_npcm4xx_get_tap_state()); + + return 0; +} + +static int jtag_npcm4xx_tap_set(const struct device *dev, enum tap_state state) +{ + enum jtag_npcm4xx_tap_states end_state = NPCM4XX_TAP_CURRENT_STATE; + + end_state = jtag_npcm4xx_covert_tap_state(state); + + if (end_state == NPCM4XX_TAP_CURRENT_STATE) + return -EINVAL; + + jtag_npcm4xx_set_tap_state(NPCM4XX_TAP_CURRENT_STATE, end_state); + + return 0; +} + +static int jtag_npcm4xx_tck_run(const struct device *dev, uint32_t run_count) +{ + uint32_t i; + uint8_t dummy; + + for (i = 0; i < run_count; i++) + dummy = jtag_npcm4xx_tck_cycle(0, 0); + + return 0; +} + +static int jtag_npcm4xx_xfer(const struct device *dev, struct scan_command_s *scan) +{ + struct scan_field_s *fields; + enum jtag_npcm4xx_tap_states npcm4xx_state = NPCM4XX_TAP_CURRENT_STATE; + + fields = &scan->fields; + + npcm4xx_state = jtag_npcm4xx_covert_tap_state(scan->end_state); + + if (npcm4xx_state == NPCM4XX_TAP_CURRENT_STATE) + return -1; + + if (scan->ir_scan) { + jtag_npcm4xx_ir_scan(dev, fields->num_bits, + fields->out_value, fields->in_value, npcm4xx_state); + } else { + jtag_npcm4xx_dr_scan(dev, fields->num_bits, + fields->out_value, fields->in_value, npcm4xx_state); + } + + return 0; +} + +static int jtag_npcm4xx_sw_xfer(const struct device *dev, enum jtag_pin pin, + uint8_t value) +{ + switch (pin) { + case JTAG_TDI: + gpio_port_set_masked_raw(tdi_dev, BIT(tdi_pin), (value << tdi_pin)); + break; + case JTAG_TCK: + if (value == 0) + gpio_port_clear_bits_raw(tck_dev, BIT(tck_pin)); + else + gpio_port_set_bits_raw(tck_dev, BIT(tck_pin)); + break; + case JTAG_TMS: + gpio_port_set_masked_raw(tms_dev, BIT(tms_pin), (value << tms_pin)); + break; + case JTAG_ENABLE: + default: + return -EINVAL; + } + + return 0; +} + +static int jtag_npcm4xx_tdo_get(const struct device *dev, uint8_t *value) +{ + gpio_port_value_t ret_tdo; + + gpio_port_get_raw(tdo_dev, &ret_tdo); + + *value = (ret_tdo & BIT(tdo_pin)) >> tdo_pin; + + return 0; +} + +static int jtag_npcm4xx_init(const struct device *dev) +{ + const struct jtag_npcm4xx_cfg *config = DEV_CFG(dev); + + gpio_flags_t flags = 0; + + tck_dev = device_get_binding(config->gpio_tck.port); + tck_pin = config->gpio_tck.pin; + + tdi_dev = device_get_binding(config->gpio_tdi.port); + tdi_pin = config->gpio_tdi.pin; + + tdo_dev = device_get_binding(config->gpio_tdo.port); + tdo_pin = config->gpio_tdo.pin; + + tms_dev = device_get_binding(config->gpio_tms.port); + tms_pin = config->gpio_tms.pin; + + /* setup tck */ + flags = GPIO_OUTPUT; + + if (config->gpio_tck.flags & GPIO_ACTIVE_LOW) + flags |= GPIO_OUTPUT_INIT_HIGH; + else + flags |= GPIO_OUTPUT_INIT_LOW; + + if (config->gpio_tck.flags & GPIO_OPEN_DRAIN) + flags |= GPIO_OPEN_DRAIN; + else + flags |= GPIO_PUSH_PULL; + + gpio_pin_configure(tck_dev, tck_pin, flags); + + /* setup tdi */ + flags = GPIO_OUTPUT; + + if (config->gpio_tdi.flags & GPIO_ACTIVE_LOW) + flags |= GPIO_OUTPUT_INIT_HIGH; + else + flags |= GPIO_OUTPUT_INIT_LOW; + + if (config->gpio_tdi.flags & GPIO_OPEN_DRAIN) + flags |= GPIO_OPEN_DRAIN; + else + flags |= GPIO_PUSH_PULL; + + gpio_pin_configure(tdi_dev, tdi_pin, flags); + + /* setup tdo */ + flags = GPIO_INPUT; + + if (config->gpio_tdo.flags & GPIO_ACTIVE_LOW) + flags |= GPIO_OUTPUT_INIT_HIGH; + else + flags |= GPIO_OUTPUT_INIT_LOW; + + gpio_pin_configure(tdo_dev, tdo_pin, flags); + + /* setup tms */ + flags = GPIO_OUTPUT; + + if (config->gpio_tms.flags & GPIO_ACTIVE_LOW) + flags |= GPIO_OUTPUT_INIT_HIGH; + else + flags |= GPIO_OUTPUT_INIT_LOW; + + if (config->gpio_tms.flags & GPIO_OPEN_DRAIN) + flags |= GPIO_OPEN_DRAIN; + else + flags |= GPIO_PUSH_PULL; + + gpio_pin_configure(tms_dev, tms_pin, flags); + + LOG_INF("TCK = %s PIN = %d", tck_dev->name, tck_pin); + LOG_INF("TDI = %s PIN = %d", tdi_dev->name, tdi_pin); + LOG_INF("TDO = %s PIN = %d", tdo_dev->name, tdo_pin); + LOG_INF("TMS = %s PIN = %d", tms_dev->name, tms_pin); + + /* Test-Logic Reset state */ + gjtag.tap_state = NPCM4XX_TAP_RESET; + + return 0; +} + +static struct jtag_driver_api jtag_npcm4xx_api = { + .freq_get = jtag_npcm4xx_freq_get, + .freq_set = jtag_npcm4xx_freq_set, + .tap_get = jtag_npcm4xx_tap_get, + .tap_set = jtag_npcm4xx_tap_set, + .tck_run = jtag_npcm4xx_tck_run, + .xfer = jtag_npcm4xx_xfer, + .sw_xfer = jtag_npcm4xx_sw_xfer, + .tdo_get = jtag_npcm4xx_tdo_get, +}; + +#define NPCM4XX_JTAG_INIT(n) \ + static const struct jtag_npcm4xx_cfg jtag_npcm4xx_cfg_##n = { \ + .use_spi = DT_INST_PROP(n, use_spi), \ + .gpio_tck = UTIL_LISTIFY(DT_INST_PROP_LEN(n, tck_gpios), NPCM4XX_JTAG_TCK_GPIO_ELEM, n), \ + .gpio_tdi = UTIL_LISTIFY(DT_INST_PROP_LEN(n, tdi_gpios), NPCM4XX_JTAG_TDI_GPIO_ELEM, n), \ + .gpio_tdo = UTIL_LISTIFY(DT_INST_PROP_LEN(n, tdo_gpios), NPCM4XX_JTAG_TDO_GPIO_ELEM, n), \ + .gpio_tms = UTIL_LISTIFY(DT_INST_PROP_LEN(n, tms_gpios), NPCM4XX_JTAG_TMS_GPIO_ELEM, n), \ + }; \ + DEVICE_DT_INST_DEFINE(n, jtag_npcm4xx_init, NULL, \ + NULL, &jtag_npcm4xx_cfg_##n, \ + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &jtag_npcm4xx_api); + +DT_INST_FOREACH_STATUS_OKAY(NPCM4XX_JTAG_INIT) diff --git a/drivers/jtag/jtag_npcm4xx.h b/drivers/jtag/jtag_npcm4xx.h new file mode 100644 index 00000000000000..936a36b4f6b5e5 --- /dev/null +++ b/drivers/jtag/jtag_npcm4xx.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2023 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _JTAG_MASTER_H_ +#define _JTAG_MASTER_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum jtag_npcm4xx_tap_states { + NPCM4XX_TAP_RESET, /* 0: Test-Logic Reset */ + NPCM4XX_TAP_IDLE, /* 1: Run-Test/ Idle */ + + NPCM4XX_TAP_SELECT_DR, /* 2: Select-DR/ Scan */ + NPCM4XX_TAP_CAPTURE_DR, /* 3: Capture-DR */ + NPCM4XX_TAP_SHIFT_DR, /* 4: Shift-DR */ + NPCM4XX_TAP_EXIT1_DR, /* 5: Exit1-DR */ + NPCM4XX_TAP_PAUSE_DR, /* 6: Pause-DR */ + NPCM4XX_TAP_EXIT2_DR, /* 7: Exit2-DR */ + NPCM4XX_TAP_UPDATE_DR, /* 8: Update-DR */ + + NPCM4XX_TAP_SELECT_IR, /* 9: Select-IR/ Scan */ + NPCM4XX_TAP_CAPTURE_IR, /* 10: Capture-IR */ + NPCM4XX_TAP_SHIFT_IR, /* 11: Shift-IR */ + NPCM4XX_TAP_EXIT1_IR, /* 12: Exit1-IR */ + NPCM4XX_TAP_PAUSE_IR, /* 13: Pause-IR */ + NPCM4XX_TAP_EXIT2_IR, /* 14: Exit2-IR */ + NPCM4XX_TAP_UPDATE_IR, /* 15: Update-IR */ + + NPCM4XX_TAP_CURRENT_STATE +}; + +/* this structure represents a TMS cycle, as expressed in a set of bits and + * a count of bits (note: there are no start->end state transitions that + * require more than 1 byte of TMS cycles) + */ +struct tms_cycle { + uint8_t tms_bits; + uint8_t count; +}; + +/* this is the complete set TMS cycles for going from any TAP state to + * any other TAP state, following a 。ァshortest path。ィ rule + */ +const struct tms_cycle _tms_cycle_lookup[][16] = { +/* RESET IDLE SELECT_DR CAPTURE_DR SHIFT_DR */ +/* EXIT1_DR PAUSE_DR EXIT2_DR UPDATE_DR SELECT_IR */ +/* CAPTURE_IR SHIFT_IR EXIT1_IR PAUSE_IR EXIT2_IR */ +/* UPDATE_IR */ +/* RESET */ + { + { 0x01, 1 }, { 0x00, 1 }, { 0x02, 2 }, { 0x02, 3 }, { 0x02, 4 }, + { 0x0a, 4 }, { 0x0a, 5 }, { 0x2a, 6 }, { 0x1a, 5 }, { 0x06, 3 }, + { 0x06, 4 }, { 0x06, 5 }, { 0x16, 5 }, { 0x16, 6 }, { 0x56, 7 }, + { 0x36, 6 } + }, +/* IDLE */ + { + { 0x07, 3 }, { 0x00, 1 }, { 0x01, 1 }, { 0x01, 2 }, { 0x01, 3 }, + { 0x05, 3 }, { 0x05, 4 }, { 0x15, 5 }, { 0x0d, 4 }, { 0x03, 2 }, + { 0x03, 3 }, { 0x03, 4 }, { 0x0b, 4 }, { 0x0b, 5 }, { 0x2b, 6 }, + { 0x1b, 5 } + }, +/* SELECT_DR */ + { + { 0x03, 2 }, { 0x03, 3 }, { 0x00, 0 }, { 0x00, 1 }, { 0x00, 2 }, + { 0x02, 2 }, { 0x02, 3 }, { 0x0a, 4 }, { 0x06, 3 }, { 0x01, 1 }, + { 0x01, 2 }, { 0x01, 3 }, { 0x05, 3 }, { 0x05, 4 }, { 0x15, 5 }, + { 0x0d, 4 } + }, +/* CAPTURE_DR */ + { + { 0x1f, 5 }, { 0x03, 3 }, { 0x07, 3 }, { 0x00, 0 }, { 0x00, 1 }, + { 0x01, 1 }, { 0x01, 2 }, { 0x05, 3 }, { 0x03, 2 }, { 0x0f, 4 }, + { 0x0f, 5 }, { 0x0f, 6 }, { 0x2f, 6 }, { 0x2f, 7 }, { 0xaf, 8 }, + { 0x6f, 7 } + }, +/* SHIFT_DR */ + { + { 0x1f, 5 }, { 0x03, 3 }, { 0x07, 3 }, { 0x07, 4 }, { 0x00, 0 }, + { 0x01, 1 }, { 0x01, 2 }, { 0x05, 3 }, { 0x03, 2 }, { 0x0f, 4 }, + { 0x0f, 5 }, { 0x0f, 6 }, { 0x2f, 6 }, { 0x2f, 7 }, { 0xaf, 8 }, + { 0x6f, 7 } + }, +/* EXIT1_DR */ + { + { 0x0f, 4 }, { 0x01, 2 }, { 0x03, 2 }, { 0x03, 3 }, { 0x02, 3 }, + { 0x00, 0 }, { 0x00, 1 }, { 0x02, 2 }, { 0x01, 1 }, { 0x07, 3 }, + { 0x07, 4 }, { 0x07, 5 }, { 0x17, 5 }, { 0x17, 6 }, { 0x57, 7 }, + { 0x37, 6 } + }, +/* PAUSE_DR */ + { + { 0x1f, 5 }, { 0x03, 3 }, { 0x07, 3 }, { 0x07, 4 }, { 0x01, 2 }, + { 0x05, 3 }, { 0x00, 1 }, { 0x01, 1 }, { 0x03, 2 }, { 0x0f, 4 }, + { 0x0f, 5 }, { 0x0f, 6 }, { 0x2f, 6 }, { 0x2f, 7 }, { 0xaf, 8 }, + { 0x6f, 7 } + }, +/* EXIT2_DR */ + { + { 0x0f, 4 }, { 0x01, 2 }, { 0x03, 2 }, { 0x03, 3 }, { 0x00, 1 }, + { 0x02, 2 }, { 0x02, 3 }, { 0x00, 0 }, { 0x01, 1 }, { 0x07, 3 }, + { 0x07, 4 }, { 0x07, 5 }, { 0x17, 5 }, { 0x17, 6 }, { 0x57, 7 }, + { 0x37, 6 } + }, +/* UPDATE_DR */ + { + { 0x07, 3 }, { 0x00, 1 }, { 0x01, 1 }, { 0x01, 2 }, { 0x01, 3 }, + { 0x05, 3 }, { 0x05, 4 }, { 0x15, 5 }, { 0x00, 0 }, { 0x03, 2 }, + { 0x03, 3 }, { 0x03, 4 }, { 0x0b, 4 }, { 0x0b, 5 }, { 0x2b, 6 }, + { 0x1b, 5 } + }, +/* SELECT_IR */ + { + { 0x01, 1 }, { 0x01, 2 }, { 0x05, 3 }, { 0x05, 4 }, { 0x05, 5 }, + { 0x15, 5 }, { 0x15, 6 }, { 0x55, 7 }, { 0x35, 6 }, { 0x00, 0 }, + { 0x00, 1 }, { 0x00, 2 }, { 0x02, 2 }, { 0x02, 3 }, { 0x0a, 4 }, + { 0x06, 3 } + }, +/* CAPTURE_IR */ + { + { 0x1f, 5 }, { 0x03, 3 }, { 0x07, 3 }, { 0x07, 4 }, { 0x07, 5 }, + { 0x17, 5 }, { 0x17, 6 }, { 0x57, 7 }, { 0x37, 6 }, { 0x0f, 4 }, + { 0x00, 0 }, { 0x00, 1 }, { 0x01, 1 }, { 0x01, 2 }, { 0x05, 3 }, + { 0x03, 2 } + }, +/* SHIFT_IR */ + { + { 0x1f, 5 }, { 0x03, 3 }, { 0x07, 3 }, { 0x07, 4 }, { 0x07, 5 }, + { 0x17, 5 }, { 0x17, 6 }, { 0x57, 7 }, { 0x37, 6 }, { 0x0f, 4 }, + { 0x0f, 5 }, { 0x00, 0 }, { 0x01, 1 }, { 0x01, 2 }, { 0x05, 3 }, + { 0x03, 2 } + }, +/* EXIT1_IR */ + { + { 0x0f, 4 }, { 0x01, 2 }, { 0x03, 2 }, { 0x03, 3 }, { 0x03, 4 }, + { 0x0b, 4 }, { 0x0b, 5 }, { 0x2b, 6 }, { 0x1b, 5 }, { 0x07, 3 }, + { 0x07, 4 }, { 0x02, 3 }, { 0x00, 0 }, { 0x00, 1 }, { 0x02, 2 }, + { 0x01, 1 } + }, +/* PAUSE_IR */ + { + { 0x1f, 5 }, { 0x03, 3 }, { 0x07, 3 }, { 0x07, 4 }, { 0x07, 5 }, + { 0x17, 5 }, { 0x17, 6 }, { 0x57, 7 }, { 0x37, 6 }, { 0x0f, 4 }, + { 0x0f, 5 }, { 0x01, 2 }, { 0x05, 3 }, { 0x00, 1 }, { 0x01, 1 }, + { 0x03, 2 } + }, +/* EXIT2_IR */ + { + { 0x0f, 4 }, { 0x01, 2 }, { 0x03, 2 }, { 0x03, 3 }, { 0x03, 4 }, + { 0x0b, 4 }, { 0x0b, 5 }, { 0x2b, 6 }, { 0x1b, 5 }, { 0x07, 3 }, + { 0x07, 4 }, { 0x00, 1 }, { 0x02, 2 }, { 0x02, 3 }, { 0x00, 0 }, + { 0x01, 1 } + }, +/* UPDATE_IR */ + { + { 0x07, 3 }, { 0x00, 1 }, { 0x01, 1 }, { 0x01, 2 }, { 0x01, 3 }, + { 0x05, 3 }, { 0x05, 4 }, { 0x15, 5 }, { 0x0d, 4 }, { 0x03, 2 }, + { 0x03, 3 }, { 0x03, 4 }, { 0x0b, 4 }, { 0x0b, 5 }, { 0x2b, 6 }, + { 0x00, 0 } + }, +}; + +#ifdef __cplusplus +} +#endif + + +#endif /* _JTAG_MASTER_H_ */ diff --git a/drivers/jtag/jtag_shell.c b/drivers/jtag/jtag_shell.c new file mode 100644 index 00000000000000..3a998ee86ab9b4 --- /dev/null +++ b/drivers/jtag/jtag_shell.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2021 ASPEED + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief JTAG shell commands. + */ + +#include +#include +#include + +#define JTAG_DEVICE_PREFIX "JTAG" + +static uint8_t tdi_buffer[512]; + +static int cmd_ir_scan(const struct shell *shell, size_t argc, char **argv) +{ + const struct device *dev; + uint32_t bit_len, byte_len; + uint32_t value; + int err, index; + + dev = device_get_binding(argv[-1]); + if (!dev) { + shell_error(shell, "JTAG device not found"); + return -EINVAL; + } + + bit_len = strtoul(argv[1], NULL, 0); + value = strtoul(argv[2], NULL, 16); + + err = jtag_ir_scan(dev, bit_len, (uint8_t *)&value, tdi_buffer, + TAP_IDLE); + if (err) { + shell_error(shell, "failed to IR scan (err %d)", err); + return err; + } + byte_len = (bit_len + 7) >> 3; + for (index = byte_len - 1; index >= 0; index--) { + shell_print(shell, "%x", tdi_buffer[index]); + } + return 0; +} + +static int cmd_dr_scan(const struct shell *shell, size_t argc, char **argv) +{ + const struct device *dev; + uint32_t bit_len, byte_len; + uint32_t value; + int err, index; + + dev = device_get_binding(argv[-1]); + if (!dev) { + shell_error(shell, "JTAG device not found"); + return -EINVAL; + } + + bit_len = strtoul(argv[1], NULL, 0); + value = strtoul(argv[2], NULL, 16); + + err = jtag_dr_scan(dev, bit_len, (uint8_t *)&value, tdi_buffer, + TAP_IDLE); + if (err) { + shell_error(shell, "failed to DR scan (err %d)", err); + return err; + } + byte_len = (bit_len + 7) >> 3; + for (index = byte_len - 1; index >= 0; index--) { + shell_print(shell, "%x", tdi_buffer[index]); + } + return 0; +} + +static int cmd_frequency(const struct shell *shell, size_t argc, char **argv) +{ + const struct device *dev; + uint32_t freq; + int err; + + dev = device_get_binding(argv[-1]); + if (!dev) { + shell_error(shell, "JTAG device not found"); + return -EINVAL; + } + + freq = strtoul(argv[1], NULL, 0); + + err = jtag_freq_set(dev, freq); + if (err) { + shell_error(shell, "failed to setup JTAG frequency(err %d)", + err); + return err; + } + err = jtag_freq_get(dev, &freq); + if (err) { + shell_error(shell, "failed to get JTAG frequency (err %d)", + err); + return err; + } + shell_print(shell, "%d\n", freq); + + return 0; +} + +static int cmd_tap_state(const struct shell *shell, size_t argc, char **argv, void *data) +{ + const struct device *dev; + enum tap_state state = (enum tap_state) data; + int err; + + dev = device_get_binding(argv[-2]); + if (!dev) { + shell_error(shell, "JTAG device not found"); + return -EINVAL; + } + + err = jtag_tap_set(dev, state); + if (err) { + shell_error(shell, "failed to set JTAG tap_state to %d(err %d)", + state, err); + return err; + } + + return 0; +} + +static int cmd_sw_xfer(const struct shell *shell, size_t argc, char **argv, void *data) +{ + const struct device *dev; + enum jtag_pin pin = (enum jtag_pin) data; + uint8_t value; + int err; + + dev = device_get_binding(argv[-3]); + if (!dev) { + shell_error(shell, "JTAG device not found"); + return -EINVAL; + } + value = strcmp("high", argv[-1]) ? 0 : 1; + + err = jtag_sw_xfer(dev, pin, value); + if (err) { + shell_error(shell, "failed to transfer pin%d = %d(err %d)", + pin, value, err); + return err; + } + + return 0; +} + +SHELL_SUBCMD_DICT_SET_CREATE(sub_tap_cmds, cmd_tap_state, + (DREXIT2, TAP_DREXIT2), + (DREXIT1, TAP_DREXIT1), + (DRSHIFT, TAP_DRSHIFT), + (DRPAUSE, TAP_DRPAUSE), + (IRSELECT, TAP_IRSELECT), + (DRUPDATE, TAP_DRUPDATE), + (DRCAPTURE, TAP_DRCAPTURE), + (DRSELECT, TAP_DRSELECT), + (IREXIT2, TAP_IREXIT2), + (IREXIT1, TAP_IREXIT1), + (IRSHIFT, TAP_IRSHIFT), + (IRPAUSE, TAP_IRPAUSE), + (IDLE, TAP_IDLE), + (IRUPDATE, TAP_IRUPDATE), + (IRCAPTURE, TAP_IRCAPTURE), + (RESET, TAP_RESET) +); + +SHELL_SUBCMD_DICT_SET_CREATE(sub_pin_cmds, cmd_sw_xfer, + (TDI, JTAG_TDI), + (TCK, JTAG_TCK), + (TMS, JTAG_TMS), + (TRST, JTAG_TRST) +); + +SHELL_STATIC_SUBCMD_SET_CREATE(sub_action_cmds, + SHELL_CMD(high, &sub_pin_cmds, "", NULL), + SHELL_CMD(low, &sub_pin_cmds, "", NULL), + SHELL_SUBCMD_SET_END +); + +SHELL_STATIC_SUBCMD_SET_CREATE( + sub_jtag_cmds, + SHELL_CMD_ARG(frequency, NULL, "", cmd_frequency, 2, + 0), + SHELL_CMD_ARG(ir_scan, NULL, " ", cmd_ir_scan, 3, + 0), + SHELL_CMD_ARG(dr_scan, NULL, " ", cmd_dr_scan, 3, + 0), + SHELL_CMD(tap_set, &sub_tap_cmds, "", NULL), + SHELL_CMD(sw_xfer, &sub_action_cmds, " ", NULL), + SHELL_SUBCMD_SET_END); + +static void cmd_jtag_dev_get(size_t idx, struct shell_static_entry *entry) +{ + const struct device *dev = shell_device_lookup(idx, JTAG_DEVICE_PREFIX); + + entry->syntax = (dev != NULL) ? dev->name : NULL; + entry->handler = NULL; + entry->help = "Select JTAG device for subcommand.\n"; + entry->subcmd = &sub_jtag_cmds; +} +SHELL_DYNAMIC_CMD_CREATE(sub_jtag_dev, cmd_jtag_dev_get); + +SHELL_CMD_REGISTER(jtag, &sub_jtag_dev, "JTAG shell commands", NULL); diff --git a/dts/arm/nuvoton/npcm4xx.dtsi b/dts/arm/nuvoton/npcm4xx.dtsi index ef1a6754569efa..1e710f47ae1a0a 100644 --- a/dts/arm/nuvoton/npcm4xx.dtsi +++ b/dts/arm/nuvoton/npcm4xx.dtsi @@ -497,6 +497,13 @@ }; }; + jtag1: jtag1 { + compatible = "nuvoton,npcm4xx-jtag"; + label = "JTAG1"; + use-spi = <0>; + status = "disabled"; + }; + }; soc-if { diff --git a/dts/bindings/jtag/nuvoton,npcm4xx-jtag.yaml b/dts/bindings/jtag/nuvoton,npcm4xx-jtag.yaml new file mode 100644 index 00000000000000..db3f671db71c83 --- /dev/null +++ b/dts/bindings/jtag/nuvoton,npcm4xx-jtag.yaml @@ -0,0 +1,32 @@ +description: NPCM4XX family JTAG + +compatible: "nuvoton,npcm4xx-jtag" + +include: base.yaml + +properties: + use-spi: + type: int + required: true + description: | + Use spi pins to service jtag signal. + tck-gpios: + type: phandle-array + required: true + description: | + Use to service jtag tck signal. + tdi-gpios: + type: phandle-array + required: true + description: | + Use to service jtag tdi signal. + tdo-gpios: + type: phandle-array + required: true + description: | + Use to service jtag tdo signal. + tms-gpios: + type: phandle-array + required: true + description: | + Use to service jtag tms signal. diff --git a/include/drivers/jtag.h b/include/drivers/jtag.h new file mode 100644 index 00000000000000..b85d0261d556c6 --- /dev/null +++ b/include/drivers/jtag.h @@ -0,0 +1,288 @@ +/** + * @file + * @brief JTAG public API header file. + */ + +/* + * Copyright (c) 2023 Zephyr OpenBIC Framework. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_JTAG_H_ +#define ZEPHYR_INCLUDE_DRIVERS_JTAG_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief JTAG driver APIs + * @{ + */ + +/** + * Defines JTAG Test Access Port states. + * + * These definitions were gleaned from the ARM7TDMI-S Technical + * Reference Manual and validated against several other ARM core + * technical manuals. + * + * FIXME some interfaces require specific numbers be used, as they + * are handed-off directly to their hardware implementations. + * Fix those drivers to map as appropriate ... then pick some + * sane set of numbers here (where 0/uninitialized == INVALID). + */ +enum tap_state { + TAP_INVALID = -1, + /* Proper ARM recommended numbers */ + TAP_DREXIT2 = 0x0, + TAP_DREXIT1 = 0x1, + TAP_DRSHIFT = 0x2, + TAP_DRPAUSE = 0x3, + TAP_IRSELECT = 0x4, + TAP_DRUPDATE = 0x5, + TAP_DRCAPTURE = 0x6, + TAP_DRSELECT = 0x7, + TAP_IREXIT2 = 0x8, + TAP_IREXIT1 = 0x9, + TAP_IRSHIFT = 0xa, + TAP_IRPAUSE = 0xb, + TAP_IDLE = 0xc, + TAP_IRUPDATE = 0xd, + TAP_IRCAPTURE = 0xe, + TAP_RESET = 0x0f, +}; + +enum jtag_pin { + JTAG_TDI = 0x01, + JTAG_TCK = 0x02, + JTAG_TMS = 0x04, + JTAG_ENABLE = 0x08, + JTAG_TRST = 0x10, +}; + +/** + * This structure defines a single scan field in the scan. It provides + * fields for the field's width and pointers to scan input and output + * values. + */ +struct scan_field_s { + /** The number of bits this field specifies */ + int num_bits; + /** A pointer to value to be scanned into the device */ + const uint8_t *out_value; + /** A pointer to a 32-bit memory location for data scanned out */ + uint8_t *in_value; +}; + +/** + * The scan_command provide a means of encapsulating a set of scan_field_s + * structures that should be scanned in/out to the device. + */ +struct scan_command_s { + /** instruction/not data scan */ + bool ir_scan; + /** data scan fields */ + struct scan_field_s fields; + /** state in which JTAG commands should finish */ + enum tap_state end_state; +}; + +/** + * @brief Type definition of ADC API function for getting frequency. + * See jtag_freq_get() for argument descriptions. + */ +typedef int (*jtag_api_freq_get)(const struct device *dev, uint32_t *freq); + +/** + * @brief Type definition of ADC API function for setting frequency. + * See jtag_freq_set() for argument descriptions. + */ +typedef int (*jtag_api_freq_set)(const struct device *dev, uint32_t freq); + +/** + * @brief Type definition of JTAG API function for setting tap state. + * See jtag_tap_set() for argument descriptions. + */ +typedef int (*jtag_api_tap_set)(const struct device *dev, enum tap_state state); + +/** + * @brief Type definition of JTAG API function for getting tap state. + * See jtag_tap_get() for argument descriptions. + */ +typedef int (*jtag_api_tap_get)(const struct device *dev, + enum tap_state *state); + +/** + * @brief Type definition of JTAG API function for running tck cycles. + * See jtag_tck_run() for argument descriptions. + */ +typedef int (*jtag_api_tck_run)(const struct device *dev, uint32_t run_count); + +/** + * @brief Type definition of JTAG API function for scanning. + */ +typedef int (*jtag_api_xfer)(const struct device *dev, + struct scan_command_s *scan); + +/** + * @brief Type definition of JTAG API function for software mode. + */ +typedef int (*jtag_api_sw_xfer)(const struct device *dev, enum jtag_pin pin, + uint8_t value); + +/** + * @brief Type definition of JTAG API function for getting tdo value. + */ +typedef int (*jtag_api_tdo_get)(const struct device *dev, uint8_t *value); + + +/** + * @brief JTAG driver API + * + * This is the mandatory API any JTAG driver needs to expose. + */ +__subsystem struct jtag_driver_api { + jtag_api_freq_get freq_get; + jtag_api_freq_set freq_set; + jtag_api_tap_get tap_get; + jtag_api_tap_set tap_set; + jtag_api_tck_run tck_run; + jtag_api_xfer xfer; + jtag_api_sw_xfer sw_xfer; + jtag_api_tdo_get tdo_get; +}; + +__syscall int jtag_freq_get(const struct device *dev, uint32_t *freq); + +static inline int z_impl_jtag_freq_get(const struct device *dev, uint32_t *freq) +{ + const struct jtag_driver_api *api = + (const struct jtag_driver_api *)dev->api; + + return api->freq_get(dev, freq); +} + +__syscall int jtag_freq_set(const struct device *dev, uint32_t freq); + +static inline int z_impl_jtag_freq_set(const struct device *dev, uint32_t freq) +{ + const struct jtag_driver_api *api = + (const struct jtag_driver_api *)dev->api; + + return api->freq_set(dev, freq); +} + +__syscall int jtag_tap_get(const struct device *dev, enum tap_state *state); + +static inline int z_impl_jtag_tap_get(const struct device *dev, + enum tap_state *state) +{ + const struct jtag_driver_api *api = + (const struct jtag_driver_api *)dev->api; + + return api->tap_get(dev, state); +} + +__syscall int jtag_tap_set(const struct device *dev, enum tap_state state); + +static inline int z_impl_jtag_tap_set(const struct device *dev, + enum tap_state state) +{ + const struct jtag_driver_api *api = + (const struct jtag_driver_api *)dev->api; + + return api->tap_set(dev, state); +} + +__syscall int jtag_tck_run(const struct device *dev, uint32_t run_count); + +static inline int z_impl_jtag_tck_run(const struct device *dev, + uint32_t run_count) +{ + const struct jtag_driver_api *api = + (const struct jtag_driver_api *)dev->api; + + return api->tck_run(dev, run_count); +} + +__syscall int jtag_ir_scan(const struct device *dev, int num_bits, + const uint8_t *out_value, uint8_t *in_value, + enum tap_state state); + +static inline int z_impl_jtag_ir_scan(const struct device *dev, int num_bits, + const uint8_t *out_value, + uint8_t *in_value, enum tap_state state) +{ + const struct jtag_driver_api *api = + (const struct jtag_driver_api *)dev->api; + + struct scan_command_s scan; + + scan.ir_scan = 1; + scan.end_state = state; + scan.fields.num_bits = num_bits; + scan.fields.out_value = out_value; + scan.fields.in_value = in_value; + + return api->xfer(dev, &scan); +} + +__syscall int jtag_dr_scan(const struct device *dev, int num_bits, + const uint8_t *out_value, uint8_t *in_value, + enum tap_state state); + +static inline int z_impl_jtag_dr_scan(const struct device *dev, int num_bits, + const uint8_t *out_value, + uint8_t *in_value, enum tap_state state) +{ + const struct jtag_driver_api *api = + (const struct jtag_driver_api *)dev->api; + + struct scan_command_s scan; + + scan.ir_scan = 0; + scan.end_state = state; + scan.fields.num_bits = num_bits; + scan.fields.out_value = out_value; + scan.fields.in_value = in_value; + + return api->xfer(dev, &scan); +} + +__syscall int jtag_sw_xfer(const struct device *dev, enum jtag_pin pin, + uint8_t value); + +static inline int z_impl_jtag_sw_xfer(const struct device *dev, enum jtag_pin pin, + uint8_t value) +{ + const struct jtag_driver_api *api = + (const struct jtag_driver_api *)dev->api; + + return api->sw_xfer(dev, pin, value); +} + +__syscall int jtag_tdo_get(const struct device *dev, uint8_t *value); + +static inline int z_impl_jtag_tdo_get(const struct device *dev, uint8_t *value) +{ + const struct jtag_driver_api *api = + (const struct jtag_driver_api *)dev->api; + + return api->tdo_get(dev, value); +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include + +#endif /* ZEPHYR_INCLUDE_DRIVERS_JTAG_H_ */ diff --git a/soc/arm/npcm4xx/npcm400f/CMakeLists.txt b/soc/arm/npcm4xx/npcm400f/CMakeLists.txt index 7e40a277ca5b11..ef311a1be7c1c3 100644 --- a/soc/arm/npcm4xx/npcm400f/CMakeLists.txt +++ b/soc/arm/npcm4xx/npcm400f/CMakeLists.txt @@ -5,5 +5,4 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_sources( soc.c gdma.c - jtag_master.c ) diff --git a/soc/arm/npcm4xx/npcm400f/jtag_master.c b/soc/arm/npcm4xx/npcm400f/jtag_master.c deleted file mode 100644 index c0c29d09b08776..00000000000000 --- a/soc/arm/npcm4xx/npcm400f/jtag_master.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright (c) 2023 Nuvoton Technology Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "jtag_master.h" -#include - -/* ----------------------- Configuration -------------------------------*/ -/* 0: not using SPI, 1: using SPI */ -#define CONFIG_USE_SPI 0 - -#if (CONFIG_USE_SPI == 1) -/* SPI_CLK */ - #define CONFIG_TCK_DEV DT_LABEL(DT_NODELABEL(gpio6)) - #define CONFIG_TCK_PIN 6 - #define CONFIG_TCK_FLAG (GPIO_OUTPUT | GPIO_PUSH_PULL | GPIO_OUTPUT_INIT_LOW) - -/* SPI_MOSI */ - #define CONFIG_TDI_DEV DT_LABEL(DT_NODELABEL(gpio6)) - #define CONFIG_TDI_PIN 7 - #define CONFIG_TDI_FLAG (GPIO_OUTPUT | GPIO_PUSH_PULL | GPIO_OUTPUT_INIT_LOW) - -/* SPI_MISO */ - #define CONFIG_TDO_DEV DT_LABEL(DT_NODELABEL(gpio7)) - #define CONFIG_TDO_PIN 0 - #define CONFIG_TDO_FLAG (GPIO_INPUT) - -/* SPI_CS */ - #define CONFIG_TMS_DEV DT_LABEL(DT_NODELABEL(gpio7)) - #define CONFIG_TMS_PIN 3 - #define CONFIG_TMS_FLAG (GPIO_OUTPUT | GPIO_PUSH_PULL | GPIO_OUTPUT_INIT_LOW) -#else - #define CONFIG_TCK_DEV DT_LABEL(DT_NODELABEL(gpio6)) - #define CONFIG_TCK_PIN 6 - #define CONFIG_TCK_FLAG (GPIO_OUTPUT | GPIO_PUSH_PULL | GPIO_OUTPUT_INIT_LOW) - - #define CONFIG_TDI_DEV DT_LABEL(DT_NODELABEL(gpio6)) - #define CONFIG_TDI_PIN 7 - #define CONFIG_TDI_FLAG (GPIO_OUTPUT | GPIO_PUSH_PULL | GPIO_OUTPUT_INIT_LOW) - - #define CONFIG_TDO_DEV DT_LABEL(DT_NODELABEL(gpio7)) - #define CONFIG_TDO_PIN 0 - #define CONFIG_TDO_FLAG (GPIO_INPUT) - - #define CONFIG_TMS_DEV DT_LABEL(DT_NODELABEL(gpio7)) - #define CONFIG_TMS_PIN 3 - #define CONFIG_TMS_FLAG (GPIO_OUTPUT | GPIO_PUSH_PULL | GPIO_OUTPUT_INIT_LOW) -#endif -/* ---------------------------------------------------------------------*/ - -struct jtag_info { - uint8_t tap_state; -}; - -static struct jtag_info gjtag; - -/* this structure represents a TMS cycle, as expressed in a set of bits and - * a count of bits (note: there are no start->end state transitions that - * require more than 1 byte of TMS cycles) - */ -struct tms_cycle { - uint8_t tms_bits; - uint8_t count; -}; - -/* this is the complete set TMS cycles for going from any TAP state to - * any other TAP state, following a “shortest path” rule - */ -const struct tms_cycle _tms_cycle_lookup[][16] = { -/* RESET IDLE SELECT_DR CAPTURE_DR SHIFT_DR */ -/* EXIT1_DR PAUSE_DR EXIT2_DR UPDATE_DR SELECT_IR */ -/* CAPTURE_IR SHIFT_IR EXIT1_IR PAUSE_IR EXIT2_IR */ -/* UPDATE_IR */ -/* RESET */ - { - { 0x01, 1 }, { 0x00, 1 }, { 0x02, 2 }, { 0x02, 3 }, { 0x02, 4 }, - { 0x0a, 4 }, { 0x0a, 5 }, { 0x2a, 6 }, { 0x1a, 5 }, { 0x06, 3 }, - { 0x06, 4 }, { 0x06, 5 }, { 0x16, 5 }, { 0x16, 6 }, { 0x56, 7 }, - { 0x36, 6 } - }, -/* IDLE */ - { - { 0x07, 3 }, { 0x00, 1 }, { 0x01, 1 }, { 0x01, 2 }, { 0x01, 3 }, - { 0x05, 3 }, { 0x05, 4 }, { 0x15, 5 }, { 0x0d, 4 }, { 0x03, 2 }, - { 0x03, 3 }, { 0x03, 4 }, { 0x0b, 4 }, { 0x0b, 5 }, { 0x2b, 6 }, - { 0x1b, 5 } - }, -/* SELECT_DR */ - { - { 0x03, 2 }, { 0x03, 3 }, { 0x00, 0 }, { 0x00, 1 }, { 0x00, 2 }, - { 0x02, 2 }, { 0x02, 3 }, { 0x0a, 4 }, { 0x06, 3 }, { 0x01, 1 }, - { 0x01, 2 }, { 0x01, 3 }, { 0x05, 3 }, { 0x05, 4 }, { 0x15, 5 }, - { 0x0d, 4 } - }, -/* CAPTURE_DR */ - { - { 0x1f, 5 }, { 0x03, 3 }, { 0x07, 3 }, { 0x00, 0 }, { 0x00, 1 }, - { 0x01, 1 }, { 0x01, 2 }, { 0x05, 3 }, { 0x03, 2 }, { 0x0f, 4 }, - { 0x0f, 5 }, { 0x0f, 6 }, { 0x2f, 6 }, { 0x2f, 7 }, { 0xaf, 8 }, - { 0x6f, 7 } - }, -/* SHIFT_DR */ - { - { 0x1f, 5 }, { 0x03, 3 }, { 0x07, 3 }, { 0x07, 4 }, { 0x00, 0 }, - { 0x01, 1 }, { 0x01, 2 }, { 0x05, 3 }, { 0x03, 2 }, { 0x0f, 4 }, - { 0x0f, 5 }, { 0x0f, 6 }, { 0x2f, 6 }, { 0x2f, 7 }, { 0xaf, 8 }, - { 0x6f, 7 } - }, -/* EXIT1_DR */ - { - { 0x0f, 4 }, { 0x01, 2 }, { 0x03, 2 }, { 0x03, 3 }, { 0x02, 3 }, - { 0x00, 0 }, { 0x00, 1 }, { 0x02, 2 }, { 0x01, 1 }, { 0x07, 3 }, - { 0x07, 4 }, { 0x07, 5 }, { 0x17, 5 }, { 0x17, 6 }, { 0x57, 7 }, - { 0x37, 6 } - }, -/* PAUSE_DR */ - { - { 0x1f, 5 }, { 0x03, 3 }, { 0x07, 3 }, { 0x07, 4 }, { 0x01, 2 }, - { 0x05, 3 }, { 0x00, 1 }, { 0x01, 1 }, { 0x03, 2 }, { 0x0f, 4 }, - { 0x0f, 5 }, { 0x0f, 6 }, { 0x2f, 6 }, { 0x2f, 7 }, { 0xaf, 8 }, - { 0x6f, 7 } - }, -/* EXIT2_DR */ - { - { 0x0f, 4 }, { 0x01, 2 }, { 0x03, 2 }, { 0x03, 3 }, { 0x00, 1 }, - { 0x02, 2 }, { 0x02, 3 }, { 0x00, 0 }, { 0x01, 1 }, { 0x07, 3 }, - { 0x07, 4 }, { 0x07, 5 }, { 0x17, 5 }, { 0x17, 6 }, { 0x57, 7 }, - { 0x37, 6 } - }, -/* UPDATE_DR */ - { - { 0x07, 3 }, { 0x00, 1 }, { 0x01, 1 }, { 0x01, 2 }, { 0x01, 3 }, - { 0x05, 3 }, { 0x05, 4 }, { 0x15, 5 }, { 0x00, 0 }, { 0x03, 2 }, - { 0x03, 3 }, { 0x03, 4 }, { 0x0b, 4 }, { 0x0b, 5 }, { 0x2b, 6 }, - { 0x1b, 5 } - }, -/* SELECT_IR */ - { - { 0x01, 1 }, { 0x01, 2 }, { 0x05, 3 }, { 0x05, 4 }, { 0x05, 5 }, - { 0x15, 5 }, { 0x15, 6 }, { 0x55, 7 }, { 0x35, 6 }, { 0x00, 0 }, - { 0x00, 1 }, { 0x00, 2 }, { 0x02, 2 }, { 0x02, 3 }, { 0x0a, 4 }, - { 0x06, 3 } - }, -/* CAPTURE_IR */ - { - { 0x1f, 5 }, { 0x03, 3 }, { 0x07, 3 }, { 0x07, 4 }, { 0x07, 5 }, - { 0x17, 5 }, { 0x17, 6 }, { 0x57, 7 }, { 0x37, 6 }, { 0x0f, 4 }, - { 0x00, 0 }, { 0x00, 1 }, { 0x01, 1 }, { 0x01, 2 }, { 0x05, 3 }, - { 0x03, 2 } - }, -/* SHIFT_IR */ - { - { 0x1f, 5 }, { 0x03, 3 }, { 0x07, 3 }, { 0x07, 4 }, { 0x07, 5 }, - { 0x17, 5 }, { 0x17, 6 }, { 0x57, 7 }, { 0x37, 6 }, { 0x0f, 4 }, - { 0x0f, 5 }, { 0x00, 0 }, { 0x01, 1 }, { 0x01, 2 }, { 0x05, 3 }, - { 0x03, 2 } - }, -/* EXIT1_IR */ - { - { 0x0f, 4 }, { 0x01, 2 }, { 0x03, 2 }, { 0x03, 3 }, { 0x03, 4 }, - { 0x0b, 4 }, { 0x0b, 5 }, { 0x2b, 6 }, { 0x1b, 5 }, { 0x07, 3 }, - { 0x07, 4 }, { 0x02, 3 }, { 0x00, 0 }, { 0x00, 1 }, { 0x02, 2 }, - { 0x01, 1 } - }, -/* PAUSE_IR */ - { - { 0x1f, 5 }, { 0x03, 3 }, { 0x07, 3 }, { 0x07, 4 }, { 0x07, 5 }, - { 0x17, 5 }, { 0x17, 6 }, { 0x57, 7 }, { 0x37, 6 }, { 0x0f, 4 }, - { 0x0f, 5 }, { 0x01, 2 }, { 0x05, 3 }, { 0x00, 1 }, { 0x01, 1 }, - { 0x03, 2 } - }, -/* EXIT2_IR */ - { - { 0x0f, 4 }, { 0x01, 2 }, { 0x03, 2 }, { 0x03, 3 }, { 0x03, 4 }, - { 0x0b, 4 }, { 0x0b, 5 }, { 0x2b, 6 }, { 0x1b, 5 }, { 0x07, 3 }, - { 0x07, 4 }, { 0x00, 1 }, { 0x02, 2 }, { 0x02, 3 }, { 0x00, 0 }, - { 0x01, 1 } - }, -/* UPDATE_IR */ - { - { 0x07, 3 }, { 0x00, 1 }, { 0x01, 1 }, { 0x01, 2 }, { 0x01, 3 }, - { 0x05, 3 }, { 0x05, 4 }, { 0x15, 5 }, { 0x0d, 4 }, { 0x03, 2 }, - { 0x03, 3 }, { 0x03, 4 }, { 0x0b, 4 }, { 0x0b, 5 }, { 0x2b, 6 }, - { 0x00, 0 } - }, -}; - -const struct device *tck_dev, *tdi_dev, *tdo_dev, *tms_dev; -const gpio_pin_t tck_pin = CONFIG_TCK_PIN; -const gpio_pin_t tdi_pin = CONFIG_TDI_PIN; -const gpio_pin_t tdo_pin = CONFIG_TDO_PIN; -const gpio_pin_t tms_pin = CONFIG_TMS_PIN; - - -void jtag_npcm4xx_init(void) -{ - tck_dev = device_get_binding(CONFIG_TCK_DEV); - tdi_dev = device_get_binding(CONFIG_TDI_DEV); - tdo_dev = device_get_binding(CONFIG_TDO_DEV); - tms_dev = device_get_binding(CONFIG_TMS_DEV); - - gpio_pin_configure(tck_dev, tck_pin, CONFIG_TCK_FLAG); - gpio_pin_configure(tdi_dev, tdi_pin, CONFIG_TDI_FLAG); - gpio_pin_configure(tdo_dev, tdo_pin, CONFIG_TDO_FLAG); - gpio_pin_configure(tms_dev, tms_pin, CONFIG_TMS_FLAG); - - /* Test-Logic Reset state */ - gjtag.tap_state = TAP_RESET; -} - -/* return value: tdo */ -static inline uint8_t jtag_npcm4xx_tck_cycle(uint8_t tms, uint8_t tdi) -{ - gpio_port_value_t ret_tdo; - - /* TCK = 0 */ - gpio_port_clear_bits_raw(tck_dev, BIT(tck_pin)); - gpio_port_set_masked_raw(tdi_dev, BIT(tdi_pin), (tdi << tdi_pin)); - gpio_port_set_masked_raw(tms_dev, BIT(tms_pin), (tms << tms_pin)); - - /* TCK = 1 */ - gpio_port_set_bits_raw(tck_dev, BIT(tck_pin)); - gpio_port_get_raw(tdo_dev, &ret_tdo); - gpio_port_clear_bits_raw(tck_dev, BIT(tck_pin)); - - return ((ret_tdo & BIT(tdo_pin)) >> tdo_pin); -} - -void jtag_npcm4xx_set_tap_state(enum jtag_tap_states from, enum jtag_tap_states to) -{ - uint8_t i; - uint8_t tmsbits; - uint8_t count; - - if (from == to) { - return; - } - if (from == TAP_CURRENT_STATE) { - from = gjtag.tap_state; - } - - if (from > TAP_CURRENT_STATE || to > TAP_CURRENT_STATE) { - return; - } - - /* Reset to Test-Logic Reset state: - * Also notice that in whatever state the TAP controller may be at, - * it will goes back to this state if TMS is set to 1 for 5 consecutive TCK cycles. - */ - if (to == TAP_RESET) { - for (i = 0; i < 9; i++) { - jtag_npcm4xx_tck_cycle(1, 0); - } - gjtag.tap_state = TAP_RESET; - return; - } - - tmsbits = _tms_cycle_lookup[from][to].tms_bits; - count = _tms_cycle_lookup[from][to].count; - - if (count == 0) { - return; - } - - for (i = 0; i < count; i++) { - jtag_npcm4xx_tck_cycle((tmsbits & 1), 1); - tmsbits >>= 1; - } - - gjtag.tap_state = to; -} - -enum jtag_tap_states jtag_npcm4xx_get_tap_state(void) -{ - return gjtag.tap_state; -} - -void jtag_npcm4xx_xfer_spi(uint32_t out_bytes_len, uint8_t *out_data, - uint32_t in_byte_len, uint8_t *in_data) -{ - -} - -void jtag_npcm4xx_xfer_gpio(uint32_t out_bits_len, uint8_t *out_data, - uint32_t in_bits_len, uint8_t *in_data, uint8_t last_data) -{ - uint32_t bits_len; - uint32_t bits_idx = 0; - uint8_t tdi, tms; - - bits_len = (out_bits_len > in_bits_len) ? out_bits_len : in_bits_len; - - tms = 0; - while (bits_idx < bits_len) { - if (out_bits_len) { - tdi = (*out_data & BIT(bits_idx)) >> bits_idx; - } else { - tdi = 0; - } - - if (bits_idx == bits_len - 1) { /* last bit */ - if (last_data) { - tms = 1; - } - } - - if (in_bits_len) { - *in_data |= (jtag_npcm4xx_tck_cycle(tms, tdi) << bits_idx); - } else { - jtag_npcm4xx_tck_cycle(tms, tdi); - } - - out_bits_len = (out_bits_len) ? (out_bits_len - 1) : 0; - in_bits_len = (in_bits_len) ? (in_bits_len - 1) : 0; - - if (++bits_idx == 8) { - bits_idx = 0; - bits_len -= 8; - out_data++; - if (in_bits_len) { - *(++in_data) = 0; - } - } - } -} - -void jtag_npcm4xx_readwrite_scan(uint32_t bits_len, uint8_t *out_data, uint8_t *in_data, - enum jtag_tap_states end_state) -{ -#if (CONFIG_USE_SPI == 1) - uint32_t spi_xfer_bytes = (bits_len / 8) - 1; -#else - uint32_t spi_xfer_bytes = 0; -#endif - uint32_t remain_bits = bits_len; - - if (spi_xfer_bytes) { - jtag_npcm4xx_xfer_spi(spi_xfer_bytes, out_data, spi_xfer_bytes, in_data); - remain_bits -= spi_xfer_bytes * 8; - } - - if (remain_bits) { - if (end_state != TAP_SHIFT_DR && end_state != TAP_SHIFT_IR && - end_state != TAP_CURRENT_STATE) { - jtag_npcm4xx_xfer_gpio(remain_bits, out_data + spi_xfer_bytes, - remain_bits, in_data + spi_xfer_bytes, 1); - gjtag.tap_state = (gjtag.tap_state == TAP_SHIFT_DR) ? - TAP_EXIT1_DR : TAP_EXIT1_IR; - } else { - jtag_npcm4xx_xfer_gpio(remain_bits, out_data + spi_xfer_bytes, - remain_bits, in_data + spi_xfer_bytes, 0); - } - } - - jtag_npcm4xx_set_tap_state(TAP_CURRENT_STATE, end_state); -} - -void jtag_npcm4xx_ir_scan(uint32_t bits_len, uint8_t *out_data, uint8_t *in_data, - enum jtag_tap_states end_state) -{ - if (bits_len == 0) { - return; - } - - jtag_npcm4xx_set_tap_state(TAP_CURRENT_STATE, TAP_SHIFT_IR); - - jtag_npcm4xx_readwrite_scan(bits_len, out_data, in_data, end_state); - -} - -void jtag_npcm4xx_dr_scan(uint32_t bits_len, uint8_t *out_data, uint8_t *in_data, - enum jtag_tap_states end_state) -{ - if (bits_len == 0) { - return; - } - - jtag_npcm4xx_set_tap_state(TAP_CURRENT_STATE, TAP_SHIFT_DR); - - jtag_npcm4xx_readwrite_scan(bits_len, out_data, in_data, end_state); - -} - -/* ============= (reference) hal for Open BIC ============= */ -void jtag_set_tap(uint8_t data, uint8_t bitlength) -{ - uint8_t tms, index; - - for (index = 0; index < bitlength; index++) { - tms = data & 0x01; - jtag_npcm4xx_tck_cycle(tms, 0); - data = data >> 1; - } -} - -void jtag_shift_data(uint16_t Wbit, uint8_t *Wdate, - uint16_t Rbit, uint8_t *Rdate, - uint8_t lastidx) -{ - jtag_npcm4xx_xfer_gpio(Wbit, Wdate, Rbit, Rdate, lastidx); -} diff --git a/soc/arm/npcm4xx/npcm400f/jtag_master.h b/soc/arm/npcm4xx/npcm400f/jtag_master.h deleted file mode 100644 index 10eb4f552b6680..00000000000000 --- a/soc/arm/npcm4xx/npcm400f/jtag_master.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2023 Nuvoton Technology Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef _JTAG_MASTER_H_ -#define _JTAG_MASTER_H_ - -#include - -enum jtag_tap_states { - TAP_RESET, /* 0: Test-Logic Reset */ - TAP_IDLE, /* 1: Run-Test/ Idle */ - - TAP_SELECT_DR, /* 2: Select-DR/ Scan */ - TAP_CAPTURE_DR, /* 3: Capture-DR */ - TAP_SHIFT_DR, /* 4: Shift-DR */ - TAP_EXIT1_DR, /* 5: Exit1-DR */ - TAP_PAUSE_DR, /* 6: Pause-DR */ - TAP_EXIT2_DR, /* 7: Exit2-DR */ - TAP_UPDATE_DR, /* 8: Update-DR */ - - TAP_SELECT_IR, /* 9: Select-IR/ Scan */ - TAP_CAPTURE_IR, /* 10: Capture-IR */ - TAP_SHIFT_IR, /* 11: Shift-IR */ - TAP_EXIT1_IR, /* 12: Exit1-IR */ - TAP_PAUSE_IR, /* 13: Pause-IR */ - TAP_EXIT2_IR, /* 14: Exit2-IR */ - TAP_UPDATE_IR, /* 15: Update-IR */ - - TAP_CURRENT_STATE -}; - -#ifdef __cplusplus -extern "C" { -#endif - -void jtag_npcm4xx_init(void); -void jtag_npcm4xx_xfer_gpio(uint32_t out_bits_len, uint8_t *out_data, - uint32_t in_bits_len, uint8_t *in_data, uint8_t last_data); -void jtag_npcm4xx_set_tap_state(enum jtag_tap_states from, enum jtag_tap_states to); -void jtag_npcm4xx_ir_scan(uint32_t bits_len, uint8_t *out_data, uint8_t *in_data, - enum jtag_tap_states end_state); -void jtag_npcm4xx_dr_scan(uint32_t bits_len, uint8_t *out_data, uint8_t *in_data, - enum jtag_tap_states end_state); -enum jtag_tap_states jtag_npcm4xx_get_tap_state(void); - -#ifdef __cplusplus -} -#endif - - -#endif /* _JTAG_MASTER_H_ */ diff --git a/soc/arm/npcm4xx/npcm400f/sig_def_list.h b/soc/arm/npcm4xx/npcm400f/sig_def_list.h index 64a51799a386a4..3986fbb0244268 100644 --- a/soc/arm/npcm4xx/npcm400f/sig_def_list.h +++ b/soc/arm/npcm4xx/npcm400f/sig_def_list.h @@ -25,6 +25,11 @@ GPIO_SIG_DEFINE(GPIO37, M7, SIG_DESC_CLEAR(0x16, 2), SIG_DESC_CLEAR(0x16, 3), SI /* GPIO_6 */ GPIO_SIG_DEFINE(GPIO60, K10, SIG_DESC_SET(0x5D, 2), SIG_DESC_CLEAR(0x1A, 0)) GPIO_SIG_DEFINE(GPIO61, K11, SIG_DESC_SET(0x5D, 1), SIG_DESC_CLEAR(0x1A, 0)) +GPIO_SIG_DEFINE(GPIO66, D12, SIG_DESC_CLEAR(0x1c, 1)) +GPIO_SIG_DEFINE(GPIO67, C12, SIG_DESC_CLEAR(0x1c, 1)) +/* GPIO_7 */ +GPIO_SIG_DEFINE(GPIO70, B12, SIG_DESC_CLEAR(0x1c, 1)) +GPIO_SIG_DEFINE(GPIO73, A12, SIG_DESC_CLEAR(0x1c, 1)) /* GPIO_9 */ GPIO_SIG_DEFINE(GPIO96, A5, SIG_DESC_SET(0x17, 3)) GPIO_SIG_DEFINE(GPIO97, B5, SIG_DESC_SET(0x17, 4)) @@ -39,6 +44,11 @@ GPIO_SIG_DEFINE(GPIOC5, L3, SIG_DESC_CLEAR(0x62, 5)) /* GPIO_D */ GPIO_SIG_DEFINE(GPIOD0, G11, SIG_DESC_CLEAR(0x66, 0)) GPIO_SIG_DEFINE(GPIOD1, F11, SIG_DESC_CLEAR(0x66, 1)) +/* GPIO_F */ +GPIO_SIG_DEFINE(GPIOF0, B8, SIG_DESC_CLEAR(0x34, 6)) +GPIO_SIG_DEFINE(GPIOF1, A8, SIG_DESC_CLEAR(0x34, 6)) +GPIO_SIG_DEFINE(GPIOF2, B7, SIG_DESC_CLEAR(0x34, 7)) +GPIO_SIG_DEFINE(GPIOF3, A7, SIG_DESC_CLEAR(0x34, 7)) #endif #if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) && CONFIG_UART_NPCM4XX