com.fuc revision 60a4acd7c9a5cde05ec17685072504f991fea321
1/* fuc microcode util functions for nvc0 PGRAPH
2 *
3 * Copyright 2011 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors: Ben Skeggs
24 */
25
26#ifdef INCLUDE_CODE
27// queue_put - add request to queue
28//
29// In : $r13 queue pointer
30//	$r14 command
31//	$r15 data
32//
33queue_put:
34	// make sure we have space..
35	ld b32 $r8 D[$r13 + 0x0]	// GET
36	ld b32 $r9 D[$r13 + 0x4]	// PUT
37	xor $r8 8
38	cmpu b32 $r8 $r9
39	bra ne #queue_put_next
40		mov $r15 E_CMD_OVERFLOW
41		call #error
42		ret
43
44	// store cmd/data on queue
45	queue_put_next:
46	and $r8 $r9 7
47	shl b32 $r8 3
48	add b32 $r8 $r13
49	add b32 $r8 8
50	st b32 D[$r8 + 0x0] $r14
51	st b32 D[$r8 + 0x4] $r15
52
53	// update PUT
54	add b32 $r9 1
55	and $r9 0xf
56	st b32 D[$r13 + 0x4] $r9
57	ret
58
59// queue_get - fetch request from queue
60//
61// In : $r13 queue pointer
62//
63// Out:	$p1  clear on success (data available)
64//	$r14 command
65// 	$r15 data
66//
67queue_get:
68	bset $flags $p1
69	ld b32 $r8 D[$r13 + 0x0]	// GET
70	ld b32 $r9 D[$r13 + 0x4]	// PUT
71	cmpu b32 $r8 $r9
72	bra e #queue_get_done
73		// fetch first cmd/data pair
74		and $r9 $r8 7
75		shl b32 $r9 3
76		add b32 $r9 $r13
77		add b32 $r9 8
78		ld b32 $r14 D[$r9 + 0x0]
79		ld b32 $r15 D[$r9 + 0x4]
80
81		// update GET
82		add b32 $r8 1
83		and $r8 0xf
84		st b32 D[$r13 + 0x0] $r8
85		bclr $flags $p1
86queue_get_done:
87	ret
88
89// nv_rd32 - read 32-bit value from nv register
90//
91// In : $r14 register
92// Out: $r15 value
93//
94nv_rd32:
95	mov $r11 0x728
96	shl b32 $r11 6
97	mov b32 $r12 $r14
98	bset $r12 31			// MMIO_CTRL_PENDING
99	iowr I[$r11 + 0x000] $r12	// MMIO_CTRL
100	nv_rd32_wait:
101		iord $r12 I[$r11 + 0x000]
102		xbit $r12 $r12 31
103		bra ne #nv_rd32_wait
104	mov $r10 6			// DONE_MMIO_RD
105	call #wait_doneo
106	iord $r15 I[$r11 + 0x100]	// MMIO_RDVAL
107	ret
108
109// nv_wr32 - write 32-bit value to nv register
110//
111// In : $r14 register
112//      $r15 value
113//
114nv_wr32:
115	mov $r11 0x728
116	shl b32 $r11 6
117	iowr I[$r11 + 0x200] $r15	// MMIO_WRVAL
118	mov b32 $r12 $r14
119	bset $r12 31			// MMIO_CTRL_PENDING
120	bset $r12 30			// MMIO_CTRL_WRITE
121	iowr I[$r11 + 0x000] $r12	// MMIO_CTRL
122	nv_wr32_wait:
123		iord $r12 I[$r11 + 0x000]
124		xbit $r12 $r12 31
125		bra ne #nv_wr32_wait
126	ret
127
128// (re)set watchdog timer
129//
130// In : $r15 timeout
131//
132watchdog_reset:
133	mov $r8 0x430
134	shl b32 $r8 6
135	bset $r15 31
136	iowr I[$r8 + 0x000] $r15
137	ret
138
139// clear watchdog timer
140watchdog_clear:
141	mov $r8 0x430
142	shl b32 $r8 6
143	iowr I[$r8 + 0x000] $r0
144	ret
145
146// wait_donez - wait on FUC_DONE bit to become clear
147//
148// In : $r10 bit to wait on
149//
150wait_donez:
151	trace_set(T_WAIT);
152	nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(6), 0, $r10)
153	wait_donez_ne:
154		nv_iord($r8, NV_PGRAPH_FECS_SIGNAL, 0)
155		xbit $r8 $r8 $r10
156		bra ne #wait_donez_ne
157	trace_clr(T_WAIT)
158	ret
159
160// wait_doneo - wait on FUC_DONE bit to become set
161//
162// In : $r10 bit to wait on
163//
164wait_doneo:
165	trace_set(T_WAIT);
166	mov $r8 0x818
167	shl b32 $r8 6
168	iowr I[$r8 + 0x000] $r10
169	wait_doneo_e:
170		mov $r8 0x400
171		shl b32 $r8 6
172		iord $r8 I[$r8 + 0x000]
173		xbit $r8 $r8 $r10
174		bra e #wait_doneo_e
175	trace_clr(T_WAIT)
176	ret
177
178// mmctx_size - determine size of a mmio list transfer
179//
180// In : $r14 mmio list head
181//      $r15 mmio list tail
182// Out: $r15 transfer size (in bytes)
183//
184mmctx_size:
185	clear b32 $r9
186	nv_mmctx_size_loop:
187		ld b32 $r8 D[$r14]
188		shr b32 $r8 26
189		add b32 $r8 1
190		shl b32 $r8 2
191		add b32 $r9 $r8
192		add b32 $r14 4
193		cmpu b32 $r14 $r15
194		bra ne #nv_mmctx_size_loop
195	mov b32 $r15 $r9
196	ret
197
198// mmctx_xfer - execute a list of mmio transfers
199//
200// In : $r10 flags
201//		bit 0: direction (0 = save, 1 = load)
202//		bit 1: set if first transfer
203//		bit 2: set if last transfer
204//	$r11 base
205//	$r12 mmio list head
206//	$r13 mmio list tail
207//	$r14 multi_stride
208//	$r15 multi_mask
209//
210mmctx_xfer:
211	trace_set(T_MMCTX)
212	mov $r8 0x710
213	shl b32 $r8 6
214	clear b32 $r9
215	or $r11 $r11
216	bra e #mmctx_base_disabled
217		iowr I[$r8 + 0x000] $r11	// MMCTX_BASE
218		bset $r9 0			// BASE_EN
219	mmctx_base_disabled:
220	or $r14 $r14
221	bra e #mmctx_multi_disabled
222		iowr I[$r8 + 0x200] $r14 	// MMCTX_MULTI_STRIDE
223		iowr I[$r8 + 0x300] $r15 	// MMCTX_MULTI_MASK
224		bset $r9 1			// MULTI_EN
225	mmctx_multi_disabled:
226	add b32 $r8 0x100
227
228	xbit $r11 $r10 0
229	shl b32 $r11 16			// DIR
230	bset $r11 12			// QLIMIT = 0x10
231	xbit $r14 $r10 1
232	shl b32 $r14 17
233	or $r11 $r14			// START_TRIGGER
234	iowr I[$r8 + 0x000] $r11	// MMCTX_CTRL
235
236	// loop over the mmio list, and send requests to the hw
237	mmctx_exec_loop:
238		// wait for space in mmctx queue
239		mmctx_wait_free:
240			iord $r14 I[$r8 + 0x000] // MMCTX_CTRL
241			and $r14 0x1f
242			bra e #mmctx_wait_free
243
244		// queue up an entry
245		ld b32 $r14 D[$r12]
246		or $r14 $r9
247		iowr I[$r8 + 0x300] $r14
248		add b32 $r12 4
249		cmpu b32 $r12 $r13
250		bra ne #mmctx_exec_loop
251
252	xbit $r11 $r10 2
253	bra ne #mmctx_stop
254		// wait for queue to empty
255		mmctx_fini_wait:
256			iord $r11 I[$r8 + 0x000]	// MMCTX_CTRL
257			and $r11 0x1f
258			cmpu b32 $r11 0x10
259			bra ne #mmctx_fini_wait
260		mov $r10 2				// DONE_MMCTX
261		call #wait_donez
262		bra #mmctx_done
263	mmctx_stop:
264		xbit $r11 $r10 0
265		shl b32 $r11 16			// DIR
266		bset $r11 12			// QLIMIT = 0x10
267		bset $r11 18			// STOP_TRIGGER
268		iowr I[$r8 + 0x000] $r11	// MMCTX_CTRL
269		mmctx_stop_wait:
270			// wait for STOP_TRIGGER to clear
271			iord $r11 I[$r8 + 0x000] // MMCTX_CTRL
272			xbit $r11 $r11 18
273			bra ne #mmctx_stop_wait
274	mmctx_done:
275	trace_clr(T_MMCTX)
276	ret
277
278// Wait for DONE_STRAND
279//
280strand_wait:
281	push $r10
282	mov $r10 2
283	call #wait_donez
284	pop $r10
285	ret
286
287// unknown - call before issuing strand commands
288//
289strand_pre:
290	mov $r8 0x4afc
291	sethi $r8 0x20000
292	mov $r9 0xc
293	iowr I[$r8] $r9
294	call #strand_wait
295	ret
296
297// unknown - call after issuing strand commands
298//
299strand_post:
300	mov $r8 0x4afc
301	sethi $r8 0x20000
302	mov $r9 0xd
303	iowr I[$r8] $r9
304	call #strand_wait
305	ret
306
307// Selects strand set?!
308//
309// In: $r14 id
310//
311strand_set:
312	mov $r10 0x4ffc
313	sethi $r10 0x20000
314	sub b32 $r11 $r10 0x500
315	mov $r12 0xf
316	iowr I[$r10 + 0x000] $r12		// 0x93c = 0xf
317	mov $r12 0xb
318	iowr I[$r11 + 0x000] $r12		// 0x928 = 0xb
319	call #strand_wait
320	iowr I[$r10 + 0x000] $r14		// 0x93c = <id>
321	mov $r12 0xa
322	iowr I[$r11 + 0x000] $r12		// 0x928 = 0xa
323	call #strand_wait
324	ret
325
326// Initialise strand context data
327//
328// In : $r15 context base
329// Out: $r15 context size (in bytes)
330//
331// Strandset(?) 3 hardcoded currently
332//
333strand_ctx_init:
334	trace_set(T_STRINIT)
335	call #strand_pre
336	mov $r14 3
337	call #strand_set
338	mov $r10 0x46fc
339	sethi $r10 0x20000
340	add b32 $r11 $r10 0x400
341	iowr I[$r10 + 0x100] $r0	// STRAND_FIRST_GENE = 0
342	mov $r12 1
343	iowr I[$r11 + 0x000] $r12	// STRAND_CMD = LATCH_FIRST_GENE
344	call #strand_wait
345	sub b32 $r12 $r0 1
346	iowr I[$r10 + 0x000] $r12	// STRAND_GENE_CNT = 0xffffffff
347	mov $r12 2
348	iowr I[$r11 + 0x000] $r12	// STRAND_CMD = LATCH_GENE_CNT
349	call #strand_wait
350	call #strand_post
351
352	// read the size of each strand, poke the context offset of
353	// each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry
354	// about it later then.
355	mov $r8 0x880
356	shl b32 $r8 6
357	iord $r9 I[$r8 + 0x000]		// STRANDS
358	add b32 $r8 0x2200
359	shr b32 $r14 $r15 8
360	ctx_init_strand_loop:
361		iowr I[$r8 + 0x000] $r14	// STRAND_SAVE_SWBASE
362		iowr I[$r8 + 0x100] $r14	// STRAND_LOAD_SWBASE
363		iord $r10 I[$r8 + 0x200]	// STRAND_SIZE
364		shr b32 $r10 6
365		add b32 $r10 1
366		add b32 $r14 $r10
367		add b32 $r8 4
368		sub b32 $r9 1
369		bra ne #ctx_init_strand_loop
370
371	shl b32 $r14 8
372	sub b32 $r15 $r14 $r15
373	trace_clr(T_STRINIT)
374	ret
375#endif
376