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