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 APC DMA controller. The APC is an SBus
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 apc_dma_attr = {
43 	DMA_ATTR_V0,			/* version */
44 	0x0000000000000000LL,		/* dlim_addr_lo */
45 	0x00000000ffffffffLL,		/* dlim_addr_hi */
46 	0x0000000000000fffLL,		/* DMA counter register */
47 	0x0000000000000001LL,		/* DMA address alignment */
48 	0x00000014,			/* 4 and 16 byte burst sizes */
49 	0x00000001,			/* min effective DMA size */
50 	0x0000000000000fffLL,		/* 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 acc_attr = {
58 	DDI_DEVICE_ATTR_V0,
59 	DDI_STRUCTURE_BE_ACC,
60 	DDI_STRICTORDER_ACC
61 };
62 
63 /*
64  * DMA ops vector functions
65  */
66 static int apc_map_regs(CS_state_t *);
67 static void apc_unmap_regs(CS_state_t *);
68 static void apc_reset(CS_state_t *);
69 static int apc_start_engine(CS_engine_t *);
70 static void apc_stop_engine(CS_engine_t *);
71 static void apc_power(CS_state_t *, int);
72 static void apc_reload(CS_engine_t *);
73 static uint32_t apc_addr(CS_engine_t *);
74 
75 cs4231_dma_ops_t cs4231_apcdma_ops = {
76 	"APC DMA controller",
77 	&apc_dma_attr,
78 	apc_map_regs,
79 	apc_unmap_regs,
80 	apc_reset,
81 	apc_start_engine,
82 	apc_stop_engine,
83 	apc_power,
84 	apc_reload,
85 	apc_addr,
86 };
87 
88 /*
89  * apc_map_regs()
90  *
91  * Description:
92  *	This routine allocates the DMA handles and the memory for the
93  *	DMA engines to use. It then binds each of the buffers to its
94  *	respective handle, getting a DMA cookie. Finally, the registers
95  *	are mapped in.
96  *
97  *	NOTE: All of the ddi_dma_... routines sleep if they cannot get
98  *		memory. This means these calls will almost always succeed.
99  *
100  * Arguments:
101  *	CS_state_t	*state		The device's state structure
102  *
103  * Returns:
104  *	AUDIO_SUCCESS		Registers successfully mapped
105  *	AUDIO_FAILURE		Registers not successfully mapped
106  */
107 static int
apc_map_regs(CS_state_t * state)108 apc_map_regs(CS_state_t *state)
109 {
110 	ddi_acc_handle_t	*handle = &APC_HANDLE;
111 	dev_info_t		*dip = state->cs_dip;
112 
113 	/* map in the registers, getting a handle */
114 	if (ddi_regs_map_setup(dip, 0, (caddr_t *)&state->cs_regs, 0,
115 	    sizeof (cs4231_regs_t), &acc_attr, handle) != DDI_SUCCESS) {
116 		audio_dev_warn(state->cs_adev, "ddi_regs_map_setup() failed");
117 		return (DDI_FAILURE);
118 	}
119 
120 	/* clear the CSR so we have all interrupts disabled */
121 	ddi_put32(*handle, &APC_DMACSR, APC_CLEAR_RESET_VALUE);
122 
123 	return (DDI_SUCCESS);
124 }	/* apc_map_regs() */
125 
126 /*
127  * apc_unmap_regs()
128  *
129  * Description:
130  *	This routine unmaps the Codec's and DMA engine's registers.
131  *	It must be idempotent.
132  *
133  * Arguments:
134  *	CS_state_t	*state	The device's state structure
135  *
136  * Returns:
137  *	void
138  */
139 static void
apc_unmap_regs(CS_state_t * state)140 apc_unmap_regs(CS_state_t *state)
141 {
142 	if (APC_HANDLE)
143 		ddi_regs_map_free(&APC_HANDLE);
144 
145 }	/* apc_unmap_regs() */
146 
147 /*
148  * apc_reset()
149  *
150  * Description:
151  *	Reset both the play and record DMA engines. The engines are left
152  *	with interrupts and the DMA engine disabled.
153  *
154  * Arguments:
155  *	dev_info_t	*dip	Pointer to the device's devinfo structure
156  *	CS_state_t	*state	The device's state structure
157  *
158  * Returns:
159  *	void
160  */
161 static void
apc_reset(CS_state_t * state)162 apc_reset(CS_state_t *state)
163 {
164 	ddi_acc_handle_t	handle = APC_HANDLE;
165 
166 	/*
167 	 * The APC has a bug where the reset is not done
168 	 * until you do the next pio to the APC. This
169 	 * next write to the CSR causes the posted reset to
170 	 * happen.
171 	 */
172 
173 	ddi_put32(handle, &APC_DMACSR, APC_RESET);
174 	ddi_put32(handle, &APC_DMACSR, APC_CLEAR_RESET_VALUE);
175 
176 }	/* apc_reset() */
177 
178 /*
179  * apc_start_engine()
180  *
181  * Description:
182  *	This routine starts the DMA engine.
183  *
184  *	For hard starts the DMA engine is started by programming the
185  *	Next Virtual Address and then the Next Counter twice, and
186  *	finally enabling the DMA engine.
187  *
188  *	NOTE: The state structure must be locked before this routine is called.
189  *
190  *	CAUTION: ?!? This routine doesn't start the Codec because the first
191  *		interrupt causes a recursive mutex_enter.
192  *
193  * Arguments:
194  *	CS_engine_t	*eng	The engine to start
195  *
196  * Returns:
197  *	DDI_SUCCESS		The DMA engine was started
198  *	DDI_FAILURE		The DMA engine was not started
199  */
200 static int
apc_start_engine(CS_engine_t * eng)201 apc_start_engine(CS_engine_t *eng)
202 {
203 	CS_state_t		*state = eng->ce_state;
204 	ddi_acc_handle_t	handle = APC_HANDLE;
205 	uint32_t		csr;
206 	uint32_t		enable;
207 	uint32_t		dirty;
208 	int			x;
209 
210 	ASSERT(mutex_owned(&state->cs_lock));
211 
212 	if (eng->ce_num == CS4231_PLAY) {
213 		enable = APC_PDMA_GO;
214 		dirty = APC_PD;
215 	} else {
216 		enable = APC_CDMA_GO;
217 		dirty = APC_CD;
218 	}
219 
220 	/* make sure it's okay to program the Next Address/Count registers */
221 	csr = ddi_get32(handle, &APC_DMACSR);
222 	for (x = 0; !(csr & dirty) && x < CS4231_TIMEOUT; x++) {
223 		drv_usecwait(1);	/* no reason to beat on the bus */
224 		csr = ddi_get32(handle, &APC_DMACSR);
225 	}
226 	if (x >= CS4231_TIMEOUT) {
227 		audio_dev_warn(state->cs_adev,
228 		    "timeout waiting for engine, not started!");
229 		return (DDI_FAILURE);
230 	}
231 
232 	/*
233 	 * Program the first fragment.
234 	 */
235 	apc_reload(eng);
236 
237 	/*
238 	 * Start the DMA engine, including interrupts.
239 	 */
240 	OR_SET_WORD(handle, &APC_DMACSR, enable);
241 
242 	/*
243 	 * Program the double buffering.
244 	 */
245 	apc_reload(eng);
246 
247 	return (DDI_SUCCESS);
248 }
249 
250 /*
251  * apc_stop_engine()
252  *
253  * Description:
254  *	This routine stops the engine.
255  *
256  *	The DMA engine is stopped by using the CAP_ABORT bit.
257  *
258  *	NOTE: The state structure must be locked before this routine is called.
259  *
260  * Arguments:
261  *	CS_engine_t	*eng	The engine to sotp
262  *
263  * Returns:
264  *	void
265  */
266 static void
apc_stop_engine(CS_engine_t * eng)267 apc_stop_engine(CS_engine_t *eng)
268 {
269 	CS_state_t		*state = eng->ce_state;
270 	ddi_acc_handle_t	handle = APC_HANDLE;
271 	uint32_t		reg;
272 	uint32_t		abort;
273 	uint32_t		drainbit;
274 	uint32_t		disable;
275 
276 	ASSERT(mutex_owned(&state->cs_lock));
277 
278 	if (eng->ce_num == CS4231_PLAY) {
279 		abort = APC_P_ABORT;
280 		drainbit = APC_PM;
281 		disable = APC_PLAY_DISABLE;
282 	} else {
283 		abort = APC_C_ABORT;
284 		drainbit = APC_CX;
285 		disable = APC_CAP_DISABLE;
286 	}
287 
288 	/* first, abort the DMA engine */
289 	OR_SET_WORD(handle, &APC_DMACSR, abort);
290 
291 	/* wait for the pipeline to empty */
292 	reg = ddi_get32(handle, &APC_DMACSR);
293 	for (int x = 0; (!(reg & drainbit)) && (x < CS4231_TIMEOUT); x++) {
294 		drv_usecwait(1);	/* don't beat on bus */
295 		reg = ddi_get32(handle, &APC_DMACSR);
296 	}
297 
298 	/* now clear the enable and abort bits */
299 	AND_SET_WORD(handle, &APC_DMACSR, ~(abort|disable));
300 }
301 
302 
303 /*
304  * apc_power()
305  *
306  * Description:
307  *	This routine turns the Codec off by using the COD_PDWN bit in the
308  *	apc chip. To turn power on we have to reset the APC, which clears
309  *	the COD_PDWN bit. However, this is a settling bug in the APC which
310  *	requires the driver to delay quite a while before we may continue.
311  *	Since this is the first time this feature has actually been used
312  *	it isn't too surprising that it has some problems.
313  *
314  *	NOTE: The state structure must be locked when this routine is called.
315  *
316  * Arguments:
317  *	CS_state_t	*state		Ptr to the device's state structure
318  *	int		level		Power level to set
319  */
320 static void
apc_power(CS_state_t * state,int level)321 apc_power(CS_state_t *state, int level)
322 {
323 	ddi_acc_handle_t	handle = APC_HANDLE;
324 
325 	if (level == CS4231_PWR_ON) {	/* turn power on */
326 		AND_SET_WORD(handle, &APC_DMACSR, ~APC_COD_PDWN);
327 		OR_SET_WORD(handle, &APC_DMACSR, APC_RESET);
328 		AND_SET_WORD(handle, &APC_DMACSR, ~APC_RESET);
329 
330 		/*
331 		 * wait for state change,
332 		 */
333 		delay(drv_usectohz(CS4231_300MS));
334 	} else {	/* turn power off */
335 		ASSERT(level == CS4231_PWR_OFF);
336 		OR_SET_WORD(handle, &APC_DMACSR, APC_COD_PDWN);
337 	}
338 
339 }	/* apc_power() */
340 
341 
342 static void
apc_reload(CS_engine_t * eng)343 apc_reload(CS_engine_t *eng)
344 {
345 	CS_state_t		*state = eng->ce_state;
346 	ddi_acc_handle_t	handle = APC_HANDLE;
347 	uint32_t		dirty;
348 	uint32_t		*nva;	/* next VA reg */
349 	uint32_t		*nc;	/* next count reg */
350 
351 	if (eng->ce_num == CS4231_PLAY) {
352 		dirty = APC_PD;
353 		nva = &APC_DMAPNVA;
354 		nc = &APC_DMAPNC;
355 	} else {
356 		dirty = APC_CD;
357 		nva = &APC_DMACNVA;
358 		nc = &APC_DMACNC;
359 	}
360 
361 	/* if we can't load another address, then don't */
362 	if ((ddi_get32(handle, &APC_DMACSR) & dirty) == 0) {
363 		return;
364 	}
365 
366 	/* read the NVA, as per APC document */
367 	(void) ddi_get32(handle, nva);
368 
369 	/* write the address of the next fragment */
370 	ddi_put32(handle, nva,
371 	    eng->ce_paddr + (CS4231_FRAGSZ * eng->ce_curidx));
372 	eng->ce_curidx++;
373 	eng->ce_curidx %= CS4231_NFRAGS;
374 
375 	/* now program the NC reg., which enables the state machine */
376 	ddi_put32(handle, nc, CS4231_FRAGSZ);
377 }
378 
379 /*
380  * apc_addr()
381  *
382  * Description:
383  *	This routine returns the current DMA address for the engine (the
384  *	next address being accessed).
385  *
386  * Arguments:
387  *	CS_engine_t	*eng		The engine
388  *
389  * Returns:
390  *	Physical DMA address for current transfer.
391  */
392 static uint32_t
apc_addr(CS_engine_t * eng)393 apc_addr(CS_engine_t *eng)
394 {
395 	CS_state_t		*state = eng->ce_state;
396 	ddi_acc_handle_t	handle = APC_HANDLE;
397 	uint32_t		*va;	/* VA reg */
398 
399 	if (eng->ce_num == CS4231_PLAY) {
400 		va = &APC_DMAPVA;
401 	} else {
402 		va = &APC_DMACVA;
403 	}
404 
405 	return (ddi_get32(handle, va));
406 }
407