1.. SPDX-License-Identifier: BSD-3-Clause 2 Copyright(c) 2021 Marvell. 3 4Marvell CNXK GPIO Driver 5======================== 6 7CNXK GPIO PMD configures and manages GPIOs available on the system using 8standard enqueue/dequeue mechanism offered by raw device abstraction. PMD relies 9both on standard sysfs GPIO interface provided by the Linux kernel and GPIO 10kernel driver custom interface allowing one to install userspace interrupt 11handlers. 12 13Features 14-------- 15 16Following features are available: 17 18- export/unexport a GPIO 19- read/write specific value from/to exported GPIO 20- set GPIO direction 21- set GPIO edge that triggers interrupt 22- set GPIO active low 23- register interrupt handler for specific GPIO 24- multiprocess aware 25 26Requirements 27------------ 28 29PMD relies on modified kernel GPIO driver which exposes ``ioctl()`` interface 30for installing interrupt handlers for low latency signal processing. 31 32Driver is shipped with Marvell SDK. 33 34Limitations 35----------- 36 37In multiprocess mode, user-space application must ensure 38no GPIO sharing across processes takes place. 39 40Device Setup 41------------ 42 43CNXK GPIO PMD binds to virtual device which gets created by passing 44`--vdev=cnxk_gpio,gpiochip=<number>` command line to EAL. `gpiochip` parameter 45tells PMD which GPIO controller should be used. Available controllers are 46available under `/sys/class/gpio`. For further details on how Linux represents 47GPIOs in userspace please refer to 48`sysfs.txt <https://www.kernel.org/doc/Documentation/gpio/sysfs.txt>`_. 49 50If `gpiochip=<number>` was omitted then first gpiochip from the alphabetically 51sort list of available gpiochips is used. 52 53.. code-block:: console 54 55 $ ls /sys/class/gpio 56 export gpiochip448 unexport 57 58In above scenario only one GPIO controller is present hence 59`--vdev=cnxk_gpio,gpiochip=448` should be passed to EAL. 60 61Before performing actual data transfer one needs to call 62``rte_rawdev_queue_count()`` followed by ``rte_rawdev_queue_conf_get()``. The 63former returns number GPIOs available in the system irrespective of GPIOs 64being controllable or not. Thus it is user responsibility to pick the proper 65ones. The latter call simply returns queue capacity. 66 67In order to allow using only subset of available GPIOs `allowlist` PMD param may 68be used. For example passing `--vdev=cnxk_gpio,gpiochip=448,allowlist=[0,1,2,3]` 69to EAL will deny using all GPIOs except those specified explicitly in the 70`allowlist`. 71 72Respective queue needs to be configured with ``rte_rawdev_queue_setup()``. This 73call barely exports GPIO to userspace. 74 75To perform actual data transfer use standard ``rte_rawdev_enqueue_buffers()`` 76and ``rte_rawdev_dequeue_buffers()`` APIs. Not all messages produce sensible 77responses hence dequeueing is not always necessary. 78 79CNXK GPIO PMD 80------------- 81 82PMD accepts ``struct cnxk_gpio_msg`` messages which differ by type and payload. 83Message types along with description are listed below. As for the usage examples 84please refer to ``cnxk_gpio_selftest()``. There's a set of convenient wrappers 85available, one for each existing command. 86 87Set GPIO value 88~~~~~~~~~~~~~~ 89 90Message is used to set output to low or high. This does not work for GPIOs 91configured as input. 92 93Message must have type set to ``CNXK_GPIO_MSG_TYPE_SET_PIN_VALUE``. 94 95Payload must be an integer set to 0 (low) or 1 (high). 96 97Consider using ``rte_pmd_gpio_set_pin_value()`` wrapper. 98 99Set GPIO edge 100~~~~~~~~~~~~~ 101 102Message is used to set edge that triggers interrupt. 103 104Message must have type set to ``CNXK_GPIO_MSG_TYPE_SET_PIN_EDGE``. 105 106Payload must be `enum cnxk_gpio_pin_edge`. 107 108Consider using ``rte_pmd_gpio_set_pin_edge()`` wrapper. 109 110Set GPIO direction 111~~~~~~~~~~~~~~~~~~ 112 113Message is used to change GPIO direction to either input or output. 114 115Message must have type set to ``CNXK_GPIO_MSG_TYPE_SET_PIN_DIR``. 116 117Payload must be `enum cnxk_gpio_pin_dir`. 118 119Consider using ``rte_pmd_gpio_set_pin_dir()`` wrapper. 120 121Set GPIO active low 122~~~~~~~~~~~~~~~~~~~ 123 124Message is used to set whether pin is active low. 125 126Message must have type set to ``CNXK_GPIO_MSG_TYPE_SET_PIN_ACTIVE_LOW``. 127 128Payload must be an integer set to 0 or 1. The latter activates inversion. 129 130Consider using ``rte_pmd_gpio_set_pin_active_low()`` wrapper. 131 132Get GPIO value 133~~~~~~~~~~~~~~ 134 135Message is used to read GPIO value. Value can be 0 (low) or 1 (high). 136 137Message must have type set to ``CNXK_GPIO_MSG_TYPE_GET_PIN_VALUE``. 138 139Payload contains integer set to either 0 or 1. 140 141Consider using ``rte_pmd_gpio_get_pin_value()`` wrapper. 142 143Get GPIO edge 144~~~~~~~~~~~~~ 145 146Message is used to read GPIO edge. 147 148Message must have type set to ``CNXK_GPIO_MSG_TYPE_GET_PIN_EDGE``. 149 150Payload contains `enum cnxk_gpio_pin_edge`. 151 152Consider using ``rte_pmd_gpio_get_pin_edge()`` wrapper. 153 154Get GPIO direction 155~~~~~~~~~~~~~~~~~~ 156 157Message is used to read GPIO direction. 158 159Message must have type set to ``CNXK_GPIO_MSG_TYPE_GET_PIN_DIR``. 160 161Payload contains `enum cnxk_gpio_pin_dir`. 162 163Consider using ``rte_pmd_gpio_get_pin_dir()`` wrapper. 164 165Get GPIO active low 166~~~~~~~~~~~~~~~~~~~ 167 168Message is used check whether inverted logic is active. 169 170Message must have type set to ``CNXK_GPIO_MSG_TYPE_GET_PIN_ACTIVE_LOW``. 171 172Payload contains an integer set to 0 or 1. The latter means inverted logic 173is turned on. 174 175Consider using ``rte_pmd_gpio_get_pin_active_low()`` wrapper. 176 177Request interrupt 178~~~~~~~~~~~~~~~~~ 179 180Message is used to install custom interrupt handler. 181 182Message must have type set to ``CNXK_GPIO_MSG_TYPE_REGISTER_IRQ``. 183 184Payload needs to be set to ``struct cnxk_gpio_irq`` which describes interrupt 185being requested. 186 187Consider using ``rte_pmd_gpio_register_gpio()`` wrapper. 188 189Free interrupt 190~~~~~~~~~~~~~~ 191 192Message is used to remove installed interrupt handler. 193 194Message must have type set to ``CNXK_GPIO_MSG_TYPE_UNREGISTER_IRQ``. 195 196Consider using ``rte_pmd_gpio_unregister_gpio()`` wrapper. 197 198Self test 199--------- 200 201On EAL initialization CNXK GPIO device will be probed and populated into 202the list of raw devices on condition ``--vdev=cnxk_gpio,gpiochip=<number>`` was 203passed. ``rte_rawdev_get_dev_id("CNXK_GPIO")`` returns unique device id. Use 204this identifier for further rawdev function calls. 205 206Selftest rawdev API can be used to verify the PMD functionality. Note it blindly 207assumes that all GPIOs are controllable so some errors during test are expected. 208