From: Andreas Kölbl <andreas.koe...@st.oth-regensburg.de> Implements the interface definded in libbsp/shared for Tegra124 processors.
bsp specific: The bank parameter has to include the port specified by the tegra124 address map In order to set a pin either in input or output mode requires an additional pointer of type uint32_t passing the pinmux port of the bank --- c/src/lib/libbsp/arm/jetson-tk1/Makefile.am | 5 + c/src/lib/libbsp/arm/jetson-tk1/README | 3 + .../lib/libbsp/arm/jetson-tk1/gpio/tegra124-gpio.c | 271 +++++++++++++++++++++ c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h | 4 + .../libbsp/arm/jetson-tk1/include/tegra124-gpio.h | 61 +++++ .../arm/jetson-tk1/startup/mm_config_table.c | 14 ++ 6 files changed, 358 insertions(+) create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/gpio/tegra124-gpio.c create mode 100644 c/src/lib/libbsp/arm/jetson-tk1/include/tegra124-gpio.h diff --git a/c/src/lib/libbsp/arm/jetson-tk1/Makefile.am b/c/src/lib/libbsp/arm/jetson-tk1/Makefile.am index 37d2ca267e..4ec5c81b14 100644 --- a/c/src/lib/libbsp/arm/jetson-tk1/Makefile.am +++ b/c/src/lib/libbsp/arm/jetson-tk1/Makefile.am @@ -44,6 +44,7 @@ include_bsp_HEADERS += include/cmdline.h include_bsp_HEADERS += include/irq.h include_bsp_HEADERS += include/memory.h include_bsp_HEADERS += include/mmu.h +include_bsp_HEADERS += include/tegra124-gpio.h ############################################################################### # Data # @@ -107,6 +108,10 @@ libbsp_a_SOURCES += ../../shared/src/irq-legacy.c libbsp_a_SOURCES += ../../shared/src/irq-server.c libbsp_a_SOURCES += ../../shared/src/irq-shell.c +# GPIO +libbsp_a_SOURCES += ../../shared/gpio.c +libbsp_a_SOURCES += gpio/tegra124-gpio.c + # Restart libbsp_a_SOURCES += startup/bspreset.c diff --git a/c/src/lib/libbsp/arm/jetson-tk1/README b/c/src/lib/libbsp/arm/jetson-tk1/README index 13821c7082..50022cf30c 100644 --- a/c/src/lib/libbsp/arm/jetson-tk1/README +++ b/c/src/lib/libbsp/arm/jetson-tk1/README @@ -4,6 +4,7 @@ This BSP currently supports the following devices: - Console using UART-D on DB9 connector and UART-A on the J3A2 Pin header - Clock using the ARM internal CP15 timer - Benchmark timer using the Nvidia Generic Timer TimerUS + - GPIOs Checkout the options described in include/bspopts.h.in in order to configure the second console or let the consoles operate interrupt driven. @@ -12,6 +13,7 @@ Currently, following IRQs are used: If configured NS8250_CONSOLE_USE_INTERRUPTS=1) - 122 - 68 + - 119 for the GPIO_6 bank (PU0 - PU6) Also allow the following memory regions: - UARTA 0x40@0x70006000 @@ -19,3 +21,4 @@ Also allow the following memory regions: - Nvidia Timers 0x1000@0x60005000 - RAM 64MB@0x90000000 - PINMUX AUX 0x1000@0x70003000 + - GPIO 0x1000@0x6000d000 diff --git a/c/src/lib/libbsp/arm/jetson-tk1/gpio/tegra124-gpio.c b/c/src/lib/libbsp/arm/jetson-tk1/gpio/tegra124-gpio.c new file mode 100644 index 0000000000..da35b6dfe0 --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/gpio/tegra124-gpio.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <bsp.h> +#include <bsp/gpio.h> +#include <bsp/memory.h> +#include <bsp/tegra124-gpio.h> + +#define GPIO_CNF 0x00 +#define GPIO_OE 0x10 +#define GPIO_OUT 0x20 +#define GPIO_IN 0x30 +#define GPIO_INT_STA 0x40 +#define GPIO_INT_ENB 0x50 +#define GPIO_INT_LVL 0x60 +#define GPIO_INT_CLR 0x70 + +#define GPIO_MSK_CNF 0x80 +#define GPIO_MSK_OE 0x90 +#define GPIO_MSK_OUT 0xa0 +#define GPIO_MSK_INT_STA 0xc0 +#define GPIO_MSK_INT_ENB 0xd0 +#define GPIO_MSK_INT_LVL 0xe0 + +/* + * To achieve a performant and compatible implementation the bank parameter has + * also to include the gpio port address, Tegra K1 TRM, p. 278 + */ + +static inline void tegra_gpio_write( + uintptr_t gpio_reg, + uint32_t bank, + uint32_t value +) +{ + mmio_write( GPIO_BASE + gpio_reg + bank, value ); +} + +static uint32_t tegra_gpio_read( + uintptr_t gpio_reg, + uint32_t bank +) +{ + return mmio_read( GPIO_BASE + gpio_reg + bank ); +} + +static inline void pinmux_write( + uint32_t pinmux_reg, + uint32_t pin, + tegra_pinmux_property property +) +{ + mmio_write( PINMUX_AUX + pinmux_reg + 4 * pin, property ); +} + +static inline uint32_t pinmux_read( + uint32_t pinmux_reg, + uint32_t pin +) +{ + return mmio_read( PINMUX_AUX + pinmux_reg + 4 * pin ); +} + +static inline void gpio_set_level( + uint32_t bank, + uint32_t pin, + rtems_gpio_interrupt sens +) +{ + uint32_t value; + + value = tegra_gpio_read( GPIO_INT_LVL, bank ); + + value &= ~( ( 1 << pin ) | ( ( 1 << 8 ) << pin ) | ( ( 1 << 16 ) << pin ) ); + + if ( sens != NONE ) { + value |= ( 1 << 8 ) << pin; + } + + if ( sens == RISING_EDGE || sens == HIGH_LEVEL ) { + value |= 1 << pin; + } else if ( sens == BOTH_EDGES ) { + value |= ( 1 << 16 ) << pin; + } + + tegra_gpio_write( GPIO_INT_LVL, bank, value ); +} + +rtems_status_code rtems_gpio_bsp_multi_set(uint32_t bank, uint32_t bitmask) +{ + tegra_gpio_write( GPIO_OUT, bank, bitmask & 0xff ); + + return RTEMS_SUCCESSFUL; +} + +rtems_status_code rtems_gpio_bsp_multi_clear(uint32_t bank, uint32_t bitmask) +{ + tegra_gpio_write( GPIO_MSK_OUT, bank, bitmask << 8 ); + + return RTEMS_SUCCESSFUL; +} + +uint32_t rtems_gpio_bsp_multi_read(uint32_t bank, uint32_t bitmask) +{ + return tegra_gpio_read( GPIO_IN, bank ) & bitmask; +} + +rtems_status_code rtems_gpio_bsp_set(uint32_t bank, uint32_t pin) +{ + tegra_gpio_write( GPIO_MSK_OUT, bank, ( ( 1 << 8 ) << pin ) | ( 1 << pin ) ); + + return RTEMS_SUCCESSFUL; +} + +rtems_status_code rtems_gpio_bsp_clear(uint32_t bank, uint32_t pin) +{ + tegra_gpio_write( GPIO_MSK_OUT, bank, ( 1 << 8 ) << pin ); + + return RTEMS_SUCCESSFUL; +} + +uint32_t rtems_gpio_bsp_get_value(uint32_t bank, uint32_t pin) +{ + return ( ( tegra_gpio_read( GPIO_IN, bank ) & ( 1 << pin ) ) != 0 ); +} + +rtems_status_code rtems_gpio_bsp_select_input( + uint32_t bank, + uint32_t pin, + void *pinmux_reg +) +{ + pinmux_write( + *( (uint32_t *) ( pinmux_reg ) ), + pin, + TEGRA_E_INPUT | TEGRA_TRISTATE + ); + tegra_gpio_write( GPIO_MSK_CNF, bank, 1 << pin ); + tegra_gpio_write( GPIO_MSK_OE, bank, 1 << pin ); + + return RTEMS_SUCCESSFUL; +} + +rtems_status_code rtems_gpio_bsp_select_output( + uint32_t bank, + uint32_t pin, + void *pinmux_reg +) +{ + pinmux_write( *( (uint32_t *) ( pinmux_reg ) ), pin, 0 ); + tegra_gpio_write( GPIO_MSK_CNF, bank, 1 << pin ); + tegra_gpio_write( GPIO_MSK_OE, bank, ( ( 1 << 8 ) << pin ) | ( 1 << pin ) ); + + return RTEMS_SUCCESSFUL; +} + +rtems_status_code rtems_gpio_bsp_select_specific_io( + uint32_t bank, + uint32_t pin, + uint32_t function, + void *pin_data +) +{ + pinmux_write( bank, pin, (tegra_pinmux_property) function ); + + return RTEMS_SUCCESSFUL; +} + +rtems_status_code rtems_gpio_bsp_set_resistor_mode( + uint32_t bank, + uint32_t pin, + rtems_gpio_pull_mode mode +) +{ + switch ( mode ) { + case PULL_UP: + pinmux_write( bank, pin, TEGRA_PULL_UP ); + break; + case PULL_DOWN: + pinmux_write( bank, pin, TEGRA_PULL_DOWN ); + break; + case NO_PULL_RESISTOR: + pinmux_write( bank, pin, TEGRA_PULL_DISABLED ); + break; + default: + + return RTEMS_INVALID_NUMBER; + } + + return RTEMS_SUCCESSFUL; +} + +rtems_vector_number rtems_gpio_bsp_get_vector( uint32_t bank ) +{ + if ( ( bank / 0x100 ) > sizeof( gpio_vector_table ) ) { + return -1; + } + + return gpio_vector_table[ bank / 0x100 ]; +} + +uint32_t rtems_gpio_bsp_interrupt_line( rtems_vector_number vector ) +{ + uint32_t bank; + + for ( bank = 0; bank < sizeof( gpio_vector_table ); bank++ ) { + if ( gpio_vector_table[ bank ] == vector ) { + tegra_gpio_write( GPIO_INT_CLR, bank * 0x100, 0xff ); + + return tegra_gpio_read( GPIO_INT_STA, bank * 0x100 ); + } + } + + return RTEMS_INVALID_NUMBER; +} + +rtems_status_code rtems_gpio_bsp_enable_interrupt( + uint32_t bank, + uint32_t pin, + rtems_gpio_interrupt interrupt +) +{ + tegra_gpio_write( GPIO_INT_CLR, bank, 1 << pin ); + gpio_set_level( bank, pin, interrupt ); + tegra_gpio_write( GPIO_MSK_INT_ENB, + bank, + ( ( 1 << 8 ) << pin ) | ( 1 << pin ) ); + + return RTEMS_SUCCESSFUL; +} + +rtems_status_code rtems_gpio_bsp_disable_interrupt( + uint32_t bank, + uint32_t pin, + rtems_gpio_interrupt interrupt +) +{ + uint32_t level; + + tegra_gpio_write( GPIO_INT_CLR, bank, 1 << pin ); + level = tegra_gpio_read( GPIO_INT_LVL, bank ); + tegra_gpio_write( GPIO_MSK_INT_ENB, bank, ( ( 1 << 8 ) << pin ) ); + tegra_gpio_write( GPIO_INT_LVL, bank, level & ~interrupt ); + + return RTEMS_SUCCESSFUL; +} + +rtems_status_code rtems_gpio_bsp_multi_select( + rtems_gpio_multiple_pin_select *pins, + uint32_t pin_count, + uint32_t select_bank +) +{ + return RTEMS_NOT_DEFINED; +} + +rtems_status_code rtems_gpio_bsp_specific_group_operation( + uint32_t bank, + uint32_t *pins, + uint32_t pin_count, + void *arg +) +{ + return RTEMS_NOT_DEFINED; +} diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h b/c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h index ea4dcb74e4..a9a47584a6 100644 --- a/c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h +++ b/c/src/lib/libbsp/arm/jetson-tk1/include/bsp.h @@ -22,4 +22,8 @@ #define TIMER_BASE ((void *) 0x60005000) +#define BSP_GPIO_PINS_PER_BANK 32 +#define BSP_GPIO_BANK_COUNT 8 +#define BSP_GPIO_PIN_COUNT (BSP_GPIO_PINS_PER_BANK * BSP_GPIO_BANK_COUNT) + #endif /* LIBBSP_ARM_JETSONTK1_BSP_H */ diff --git a/c/src/lib/libbsp/arm/jetson-tk1/include/tegra124-gpio.h b/c/src/lib/libbsp/arm/jetson-tk1/include/tegra124-gpio.h new file mode 100644 index 0000000000..cbfb6e4f3f --- /dev/null +++ b/c/src/lib/libbsp/arm/jetson-tk1/include/tegra124-gpio.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) OTH Regensburg, 2017 + * Author: Andreas Kölbl + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_JETSON_GPIO_H +#define LIBBSP_ARM_JETSON_GPIO_H + +#define GPIO_BASE ((void *) 0x6000d000) +#define PINMUX_AUX ((void *) 0x70003000) + +#define GPIO1_IRQ (32 + 32) +#define GPIO2_IRQ (33 + 32) +#define GPIO3_IRQ (34 + 32) +#define GPIO4_IRQ (35 + 32) +#define GPIO5_IRQ (55 + 32) +#define GPIO6_IRQ (87 + 32) +#define GPIO7_IRQ (89 + 32) +#define GPIO8_IRQ (125 + 32) + +static const uint8_t gpio_vector_table[ BSP_GPIO_BANK_COUNT ] = { + GPIO1_IRQ, + GPIO2_IRQ, + GPIO3_IRQ, + GPIO4_IRQ, + GPIO5_IRQ, + GPIO6_IRQ, + GPIO7_IRQ, + GPIO8_IRQ, +}; + +typedef enum { + TEGRA_SFIO0 = ((0 << 1) | (0 << 0)), + TEGRA_SFIO1 = ((0 << 1) | (0 << 0)), + TEGRA_SFIO2 = ((1 << 1) | (0 << 0)), + TEGRA_SFIO3 = ((1 << 1) | (1 << 0)), + TEGRA_PULL_DISABLED = ((0 << 3) | (0 << 2)), + TEGRA_PULL_DOWN = ((0 << 3) | (1 << 2)), + TEGRA_PULL_UP = ((1 << 3) | (0 << 2)), + TEGRA_TRISTATE = (1 << 4), + TEGRA_E_INPUT = (1 << 5), + TEGRA_E_OPEN_DRAIN = (1 << 6), /* Matters only for DD pads */ + TEGRA_LOCK = (1 << 7), + TEGRA_IO_RESET = (1 << 8), /* Matters only for LV pads */ +} tegra_pinmux_property; + +typedef enum { + GPIO_PU0 = 0x184, + GMI_AD8 = 0x210, +} pinmux_ball; + +typedef enum { + GPIO_DIR_IN, + GPIO_DIR_OUT, +} gpio_direction; + +#endif /* LIBBSP_ARM_JETSON_GPIO_H */ diff --git a/c/src/lib/libbsp/arm/jetson-tk1/startup/mm_config_table.c b/c/src/lib/libbsp/arm/jetson-tk1/startup/mm_config_table.c index a8c3f41ccf..603ff6fac0 100644 --- a/c/src/lib/libbsp/arm/jetson-tk1/startup/mm_config_table.c +++ b/c/src/lib/libbsp/arm/jetson-tk1/startup/mm_config_table.c @@ -10,6 +10,8 @@ #include <bsp.h> #include <bspopts.h> #include <bsp/car.h> +#include <bsp/tegra124-gpio.h> +#include <bsp/cmdline.h> #include <bsp/console.h> #include <bsp/arm-cp15-start.h> @@ -26,6 +28,10 @@ BSP_START_DATA_SECTION const arm_cp15_start_section_config arm_cp15_start_mmu_config_table[] = { ARMV7_CP15_START_DEFAULT_SECTIONS, { + .begin = (uint32_t) BSP_CMDLINE_LOCATION, + .end = (uint32_t) BSP_CMDLINE_LOCATION + 0x4000, + .flags = ARMV7_MMU_DATA_READ_WRITE_CACHED + }, { .begin = (uint32_t) CAR, .end = (uint32_t) (CAR + 0x1000), .flags = ARMV7_MMU_DEVICE @@ -38,6 +44,14 @@ arm_cp15_start_mmu_config_table[] = { .end = (uint32_t) (APB_MISC_BASE + 0x1000), .flags = ARMV7_MMU_DEVICE }, { + .begin = (uint32_t) GPIO_BASE, + .end = (uint32_t) (GPIO_BASE + 0x1000), + .flags = ARMV7_MMU_DEVICE + }, { + .begin = (uint32_t) PINMUX_AUX, + .end = (uint32_t) (PINMUX_AUX + 0x1000), + .flags = ARMV7_MMU_DEVICE + }, { .begin = (uint32_t) UARTA, .end = (uint32_t) UARTA + 0x1000, .flags = ARMV7_MMU_DEVICE -- 2.13.3 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel