xref: /titanic_41/usr/src/uts/sun/io/audio/drv/audiocs/audio_4231_eb2dma.c (revision 68c47f65208790c466e5e484f2293d3baed71c6a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * Platform specifc code for the EB2 DMA controller. The EB2 is a PCI bus
28  * IC that includes play and record DMA engines and an interface for
29  * the CS4231.
30  */
31 
32 #include <sys/systm.h>
33 #include <sys/ddi.h>
34 #include <sys/sunddi.h>
35 #include <sys/note.h>
36 #include <sys/audio/audio_driver.h>
37 #include "audio_4231.h"
38 
39 /*
40  * Attribute structure for the APC, used to create DMA handles.
41  */
42 static ddi_dma_attr_t eb2_dma_attr = {
43 	DMA_ATTR_V0,			/* version */
44 	0x0000000000000000LL,		/* dlim_addr_lo */
45 	0x00000000ffffffffLL,		/* dlim_addr_hi */
46 	0x0000000000ffffffLL,		/* DMA counter register */
47 	0x0000000000000001LL,		/* DMA address alignment */
48 	0x00000074,			/* 4 and 16 byte burst sizes */
49 	0x00000001,			/* min effective DMA size */
50 	0x000000000000ffffLL,		/* maximum transfer size, 8k */
51 	0x000000000000ffffLL,		/* segment boundary, 32k */
52 	0x00000001,			/* s/g list length, no s/g */
53 	0x00000001,			/* granularity of device, don't care */
54 	0				/* DMA flags */
55 };
56 
57 static ddi_device_acc_attr_t codec_attr = {
58 	DDI_DEVICE_ATTR_V0,
59 	DDI_STRUCTURE_BE_ACC,
60 	DDI_STRICTORDER_ACC
61 };
62 
63 static ddi_device_acc_attr_t eb2_attr = {
64 	DDI_DEVICE_ATTR_V0,
65 	DDI_STRUCTURE_LE_ACC,
66 	DDI_STRICTORDER_ACC
67 };
68 
69 /*
70  * DMA ops vector functions
71  */
72 static int eb2_map_regs(CS_state_t *);
73 static void eb2_unmap_regs(CS_state_t *);
74 static void eb2_reset(CS_state_t *);
75 static int eb2_start_engine(CS_engine_t *);
76 static void eb2_stop_engine(CS_engine_t *);
77 static void eb2_power(CS_state_t *, int);
78 static void eb2_reload(CS_engine_t *);
79 static uint32_t eb2_addr(CS_engine_t *);
80 
81 cs4231_dma_ops_t cs4231_eb2dma_ops = {
82 	"EB2 DMA controller",
83 	&eb2_dma_attr,
84 	eb2_map_regs,
85 	eb2_unmap_regs,
86 	eb2_reset,
87 	eb2_start_engine,
88 	eb2_stop_engine,
89 	eb2_power,
90 	eb2_reload,
91 	eb2_addr,
92 };
93 
94 /*
95  * eb2_map_regs()
96  *
97  * Description:
98  *	This routine allocates the DMA handles and the memory for the
99  *	DMA engines to use. It then binds each of the buffers to its
100  *	respective handle, getting a DMA cookie. Finally, the registers
101  *	are mapped in.
102  *
103  *	NOTE: All of the ddi_dma_... routines sleep if they cannot get
104  *		memory. This means these calls will almost always succeed.
105  *
106  * Arguments:
107  *	CS_state_t	*state		The device's state
108  *
109  * Returns:
110  *	DDI_SUCCESS		Registers successfully mapped
111  *	DDI_FAILURE		Registers not successfully mapped
112  */
113 static int
eb2_map_regs(CS_state_t * state)114 eb2_map_regs(CS_state_t *state)
115 {
116 	dev_info_t	*dip = state->cs_dip;
117 
118 	/* now, map the codec */
119 	if (ddi_regs_map_setup(dip, 0, (caddr_t *)&state->cs_regs, 0,
120 	    sizeof (cs4231_pioregs_t), &codec_attr, &CODEC_HANDLE) !=
121 	    DDI_SUCCESS) {
122 		audio_dev_warn(state->cs_adev, "failed mapping codec regs");
123 		goto error;
124 	}
125 
126 	/* next the play registers */
127 	if (ddi_regs_map_setup(dip, 1, (caddr_t *)&state->cs_eb2_regs.play, 0,
128 	    sizeof (cs4231_eb2regs_t), &eb2_attr, &EB2_PLAY_HNDL) !=
129 	    DDI_SUCCESS) {
130 		audio_dev_warn(state->cs_adev, "failed mapping play regs");
131 		goto error;
132 	}
133 	state->cs_engines[CS4231_PLAY]->ce_regsh = EB2_PLAY_HNDL;
134 	state->cs_engines[CS4231_PLAY]->ce_eb2regs = state->cs_eb2_regs.play;
135 
136 	/* now the capture registers */
137 	if (ddi_regs_map_setup(dip, 2, (caddr_t *)&state->cs_eb2_regs.record, 0,
138 	    sizeof (cs4231_eb2regs_t), &eb2_attr, &EB2_REC_HNDL) !=
139 	    DDI_SUCCESS) {
140 		audio_dev_warn(state->cs_adev, "failed mapping rec regs");
141 		goto error;
142 	}
143 	state->cs_engines[CS4231_REC]->ce_regsh = EB2_REC_HNDL;
144 	state->cs_engines[CS4231_REC]->ce_eb2regs = state->cs_eb2_regs.record;
145 
146 	/* finally the auxio register */
147 	if (ddi_regs_map_setup(dip, 3, (caddr_t *)&state->cs_eb2_regs.auxio, 0,
148 	    sizeof (uint_t), &eb2_attr, &EB2_AUXIO_HNDL) != DDI_SUCCESS) {
149 		audio_dev_warn(state->cs_adev, "failed mapping auxio reg");
150 		goto error;
151 	}
152 
153 	/* disable play and record interrupts */
154 	ddi_put32(EB2_PLAY_HNDL, &EB2_PLAY_CSR, EB2_PCLEAR_RESET_VALUE);
155 	ddi_put32(EB2_REC_HNDL, &EB2_REC_CSR, EB2_RCLEAR_RESET_VALUE);
156 
157 	return (DDI_SUCCESS);
158 
159 error:
160 	eb2_unmap_regs(state);
161 	return (DDI_FAILURE);
162 
163 }	/* eb2_map_regs() */
164 
165 /*
166  * eb2_unmap_regs()
167  *
168  * Description:
169  *	This routine unmaps the Codec's and DMA engine's registers.
170  *	It must be idempotent.
171  *
172  * Arguments:
173  *	CS_state_t	*state	The device's state
174  */
175 static void
eb2_unmap_regs(CS_state_t * state)176 eb2_unmap_regs(CS_state_t *state)
177 {
178 	if (CODEC_HANDLE)
179 		ddi_regs_map_free(&CODEC_HANDLE);
180 	if (EB2_PLAY_HNDL)
181 		ddi_regs_map_free(&EB2_PLAY_HNDL);
182 	if (EB2_REC_HNDL)
183 		ddi_regs_map_free(&EB2_REC_HNDL);
184 	if (EB2_AUXIO_HNDL)
185 		ddi_regs_map_free(&EB2_AUXIO_HNDL);
186 
187 }	/* eb2_unmap_regs() */
188 
189 /*
190  * eb2_reset()
191  *
192  * Description:
193  *	Reset both the play and record DMA engines. The engines are left
194  *	with interrupts and the DMA engine disabled.
195  *
196  * Arguments:
197  *	dev_info_t	*dip	Pointer to the device's devinfo structure
198  *	CS_state_t	*state	The device's state structure
199  */
200 static void
eb2_reset(CS_state_t * state)201 eb2_reset(CS_state_t *state)
202 {
203 	ddi_acc_handle_t	phandle = EB2_PLAY_HNDL;
204 	ddi_acc_handle_t	rhandle = EB2_REC_HNDL;
205 	uint_t			reg;
206 	int			x;
207 
208 	/* start with the play side */
209 	ddi_put32(phandle, &EB2_PLAY_CSR, EB2_RESET);
210 	/* wait for play data to drain */
211 	reg = ddi_get32(phandle, &EB2_PLAY_CSR);
212 	for (x = 0; (reg & EB2_FIFO_DRAIN) && x < CS4231_TIMEOUT; x++) {
213 		drv_usecwait(1);	/* don't beat on the bus */
214 		reg = ddi_get32(phandle, &EB2_PLAY_CSR);
215 	}
216 	/* clear the reset bit and program for chaining */
217 	ddi_put32(phandle, &EB2_PLAY_CSR, EB2_PCLEAR_RESET_VALUE);
218 
219 	/* now do the record side and program for chaining */
220 	ddi_put32(rhandle, &EB2_REC_CSR, EB2_RESET);
221 	/* wait for record data to drain */
222 	reg = ddi_get32(rhandle, &EB2_REC_CSR);
223 	for (x = 0; (reg & EB2_FIFO_DRAIN) && x < CS4231_TIMEOUT; x++) {
224 		drv_usecwait(1);	/* don't beat on the bus */
225 		reg = ddi_get32(rhandle, &EB2_REC_CSR);
226 	}
227 	/* clear the reset bit */
228 	ddi_put32(rhandle, &EB2_REC_CSR, EB2_RCLEAR_RESET_VALUE);
229 
230 }	/* eb2_reset() */
231 
232 /*
233  * eb2_start_engine()
234  *
235  * Description:
236  *	This routine starts the DMA engine.
237  *
238  *	NOTE: The state structure must be locked before this routine is called.
239  *
240  * Arguments:
241  *	CS_engine_t	*eng	The DMA engine's state structure
242  *
243  * Returns:
244  *	DDI_SUCCESS		The DMA engine was started
245  *	DDI_FAILURE		The DMA engine was not started
246  */
247 static int
eb2_start_engine(CS_engine_t * eng)248 eb2_start_engine(CS_engine_t *eng)
249 {
250 	CS_state_t		*state = eng->ce_state;
251 	ddi_acc_handle_t	handle = eng->ce_regsh;
252 	cs4231_eb2regs_t	*regs = eng->ce_eb2regs;
253 	uint_t			csr;
254 	int			x;
255 	uint32_t		reset;
256 	uint32_t		enable;
257 
258 	if (eng->ce_num == CS4231_PLAY) {
259 		reset = EB2_PCLEAR_RESET_VALUE;
260 		enable = EB2_PLAY_ENABLE;
261 	} else {
262 		reset = EB2_RCLEAR_RESET_VALUE;
263 		enable = EB2_REC_ENABLE;
264 	}
265 
266 	ASSERT(mutex_owned(&state->cs_lock));
267 
268 	/* reset the DMA engine so we have a good starting place */
269 	OR_SET_WORD(handle, &regs->eb2csr, EB2_RESET);
270 
271 	/* wait for the FIFO to drain, it should be empty */
272 	csr = ddi_get32(handle, &regs->eb2csr);
273 	for (x = 0; (csr & EB2_FIFO_DRAIN) && x < CS4231_TIMEOUT; x++) {
274 		drv_usecwait(1);	/* no reason to beat on the bus */
275 		csr = ddi_get32(handle, &regs->eb2csr);
276 	}
277 	if (x >= CS4231_TIMEOUT) {
278 		audio_dev_warn(state->cs_adev,
279 		    "timeout waiting for engine, not started!");
280 		return (DDI_FAILURE);
281 	}
282 
283 	/* now clear the RESET and EN_DMA bits */
284 	AND_SET_WORD(handle, &regs->eb2csr, ~(EB2_RESET|EB2_EN_DMA));
285 
286 	/* put into chaining mode, enable byte counts  */
287 	OR_SET_WORD(handle, &regs->eb2csr, reset);
288 
289 	/*
290 	 * Program the DMA engine.
291 	 */
292 	eb2_reload(eng);
293 
294 	/*
295 	 * Start playing before we load the next fragment.
296 	 */
297 	OR_SET_WORD(handle, &regs->eb2csr, enable);
298 
299 	/*
300 	 * Program the next address, too.
301 	 */
302 	eb2_reload(eng);
303 
304 	return (DDI_SUCCESS);
305 
306 }	/* eb2_start_engine() */
307 
308 /*
309  * eb2_stop_engine()
310  *
311  * Description:
312  *	This routine stops the DMA engine.
313  *
314  *	NOTE: The state structure must be locked before this routine is called.
315  *
316  * Arguments:
317  *	CS_engine_t	*eng	The engine to stop
318  */
319 static void
eb2_stop_engine(CS_engine_t * eng)320 eb2_stop_engine(CS_engine_t *eng)
321 {
322 	ddi_acc_handle_t	handle = eng->ce_regsh;
323 	cs4231_eb2regs_t	*regs = eng->ce_eb2regs;
324 	uint_t			csr;
325 
326 	/* shut off DMA and disable interrupts */
327 	AND_SET_WORD(handle, &regs->eb2csr, ~(EB2_EN_DMA | EB2_INT_EN));
328 
329 	csr = ddi_get32(handle, &regs->eb2csr);
330 	for (int x = 0; (csr & EB2_CYC_PENDING) && x < CS4231_TIMEOUT; x++) {
331 		drv_usecwait(1);
332 		csr = ddi_get32(handle, &regs->eb2csr);
333 	}
334 
335 	/* set the RESET bit to stop audio, also clear any TC interrupt */
336 	OR_SET_WORD(handle, &regs->eb2csr, EB2_RESET | EB2_TC);
337 
338 	/* wait for the FIFO to drain */
339 	csr = ddi_get32(handle, &regs->eb2csr);
340 	for (int x = 0; (csr & EB2_FIFO_DRAIN) && x < CS4231_TIMEOUT; x++) {
341 		drv_usecwait(1);		/* don't beat on the bus */
342 		csr = ddi_get32(handle, &regs->eb2csr);
343 	}
344 
345 	/* clear the RESET and EN_DMA bits */
346 	AND_SET_WORD(handle, &regs->eb2csr, ~(EB2_RESET|EB2_EN_DMA));
347 
348 }	/* eb2_stop_engine() */
349 
350 /*
351  * eb2_power()
352  *
353  * Description:
354  *	This routine turns the Codec on or off using the auxio register
355  *	in the eb2 device (cheerio or rio). Fortunately we don't need
356  *	to delay like we do with the APC.
357  *
358  *	NOTE: The state structure must be locked when this routine is called.
359  *
360  * Arguments:
361  *	CS_state_t	*state		Ptr to the device's state structure
362  *	int		level		Power level to set
363  */
364 static void
eb2_power(CS_state_t * state,int level)365 eb2_power(CS_state_t *state, int level)
366 {
367 	ddi_acc_handle_t	xhandle = EB2_AUXIO_HNDL;
368 
369 	if (level == CS4231_PWR_ON) {	/* turn power on */
370 		AND_SET_WORD(xhandle, EB2_AUXIO_REG, ~EB2_AUXIO_COD_PDWN);
371 	} else {	/* turn power off */
372 		OR_SET_WORD(xhandle, EB2_AUXIO_REG, EB2_AUXIO_COD_PDWN);
373 	}
374 
375 }	/* eb2_power() */
376 
377 /*
378  * eb2_reload()
379  *
380  * Description:
381  *	This routine reloads the DMA address, so that we can continue
382  *	double buffer round-robin fashion.
383  *
384  * Arguments:
385  *	CS_engine_t	*eng		The engine
386  */
387 static void
eb2_reload(CS_engine_t * eng)388 eb2_reload(CS_engine_t *eng)
389 {
390 	ddi_acc_handle_t	handle = eng->ce_regsh;
391 	cs4231_eb2regs_t	*regs = eng->ce_eb2regs;
392 
393 	/* if next address already loaded, then we're done */
394 	if ((ddi_get32(handle, &regs->eb2csr) & EB2_NA_LOADED)) {
395 		return;
396 	}
397 
398 	/*
399 	 * For eb2 we first program the Next Byte Count Register.
400 	 */
401 	ddi_put32(handle, &regs->eb2bcr, CS4231_FRAGSZ);
402 
403 	/* now program the Next Address Register */
404 	ddi_put32(handle, &regs->eb2acr,
405 	    eng->ce_paddr + (CS4231_FRAGSZ * eng->ce_curidx));
406 
407 	eng->ce_curidx++;
408 	eng->ce_curidx %= CS4231_NFRAGS;
409 }
410 
411 /*
412  * eb2_addr()
413  *
414  * Description:
415  *	This routine returns the current DMA address for the engine (the
416  *	next address being accessed).
417  *
418  * Arguments:
419  *	CS_engine_t	*eng		The engine
420  *
421  * Returns:
422  *	Physical DMA address for current transfer.
423  */
424 static uint32_t
eb2_addr(CS_engine_t * eng)425 eb2_addr(CS_engine_t *eng)
426 {
427 	ddi_acc_handle_t	handle = eng->ce_regsh;
428 	cs4231_eb2regs_t	*regs = eng->ce_eb2regs;
429 
430 	return (ddi_get32(handle, &regs->eb2acr));
431 }
432