Mauro Carvalho Chehab | 3471b9f | 2020-06-15 08:50:12 +0200 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0 |
| 2 | |
| 3 | ======================== |
| 4 | Spear PCIe Gadget Driver |
| 5 | ======================== |
| 6 | |
| 7 | Author |
| 8 | ====== |
| 9 | Pratyush Anand (pratyush.anand@gmail.com) |
| 10 | |
| 11 | Location |
| 12 | ======== |
| 13 | driver/misc/spear13xx_pcie_gadget.c |
| 14 | |
| 15 | Supported Chip: |
| 16 | =============== |
| 17 | SPEAr1300 |
| 18 | SPEAr1310 |
| 19 | |
| 20 | Menuconfig option: |
| 21 | ================== |
| 22 | Device Drivers |
| 23 | Misc devices |
| 24 | PCIe gadget support for SPEAr13XX platform |
| 25 | |
| 26 | purpose |
| 27 | ======= |
| 28 | This driver has several nodes which can be read/written by configfs interface. |
| 29 | Its main purpose is to configure selected dual mode PCIe controller as device |
| 30 | and then program its various registers to configure it as a particular device |
| 31 | type. This driver can be used to show spear's PCIe device capability. |
| 32 | |
| 33 | Description of different nodes: |
| 34 | =============================== |
| 35 | |
| 36 | read behavior of nodes: |
| 37 | ----------------------- |
| 38 | |
| 39 | =============== ============================================================== |
| 40 | link gives ltssm status. |
| 41 | int_type type of supported interrupt |
| 42 | no_of_msi zero if MSI is not enabled by host. A positive value is the |
| 43 | number of MSI vector granted. |
| 44 | vendor_id returns programmed vendor id (hex) |
| 45 | device_id returns programmed device id(hex) |
| 46 | bar0_size: returns size of bar0 in hex. |
| 47 | bar0_address returns address of bar0 mapped area in hex. |
| 48 | bar0_rw_offset returns offset of bar0 for which bar0_data will return value. |
| 49 | bar0_data returns data at bar0_rw_offset. |
| 50 | =============== ============================================================== |
| 51 | |
| 52 | write behavior of nodes: |
| 53 | ------------------------ |
| 54 | |
| 55 | =============== ================================================================ |
| 56 | link write UP to enable ltsmm DOWN to disable |
| 57 | int_type write interrupt type to be configured and (int_type could be |
| 58 | INTA, MSI or NO_INT). Select MSI only when you have programmed |
| 59 | no_of_msi node. |
| 60 | no_of_msi number of MSI vector needed. |
| 61 | inta write 1 to assert INTA and 0 to de-assert. |
| 62 | send_msi write MSI vector to be sent. |
| 63 | vendor_id write vendor id(hex) to be programmed. |
| 64 | device_id write device id(hex) to be programmed. |
| 65 | bar0_size write size of bar0 in hex. default bar0 size is 1000 (hex) |
| 66 | bytes. |
| 67 | bar0_address write address of bar0 mapped area in hex. (default mapping of |
| 68 | bar0 is SYSRAM1(E0800000). Always program bar size before bar |
| 69 | address. Kernel might modify bar size and address for alignment, |
| 70 | so read back bar size and address after writing to cross check. |
| 71 | bar0_rw_offset write offset of bar0 for which bar0_data will write value. |
| 72 | bar0_data write data to be written at bar0_rw_offset. |
| 73 | =============== ================================================================ |
| 74 | |
| 75 | Node programming example |
| 76 | ======================== |
| 77 | |
| 78 | Program all PCIe registers in such a way that when this device is connected |
| 79 | to the PCIe host, then host sees this device as 1MB RAM. |
| 80 | |
| 81 | :: |
| 82 | |
| 83 | #mount -t configfs none /Config |
| 84 | |
| 85 | For nth PCIe Device Controller:: |
| 86 | |
| 87 | # cd /config/pcie_gadget.n/ |
| 88 | |
| 89 | Now you have all the nodes in this directory. |
| 90 | program vendor id as 0x104a:: |
| 91 | |
| 92 | # echo 104A >> vendor_id |
| 93 | |
| 94 | program device id as 0xCD80:: |
| 95 | |
| 96 | # echo CD80 >> device_id |
| 97 | |
| 98 | program BAR0 size as 1MB:: |
| 99 | |
| 100 | # echo 100000 >> bar0_size |
| 101 | |
| 102 | check for programmed bar0 size:: |
| 103 | |
| 104 | # cat bar0_size |
| 105 | |
| 106 | Program BAR0 Address as DDR (0x2100000). This is the physical address of |
| 107 | memory, which is to be made visible to PCIe host. Similarly any other peripheral |
| 108 | can also be made visible to PCIe host. E.g., if you program base address of UART |
| 109 | as BAR0 address then when this device will be connected to a host, it will be |
| 110 | visible as UART. |
| 111 | |
| 112 | :: |
| 113 | |
| 114 | # echo 2100000 >> bar0_address |
| 115 | |
| 116 | program interrupt type : INTA:: |
| 117 | |
| 118 | # echo INTA >> int_type |
| 119 | |
| 120 | go for link up now:: |
| 121 | |
| 122 | # echo UP >> link |
| 123 | |
| 124 | It will have to be insured that, once link up is done on gadget, then only host |
| 125 | is initialized and start to search PCIe devices on its port. |
| 126 | |
| 127 | :: |
| 128 | |
| 129 | /*wait till link is up*/ |
| 130 | # cat link |
| 131 | |
| 132 | Wait till it returns UP. |
| 133 | |
| 134 | To assert INTA:: |
| 135 | |
| 136 | # echo 1 >> inta |
| 137 | |
| 138 | To de-assert INTA:: |
| 139 | |
| 140 | # echo 0 >> inta |
| 141 | |
| 142 | if MSI is to be used as interrupt, program no of msi vector needed (say4):: |
| 143 | |
| 144 | # echo 4 >> no_of_msi |
| 145 | |
| 146 | select MSI as interrupt type:: |
| 147 | |
| 148 | # echo MSI >> int_type |
| 149 | |
| 150 | go for link up now:: |
| 151 | |
| 152 | # echo UP >> link |
| 153 | |
| 154 | wait till link is up:: |
| 155 | |
| 156 | # cat link |
| 157 | |
| 158 | An application can repetitively read this node till link is found UP. It can |
| 159 | sleep between two read. |
| 160 | |
| 161 | wait till msi is enabled:: |
| 162 | |
| 163 | # cat no_of_msi |
| 164 | |
| 165 | Should return 4 (number of requested MSI vector) |
| 166 | |
| 167 | to send msi vector 2:: |
| 168 | |
| 169 | # echo 2 >> send_msi |
| 170 | # cd - |