mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
4.3 KiB
170 lines
4.3 KiB
.. SPDX-License-Identifier: GPL-2.0 |
|
|
|
======================== |
|
Spear PCIe Gadget Driver |
|
======================== |
|
|
|
Author |
|
====== |
|
Pratyush Anand ([email protected]) |
|
|
|
Location |
|
======== |
|
driver/misc/spear13xx_pcie_gadget.c |
|
|
|
Supported Chip: |
|
=============== |
|
SPEAr1300 |
|
SPEAr1310 |
|
|
|
Menuconfig option: |
|
================== |
|
Device Drivers |
|
Misc devices |
|
PCIe gadget support for SPEAr13XX platform |
|
|
|
purpose |
|
======= |
|
This driver has several nodes which can be read/written by configfs interface. |
|
Its main purpose is to configure selected dual mode PCIe controller as device |
|
and then program its various registers to configure it as a particular device |
|
type. This driver can be used to show spear's PCIe device capability. |
|
|
|
Description of different nodes: |
|
=============================== |
|
|
|
read behavior of nodes: |
|
----------------------- |
|
|
|
=============== ============================================================== |
|
link gives ltssm status. |
|
int_type type of supported interrupt |
|
no_of_msi zero if MSI is not enabled by host. A positive value is the |
|
number of MSI vector granted. |
|
vendor_id returns programmed vendor id (hex) |
|
device_id returns programmed device id(hex) |
|
bar0_size: returns size of bar0 in hex. |
|
bar0_address returns address of bar0 mapped area in hex. |
|
bar0_rw_offset returns offset of bar0 for which bar0_data will return value. |
|
bar0_data returns data at bar0_rw_offset. |
|
=============== ============================================================== |
|
|
|
write behavior of nodes: |
|
------------------------ |
|
|
|
=============== ================================================================ |
|
link write UP to enable ltsmm DOWN to disable |
|
int_type write interrupt type to be configured and (int_type could be |
|
INTA, MSI or NO_INT). Select MSI only when you have programmed |
|
no_of_msi node. |
|
no_of_msi number of MSI vector needed. |
|
inta write 1 to assert INTA and 0 to de-assert. |
|
send_msi write MSI vector to be sent. |
|
vendor_id write vendor id(hex) to be programmed. |
|
device_id write device id(hex) to be programmed. |
|
bar0_size write size of bar0 in hex. default bar0 size is 1000 (hex) |
|
bytes. |
|
bar0_address write address of bar0 mapped area in hex. (default mapping of |
|
bar0 is SYSRAM1(E0800000). Always program bar size before bar |
|
address. Kernel might modify bar size and address for alignment, |
|
so read back bar size and address after writing to cross check. |
|
bar0_rw_offset write offset of bar0 for which bar0_data will write value. |
|
bar0_data write data to be written at bar0_rw_offset. |
|
=============== ================================================================ |
|
|
|
Node programming example |
|
======================== |
|
|
|
Program all PCIe registers in such a way that when this device is connected |
|
to the PCIe host, then host sees this device as 1MB RAM. |
|
|
|
:: |
|
|
|
#mount -t configfs none /Config |
|
|
|
For nth PCIe Device Controller:: |
|
|
|
# cd /config/pcie_gadget.n/ |
|
|
|
Now you have all the nodes in this directory. |
|
program vendor id as 0x104a:: |
|
|
|
# echo 104A >> vendor_id |
|
|
|
program device id as 0xCD80:: |
|
|
|
# echo CD80 >> device_id |
|
|
|
program BAR0 size as 1MB:: |
|
|
|
# echo 100000 >> bar0_size |
|
|
|
check for programmed bar0 size:: |
|
|
|
# cat bar0_size |
|
|
|
Program BAR0 Address as DDR (0x2100000). This is the physical address of |
|
memory, which is to be made visible to PCIe host. Similarly any other peripheral |
|
can also be made visible to PCIe host. E.g., if you program base address of UART |
|
as BAR0 address then when this device will be connected to a host, it will be |
|
visible as UART. |
|
|
|
:: |
|
|
|
# echo 2100000 >> bar0_address |
|
|
|
program interrupt type : INTA:: |
|
|
|
# echo INTA >> int_type |
|
|
|
go for link up now:: |
|
|
|
# echo UP >> link |
|
|
|
It will have to be insured that, once link up is done on gadget, then only host |
|
is initialized and start to search PCIe devices on its port. |
|
|
|
:: |
|
|
|
/*wait till link is up*/ |
|
# cat link |
|
|
|
Wait till it returns UP. |
|
|
|
To assert INTA:: |
|
|
|
# echo 1 >> inta |
|
|
|
To de-assert INTA:: |
|
|
|
# echo 0 >> inta |
|
|
|
if MSI is to be used as interrupt, program no of msi vector needed (say4):: |
|
|
|
# echo 4 >> no_of_msi |
|
|
|
select MSI as interrupt type:: |
|
|
|
# echo MSI >> int_type |
|
|
|
go for link up now:: |
|
|
|
# echo UP >> link |
|
|
|
wait till link is up:: |
|
|
|
# cat link |
|
|
|
An application can repetitively read this node till link is found UP. It can |
|
sleep between two read. |
|
|
|
wait till msi is enabled:: |
|
|
|
# cat no_of_msi |
|
|
|
Should return 4 (number of requested MSI vector) |
|
|
|
to send msi vector 2:: |
|
|
|
# echo 2 >> send_msi |
|
# cd -
|
|
|