| | 265 | [=#reset] |
| | 266 | = PCIe Reset |
| | 267 | |
| | 268 | PCIe reset is controlled by the driver and the devices are sensitive to this reset. Typically the signal is named PERST#. |
| | 269 | |
| | 270 | Reset signals are routed to the FSA/Mini-PCIe sockets. |
| | 271 | |
| | 272 | On boards without a switch this is typically a GPIO and on boards with a PCIe switch a GPIO drives the PERST# of the switch and the switch automatically controls the PERST# signal going to each down-stream socket and they can not be independently controlled. |
| | 273 | |
| | 274 | |
| | 275 | |
| | 276 | |
| | 277 | === Manual Control of PCIe Reset |
| | 278 | |
| | 279 | For very special circumstances, it may be desired to manually control the PERST# (active low) signal. Note that other things may be on the PCIe bus, such as Ethernet, etc. Many devices cannot be reset on a live board, but rather it's part of a special sequencing at the time of boot. |
| | 280 | |
| | 281 | You can remove the reset-gpio property from the device-tree for the PCI node so that the PCI driver won't be able to toggle it. This means you will need to drive it manually. Additionally you need to remove the PCI devices from the kernel before you toggle reset, then trigger the kernel to rescan. |
| | 282 | |
| | 283 | You need to know the dt path for the PCI controller (which varies per SoC) and the GPIO mapped to PERST# (which varies per board). Both of these things can be determined by looking at the device-tree. |
| | 284 | |
| | 285 | Example: using an Venice GW72xx imx8mm-gw72xx-0x to remove PERST# from the kernel driver to allow toggling it manually in userspace. |
| | 286 | |
| | 287 | U-Boot: |
| | 288 | {{{ |
| | 289 | setenv preboot "$preboot; gpio set GPIO4_6" # imx8mm-gw72xx PERST# is GPIO4_6 and is low on powerup; drive high |
| | 290 | setenv fixfdt 'fdt addr $fdt_addr_r && fdt rm /soc@0/pcie@33800000 reset-gpio' # remove PERST# from driver for imx8mm |
| | 291 | saveenv |
| | 292 | boot |
| | 293 | }}} |
| | 294 | |
| | 295 | Linux: |
| | 296 | {{{ |
| | 297 | # verify reset-gpio is missing from the dt |
| | 298 | ls /proc/device-tree/soc@0/pcie@33800000/reset-gpio |
| | 299 | # verify your PCI devices enumerated |
| | 300 | lspci |
| | 301 | # enable console printk so we can see enumeration |
| | 302 | echo 8 > /proc/sys/kernel/printk |
| | 303 | # remove pci devices from kernel |
| | 304 | for dev in /sys/bus/pci/devices/*; do echo 1 | tee "$dev/remove"; done |
| | 305 | # toggle GPIO |
| | 306 | gpioset gpiochip3 6=0; sleep 1; gpioset gpiochip3 6=1 |
| | 307 | # trigger kernel to rescan |
| | 308 | echo 1 > /sys/bus/pci/rescan |
| | 309 | }}} |
| | 310 | |
| | 311 | While this will fundamentally reset devices that use PERST# it is not guaranteed to not cause any issues with kernel or userspace software as those devices disappear and reappear. You will need to test this to verify it suits your needs. |
| | 312 | |
| | 313 | |