1d0b8a4e1STomasz Duszynski.. SPDX-License-Identifier: BSD-3-Clause 2d0b8a4e1STomasz Duszynski Copyright(c) 2021 Marvell. 3d0b8a4e1STomasz Duszynski 4d0b8a4e1STomasz DuszynskiMarvell CNXK GPIO Driver 5d0b8a4e1STomasz Duszynski======================== 6d0b8a4e1STomasz Duszynski 7d0b8a4e1STomasz DuszynskiCNXK GPIO PMD configures and manages GPIOs available on the system using 8d0b8a4e1STomasz Duszynskistandard enqueue/dequeue mechanism offered by raw device abstraction. PMD relies 9d0b8a4e1STomasz Duszynskiboth on standard sysfs GPIO interface provided by the Linux kernel and GPIO 10d0b8a4e1STomasz Duszynskikernel driver custom interface allowing one to install userspace interrupt 11d0b8a4e1STomasz Duszynskihandlers. 12d0b8a4e1STomasz Duszynski 13d0b8a4e1STomasz DuszynskiFeatures 14d0b8a4e1STomasz Duszynski-------- 15d0b8a4e1STomasz Duszynski 16d0b8a4e1STomasz DuszynskiFollowing features are available: 17d0b8a4e1STomasz Duszynski 18d0b8a4e1STomasz Duszynski- export/unexport a GPIO 19d0b8a4e1STomasz Duszynski- read/write specific value from/to exported GPIO 20d0b8a4e1STomasz Duszynski- set GPIO direction 21d0b8a4e1STomasz Duszynski- set GPIO edge that triggers interrupt 22d0b8a4e1STomasz Duszynski- set GPIO active low 23d0b8a4e1STomasz Duszynski- register interrupt handler for specific GPIO 24*ef2a3f3bSTomasz Duszynski- multiprocess aware 25d0b8a4e1STomasz Duszynski 26d0b8a4e1STomasz DuszynskiRequirements 27d0b8a4e1STomasz Duszynski------------ 28d0b8a4e1STomasz Duszynski 29d0b8a4e1STomasz DuszynskiPMD relies on modified kernel GPIO driver which exposes ``ioctl()`` interface 30d0b8a4e1STomasz Duszynskifor installing interrupt handlers for low latency signal processing. 31d0b8a4e1STomasz Duszynski 32d0b8a4e1STomasz DuszynskiDriver is shipped with Marvell SDK. 33d0b8a4e1STomasz Duszynski 34*ef2a3f3bSTomasz DuszynskiLimitations 35*ef2a3f3bSTomasz Duszynski----------- 36*ef2a3f3bSTomasz Duszynski 37*ef2a3f3bSTomasz DuszynskiIn multiprocess mode, user-space application must ensure 38*ef2a3f3bSTomasz Duszynskino GPIO sharing across processes takes place. 39*ef2a3f3bSTomasz Duszynski 40d0b8a4e1STomasz DuszynskiDevice Setup 41d0b8a4e1STomasz Duszynski------------ 42d0b8a4e1STomasz Duszynski 43d0b8a4e1STomasz DuszynskiCNXK GPIO PMD binds to virtual device which gets created by passing 44d0b8a4e1STomasz Duszynski`--vdev=cnxk_gpio,gpiochip=<number>` command line to EAL. `gpiochip` parameter 45d0b8a4e1STomasz Duszynskitells PMD which GPIO controller should be used. Available controllers are 46d0b8a4e1STomasz Duszynskiavailable under `/sys/class/gpio`. For further details on how Linux represents 47d0b8a4e1STomasz DuszynskiGPIOs in userspace please refer to 48d0b8a4e1STomasz Duszynski`sysfs.txt <https://www.kernel.org/doc/Documentation/gpio/sysfs.txt>`_. 49d0b8a4e1STomasz Duszynski 50d0b8a4e1STomasz DuszynskiIf `gpiochip=<number>` was omitted then first gpiochip from the alphabetically 51d0b8a4e1STomasz Duszynskisort list of available gpiochips is used. 52d0b8a4e1STomasz Duszynski 53d0b8a4e1STomasz Duszynski.. code-block:: console 54d0b8a4e1STomasz Duszynski 55d0b8a4e1STomasz Duszynski $ ls /sys/class/gpio 56d0b8a4e1STomasz Duszynski export gpiochip448 unexport 57d0b8a4e1STomasz Duszynski 58d0b8a4e1STomasz DuszynskiIn above scenario only one GPIO controller is present hence 59d0b8a4e1STomasz Duszynski`--vdev=cnxk_gpio,gpiochip=448` should be passed to EAL. 60d0b8a4e1STomasz Duszynski 61d0b8a4e1STomasz DuszynskiBefore performing actual data transfer one needs to call 62d0b8a4e1STomasz Duszynski``rte_rawdev_queue_count()`` followed by ``rte_rawdev_queue_conf_get()``. The 63d0b8a4e1STomasz Duszynskiformer returns number GPIOs available in the system irrespective of GPIOs 64d0b8a4e1STomasz Duszynskibeing controllable or not. Thus it is user responsibility to pick the proper 65d0b8a4e1STomasz Duszynskiones. The latter call simply returns queue capacity. 66d0b8a4e1STomasz Duszynski 67ecc0dd45STomasz DuszynskiIn order to allow using only subset of available GPIOs `allowlist` PMD param may 68ecc0dd45STomasz Duszynskibe used. For example passing `--vdev=cnxk_gpio,gpiochip=448,allowlist=[0,1,2,3]` 69ecc0dd45STomasz Duszynskito EAL will deny using all GPIOs except those specified explicitly in the 70ecc0dd45STomasz Duszynski`allowlist`. 71ecc0dd45STomasz Duszynski 72d0b8a4e1STomasz DuszynskiRespective queue needs to be configured with ``rte_rawdev_queue_setup()``. This 73d0b8a4e1STomasz Duszynskicall barely exports GPIO to userspace. 74d0b8a4e1STomasz Duszynski 75d0b8a4e1STomasz DuszynskiTo perform actual data transfer use standard ``rte_rawdev_enqueue_buffers()`` 76d0b8a4e1STomasz Duszynskiand ``rte_rawdev_dequeue_buffers()`` APIs. Not all messages produce sensible 77d0b8a4e1STomasz Duszynskiresponses hence dequeueing is not always necessary. 78633dae69STomasz Duszynski 79633dae69STomasz DuszynskiCNXK GPIO PMD 80633dae69STomasz Duszynski------------- 81633dae69STomasz Duszynski 82633dae69STomasz DuszynskiPMD accepts ``struct cnxk_gpio_msg`` messages which differ by type and payload. 83633dae69STomasz DuszynskiMessage types along with description are listed below. As for the usage examples 84633dae69STomasz Duszynskiplease refer to ``cnxk_gpio_selftest()``. There's a set of convenient wrappers 85633dae69STomasz Duszynskiavailable, one for each existing command. 86633dae69STomasz Duszynski 87633dae69STomasz DuszynskiSet GPIO value 88633dae69STomasz Duszynski~~~~~~~~~~~~~~ 89633dae69STomasz Duszynski 90633dae69STomasz DuszynskiMessage is used to set output to low or high. This does not work for GPIOs 91633dae69STomasz Duszynskiconfigured as input. 92633dae69STomasz Duszynski 93633dae69STomasz DuszynskiMessage must have type set to ``CNXK_GPIO_MSG_TYPE_SET_PIN_VALUE``. 94633dae69STomasz Duszynski 95633dae69STomasz DuszynskiPayload must be an integer set to 0 (low) or 1 (high). 96633dae69STomasz Duszynski 97633dae69STomasz DuszynskiConsider using ``rte_pmd_gpio_set_pin_value()`` wrapper. 98633dae69STomasz Duszynski 99633dae69STomasz DuszynskiSet GPIO edge 100633dae69STomasz Duszynski~~~~~~~~~~~~~ 101633dae69STomasz Duszynski 102633dae69STomasz DuszynskiMessage is used to set edge that triggers interrupt. 103633dae69STomasz Duszynski 104633dae69STomasz DuszynskiMessage must have type set to ``CNXK_GPIO_MSG_TYPE_SET_PIN_EDGE``. 105633dae69STomasz Duszynski 106633dae69STomasz DuszynskiPayload must be `enum cnxk_gpio_pin_edge`. 107633dae69STomasz Duszynski 108633dae69STomasz DuszynskiConsider using ``rte_pmd_gpio_set_pin_edge()`` wrapper. 109633dae69STomasz Duszynski 110633dae69STomasz DuszynskiSet GPIO direction 111633dae69STomasz Duszynski~~~~~~~~~~~~~~~~~~ 112633dae69STomasz Duszynski 113633dae69STomasz DuszynskiMessage is used to change GPIO direction to either input or output. 114633dae69STomasz Duszynski 115633dae69STomasz DuszynskiMessage must have type set to ``CNXK_GPIO_MSG_TYPE_SET_PIN_DIR``. 116633dae69STomasz Duszynski 117633dae69STomasz DuszynskiPayload must be `enum cnxk_gpio_pin_dir`. 118633dae69STomasz Duszynski 119633dae69STomasz DuszynskiConsider using ``rte_pmd_gpio_set_pin_dir()`` wrapper. 120633dae69STomasz Duszynski 121633dae69STomasz DuszynskiSet GPIO active low 122633dae69STomasz Duszynski~~~~~~~~~~~~~~~~~~~ 123633dae69STomasz Duszynski 124633dae69STomasz DuszynskiMessage is used to set whether pin is active low. 125633dae69STomasz Duszynski 126633dae69STomasz DuszynskiMessage must have type set to ``CNXK_GPIO_MSG_TYPE_SET_PIN_ACTIVE_LOW``. 127633dae69STomasz Duszynski 128633dae69STomasz DuszynskiPayload must be an integer set to 0 or 1. The latter activates inversion. 129633dae69STomasz Duszynski 130633dae69STomasz DuszynskiConsider using ``rte_pmd_gpio_set_pin_active_low()`` wrapper. 131633dae69STomasz Duszynski 132633dae69STomasz DuszynskiGet GPIO value 133633dae69STomasz Duszynski~~~~~~~~~~~~~~ 134633dae69STomasz Duszynski 135633dae69STomasz DuszynskiMessage is used to read GPIO value. Value can be 0 (low) or 1 (high). 136633dae69STomasz Duszynski 137633dae69STomasz DuszynskiMessage must have type set to ``CNXK_GPIO_MSG_TYPE_GET_PIN_VALUE``. 138633dae69STomasz Duszynski 139633dae69STomasz DuszynskiPayload contains integer set to either 0 or 1. 140633dae69STomasz Duszynski 141633dae69STomasz DuszynskiConsider using ``rte_pmd_gpio_get_pin_value()`` wrapper. 142633dae69STomasz Duszynski 143633dae69STomasz DuszynskiGet GPIO edge 144633dae69STomasz Duszynski~~~~~~~~~~~~~ 145633dae69STomasz Duszynski 146633dae69STomasz DuszynskiMessage is used to read GPIO edge. 147633dae69STomasz Duszynski 148633dae69STomasz DuszynskiMessage must have type set to ``CNXK_GPIO_MSG_TYPE_GET_PIN_EDGE``. 149633dae69STomasz Duszynski 150633dae69STomasz DuszynskiPayload contains `enum cnxk_gpio_pin_edge`. 151633dae69STomasz Duszynski 152633dae69STomasz DuszynskiConsider using ``rte_pmd_gpio_get_pin_edge()`` wrapper. 153633dae69STomasz Duszynski 154633dae69STomasz DuszynskiGet GPIO direction 155633dae69STomasz Duszynski~~~~~~~~~~~~~~~~~~ 156633dae69STomasz Duszynski 157633dae69STomasz DuszynskiMessage is used to read GPIO direction. 158633dae69STomasz Duszynski 159633dae69STomasz DuszynskiMessage must have type set to ``CNXK_GPIO_MSG_TYPE_GET_PIN_DIR``. 160633dae69STomasz Duszynski 161633dae69STomasz DuszynskiPayload contains `enum cnxk_gpio_pin_dir`. 162633dae69STomasz Duszynski 163633dae69STomasz DuszynskiConsider using ``rte_pmd_gpio_get_pin_dir()`` wrapper. 164633dae69STomasz Duszynski 165633dae69STomasz DuszynskiGet GPIO active low 166633dae69STomasz Duszynski~~~~~~~~~~~~~~~~~~~ 167633dae69STomasz Duszynski 168633dae69STomasz DuszynskiMessage is used check whether inverted logic is active. 169633dae69STomasz Duszynski 170633dae69STomasz DuszynskiMessage must have type set to ``CNXK_GPIO_MSG_TYPE_GET_PIN_ACTIVE_LOW``. 171633dae69STomasz Duszynski 172633dae69STomasz DuszynskiPayload contains an integer set to 0 or 1. The latter means inverted logic 173633dae69STomasz Duszynskiis turned on. 174633dae69STomasz Duszynski 175633dae69STomasz DuszynskiConsider using ``rte_pmd_gpio_get_pin_active_low()`` wrapper. 176aa22c0f3STomasz Duszynski 177aa22c0f3STomasz DuszynskiRequest interrupt 178aa22c0f3STomasz Duszynski~~~~~~~~~~~~~~~~~ 179aa22c0f3STomasz Duszynski 180aa22c0f3STomasz DuszynskiMessage is used to install custom interrupt handler. 181aa22c0f3STomasz Duszynski 182aa22c0f3STomasz DuszynskiMessage must have type set to ``CNXK_GPIO_MSG_TYPE_REGISTER_IRQ``. 183aa22c0f3STomasz Duszynski 184aa22c0f3STomasz DuszynskiPayload needs to be set to ``struct cnxk_gpio_irq`` which describes interrupt 185aa22c0f3STomasz Duszynskibeing requested. 186aa22c0f3STomasz Duszynski 187aa22c0f3STomasz DuszynskiConsider using ``rte_pmd_gpio_register_gpio()`` wrapper. 188aa22c0f3STomasz Duszynski 189aa22c0f3STomasz DuszynskiFree interrupt 190aa22c0f3STomasz Duszynski~~~~~~~~~~~~~~ 191aa22c0f3STomasz Duszynski 192aa22c0f3STomasz DuszynskiMessage is used to remove installed interrupt handler. 193aa22c0f3STomasz Duszynski 194aa22c0f3STomasz DuszynskiMessage must have type set to ``CNXK_GPIO_MSG_TYPE_UNREGISTER_IRQ``. 195aa22c0f3STomasz Duszynski 196aa22c0f3STomasz DuszynskiConsider using ``rte_pmd_gpio_unregister_gpio()`` wrapper. 1970e6557b4STomasz Duszynski 1980e6557b4STomasz DuszynskiSelf test 1990e6557b4STomasz Duszynski--------- 2000e6557b4STomasz Duszynski 2010e6557b4STomasz DuszynskiOn EAL initialization CNXK GPIO device will be probed and populated into 2020e6557b4STomasz Duszynskithe list of raw devices on condition ``--vdev=cnxk_gpio,gpiochip=<number>`` was 2030e6557b4STomasz Duszynskipassed. ``rte_rawdev_get_dev_id("CNXK_GPIO")`` returns unique device id. Use 2040e6557b4STomasz Duszynskithis identifier for further rawdev function calls. 2050e6557b4STomasz Duszynski 2060e6557b4STomasz DuszynskiSelftest rawdev API can be used to verify the PMD functionality. Note it blindly 2070e6557b4STomasz Duszynskiassumes that all GPIOs are controllable so some errors during test are expected. 208