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