Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.2.
  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
 26define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)')
 27define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))')
 28
 29ifdef(`include_code', `
 30// Error codes
 31define(`E_BAD_COMMAND', 0x01)
 32define(`E_CMD_OVERFLOW', 0x02)
 33
 34// Util macros to help with debugging ucode hangs etc
 35define(`T_WAIT', 0)
 36define(`T_MMCTX', 1)
 37define(`T_STRWAIT', 2)
 38define(`T_STRINIT', 3)
 39define(`T_AUTO', 4)
 40define(`T_CHAN', 5)
 41define(`T_LOAD', 6)
 42define(`T_SAVE', 7)
 43define(`T_LCHAN', 8)
 44define(`T_LCTXH', 9)
 45
 46define(`trace_set', `
 47	mov $r8 0x83c
 48	shl b32 $r8 6
 49	clear b32 $r9
 50	bset $r9 $1
 51	iowr I[$r8 + 0x000] $r9		// CC_SCRATCH[7]
 52')
 53
 54define(`trace_clr', `
 55	mov $r8 0x85c
 56	shl b32 $r8 6
 57	clear b32 $r9
 58	bset $r9 $1
 59	iowr I[$r8 + 0x000] $r9		// CC_SCRATCH[7]
 60')
 61
 62// queue_put - add request to queue
 63//
 64// In : $r13 queue pointer
 65//	$r14 command
 66//	$r15 data
 67//
 68queue_put:
 69	// make sure we have space..
 70	ld b32 $r8 D[$r13 + 0x0]	// GET
 71	ld b32 $r9 D[$r13 + 0x4]	// PUT
 72	xor $r8 8
 73	cmpu b32 $r8 $r9
 74	bra ne queue_put_next
 75		mov $r15 E_CMD_OVERFLOW
 76		call error
 77		ret
 78
 79	// store cmd/data on queue
 80	queue_put_next:
 81	and $r8 $r9 7
 82	shl b32 $r8 3
 83	add b32 $r8 $r13
 84	add b32 $r8 8
 85	st b32 D[$r8 + 0x0] $r14
 86	st b32 D[$r8 + 0x4] $r15
 87
 88	// update PUT
 89	add b32 $r9 1
 90	and $r9 0xf
 91	st b32 D[$r13 + 0x4] $r9
 92	ret
 93
 94// queue_get - fetch request from queue
 95//
 96// In : $r13 queue pointer
 97//
 98// Out:	$p1  clear on success (data available)
 99//	$r14 command
100// 	$r15 data
101//
102queue_get:
103	bset $flags $p1
104	ld b32 $r8 D[$r13 + 0x0]	// GET
105	ld b32 $r9 D[$r13 + 0x4]	// PUT
106	cmpu b32 $r8 $r9
107	bra e queue_get_done
108		// fetch first cmd/data pair
109		and $r9 $r8 7
110		shl b32 $r9 3
111		add b32 $r9 $r13
112		add b32 $r9 8
113		ld b32 $r14 D[$r9 + 0x0]
114		ld b32 $r15 D[$r9 + 0x4]
115
116		// update GET
117		add b32 $r8 1
118		and $r8 0xf
119		st b32 D[$r13 + 0x0] $r8
120		bclr $flags $p1
121queue_get_done:
122	ret
123
124// nv_rd32 - read 32-bit value from nv register
125//
126// In : $r14 register
127// Out: $r15 value
128//
129nv_rd32:
130	mov $r11 0x728
131	shl b32 $r11 6
132	mov b32 $r12 $r14
133	bset $r12 31			// MMIO_CTRL_PENDING
134	iowr I[$r11 + 0x000] $r12	// MMIO_CTRL
135	nv_rd32_wait:
136		iord $r12 I[$r11 + 0x000]
137		xbit $r12 $r12 31
138		bra ne nv_rd32_wait
139	mov $r10 6			// DONE_MMIO_RD
140	call wait_doneo
141	iord $r15 I[$r11 + 0x100]	// MMIO_RDVAL
142	ret
143
144// nv_wr32 - write 32-bit value to nv register
145//
146// In : $r14 register
147//      $r15 value
148//
149nv_wr32:
150	mov $r11 0x728
151	shl b32 $r11 6
152	iowr I[$r11 + 0x200] $r15	// MMIO_WRVAL
153	mov b32 $r12 $r14
154	bset $r12 31			// MMIO_CTRL_PENDING
155	bset $r12 30			// MMIO_CTRL_WRITE
156	iowr I[$r11 + 0x000] $r12	// MMIO_CTRL
157	nv_wr32_wait:
158		iord $r12 I[$r11 + 0x000]
159		xbit $r12 $r12 31
160		bra ne nv_wr32_wait
161	ret
162
163// (re)set watchdog timer
164//
165// In : $r15 timeout
166//
167watchdog_reset:
168	mov $r8 0x430
169	shl b32 $r8 6
170	bset $r15 31
171	iowr I[$r8 + 0x000] $r15
172	ret
173
174// clear watchdog timer
175watchdog_clear:
176	mov $r8 0x430
177	shl b32 $r8 6
178	iowr I[$r8 + 0x000] $r0
179	ret
180
181// wait_done{z,o} - wait on FUC_DONE bit to become clear/set
182//
183// In : $r10 bit to wait on
184//
185define(`wait_done', `
186$1:
187	trace_set(T_WAIT);
188	mov $r8 0x818
189	shl b32 $r8 6
190	iowr I[$r8 + 0x000] $r10	// CC_SCRATCH[6] = wait bit
191	wait_done_$1:
192		mov $r8 0x400
193		shl b32 $r8 6
194		iord $r8 I[$r8 + 0x000]	// DONE
195		xbit $r8 $r8 $r10
196		bra $2 wait_done_$1
197	trace_clr(T_WAIT)
198	ret
199')
200wait_done(wait_donez, ne)
201wait_done(wait_doneo, e)
202
203// mmctx_size - determine size of a mmio list transfer
204//
205// In : $r14 mmio list head
206//      $r15 mmio list tail
207// Out: $r15 transfer size (in bytes)
208//
209mmctx_size:
210	clear b32 $r9
211	nv_mmctx_size_loop:
212		ld b32 $r8 D[$r14]
213		shr b32 $r8 26
214		add b32 $r8 1
215		shl b32 $r8 2
216		add b32 $r9 $r8
217		add b32 $r14 4
218		cmpu b32 $r14 $r15
219		bra ne nv_mmctx_size_loop
220	mov b32 $r15 $r9
221	ret
222
223// mmctx_xfer - execute a list of mmio transfers
224//
225// In : $r10 flags
226//		bit 0: direction (0 = save, 1 = load)
227//		bit 1: set if first transfer
228//		bit 2: set if last transfer
229//	$r11 base
230//	$r12 mmio list head
231//	$r13 mmio list tail
232//	$r14 multi_stride
233//	$r15 multi_mask
234//
235mmctx_xfer:
236	trace_set(T_MMCTX)
237	mov $r8 0x710
238	shl b32 $r8 6
239	clear b32 $r9
240	or $r11 $r11
241	bra e mmctx_base_disabled
242		iowr I[$r8 + 0x000] $r11	// MMCTX_BASE
243		bset $r9 0			// BASE_EN
244	mmctx_base_disabled:
245	or $r14 $r14
246	bra e mmctx_multi_disabled
247		iowr I[$r8 + 0x200] $r14 	// MMCTX_MULTI_STRIDE
248		iowr I[$r8 + 0x300] $r15 	// MMCTX_MULTI_MASK
249		bset $r9 1			// MULTI_EN
250	mmctx_multi_disabled:
251	add b32 $r8 0x100
252
253	xbit $r11 $r10 0
254	shl b32 $r11 16			// DIR
255	bset $r11 12			// QLIMIT = 0x10
256	xbit $r14 $r10 1
257	shl b32 $r14 17
258	or $r11 $r14			// START_TRIGGER
259	iowr I[$r8 + 0x000] $r11	// MMCTX_CTRL
260
261	// loop over the mmio list, and send requests to the hw
262	mmctx_exec_loop:
263		// wait for space in mmctx queue
264		mmctx_wait_free:
265			iord $r14 I[$r8 + 0x000] // MMCTX_CTRL
266			and $r14 0x1f
267			bra e mmctx_wait_free
268
269		// queue up an entry
270		ld b32 $r14 D[$r12]
271		or $r14 $r9
272		iowr I[$r8 + 0x300] $r14
273		add b32 $r12 4
274		cmpu b32 $r12 $r13
275		bra ne mmctx_exec_loop
276
277	xbit $r11 $r10 2
278	bra ne mmctx_stop
279		// wait for queue to empty
280		mmctx_fini_wait:
281			iord $r11 I[$r8 + 0x000]	// MMCTX_CTRL
282			and $r11 0x1f
283			cmpu b32 $r11 0x10
284			bra ne mmctx_fini_wait
285		mov $r10 2				// DONE_MMCTX
286		call wait_donez
287		bra mmctx_done
288	mmctx_stop:
289		xbit $r11 $r10 0
290		shl b32 $r11 16			// DIR
291		bset $r11 12			// QLIMIT = 0x10
292		bset $r11 18			// STOP_TRIGGER
293		iowr I[$r8 + 0x000] $r11	// MMCTX_CTRL
294		mmctx_stop_wait:
295			// wait for STOP_TRIGGER to clear
296			iord $r11 I[$r8 + 0x000] // MMCTX_CTRL
297			xbit $r11 $r11 18
298			bra ne mmctx_stop_wait
299	mmctx_done:
300	trace_clr(T_MMCTX)
301	ret
302
303// Wait for DONE_STRAND
304//
305strand_wait:
306	push $r10
307	mov $r10 2
308	call wait_donez
309	pop $r10
310	ret
311
312// unknown - call before issuing strand commands
313//
314strand_pre:
315	mov $r8 0x4afc
316	sethi $r8 0x20000
317	mov $r9 0xc
318	iowr I[$r8] $r9
319	call strand_wait
320	ret
321
322// unknown - call after issuing strand commands
323//
324strand_post:
325	mov $r8 0x4afc
326	sethi $r8 0x20000
327	mov $r9 0xd
328	iowr I[$r8] $r9
329	call strand_wait
330	ret
331
332// Selects strand set?!
333//
334// In: $r14 id
335//
336strand_set:
337	mov $r10 0x4ffc
338	sethi $r10 0x20000
339	sub b32 $r11 $r10 0x500
340	mov $r12 0xf
341	iowr I[$r10 + 0x000] $r12		// 0x93c = 0xf
342	mov $r12 0xb
343	iowr I[$r11 + 0x000] $r12		// 0x928 = 0xb
344	call strand_wait
345	iowr I[$r10 + 0x000] $r14		// 0x93c = <id>
346	mov $r12 0xa
347	iowr I[$r11 + 0x000] $r12		// 0x928 = 0xa
348	call strand_wait
349	ret
350
351// Initialise strand context data
352//
353// In : $r15 context base
354// Out: $r15 context size (in bytes)
355//
356// Strandset(?) 3 hardcoded currently
357//
358strand_ctx_init:
359	trace_set(T_STRINIT)
360	call strand_pre
361	mov $r14 3
362	call strand_set
363	mov $r10 0x46fc
364	sethi $r10 0x20000
365	add b32 $r11 $r10 0x400
366	iowr I[$r10 + 0x100] $r0	// STRAND_FIRST_GENE = 0
367	mov $r12 1
368	iowr I[$r11 + 0x000] $r12	// STRAND_CMD = LATCH_FIRST_GENE
369	call strand_wait
370	sub b32 $r12 $r0 1
371	iowr I[$r10 + 0x000] $r12	// STRAND_GENE_CNT = 0xffffffff
372	mov $r12 2
373	iowr I[$r11 + 0x000] $r12	// STRAND_CMD = LATCH_GENE_CNT
374	call strand_wait
375	call strand_post
376
377	// read the size of each strand, poke the context offset of
378	// each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry
379	// about it later then.
380	mov $r8 0x880
381	shl b32 $r8 6
382	iord $r9 I[$r8 + 0x000]		// STRANDS
383	add b32 $r8 0x2200
384	shr b32 $r14 $r15 8
385	ctx_init_strand_loop:
386		iowr I[$r8 + 0x000] $r14	// STRAND_SAVE_SWBASE
387		iowr I[$r8 + 0x100] $r14	// STRAND_LOAD_SWBASE
388		iord $r10 I[$r8 + 0x200]	// STRAND_SIZE
389		shr b32 $r10 6
390		add b32 $r10 1
391		add b32 $r14 $r10
392		add b32 $r8 4
393		sub b32 $r9 1
394		bra ne ctx_init_strand_loop
395
396	shl b32 $r14 8
397	sub b32 $r15 $r14 $r15
398	trace_clr(T_STRINIT)
399	ret
400')