source: svn/trunk/newcon3bcm2_21bu/magnum/portinginterface/xpt/7552/bxpt_playback.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 94.1 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2012, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bxpt_playback.c $
11 * $brcm_Revision: Hydra_Software_Devel/29 $
12 * $brcm_Date: 3/15/12 2:13p $
13 *
14 * Porting interface code for the data transport core.
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/xpt/base2/bxpt_playback.c $
19 *
20 * Hydra_Software_Devel/29   3/15/12 2:13p gmullen
21 * SW7425-2630: Wrong PID channel used for playback all-pass
22 *
23 * Hydra_Software_Devel/28   1/23/12 3:58p gmullen
24 * SW7346-568: Forced resync flag not cleared when packetization was
25 * disabled
26 *
27 * Hydra_Software_Devel/27   11/14/11 9:49a gmullen
28 * SW7231-451: Merged to Hydra
29 *
30 * Hydra_Software_Devel/SW7231-451/1   11/14/11 9:35a gmullen
31 * SW7231-451: Removed writes to START_ADDR_ regs in RAVE, added BDBG_MSGs
32 *
33 * Hydra_Software_Devel/26   11/10/11 12:25p jtna
34 * SW7425-1672: merge to hydra
35 *
36 * Hydra_Software_Devel/SW7425-1672/2   11/10/11 8:45a gmullen
37 * SW7425-1672: Added check for looped descriptor list
38 *
39 * Hydra_Software_Devel/SW7425-1672/1   11/9/11 5:50p jtna
40 * SW7425-1672: set FORCE_RESYNC flag on descriptors when packetizing ES
41 *
42 * Hydra_Software_Devel/25   11/3/11 3:47p gmullen
43 * SW7425-1323: Fixed B0/B1 binary compatability issue
44 *
45 * Hydra_Software_Devel/24   10/5/11 4:25p gmullen
46 * SW7346-502: Merged to Hydra
47 *
48 * Hydra_Software_Devel/SW7346-502/1   10/5/11 4:03p gmullen
49 * SW7346-502: Added AcceptAdapt00 support
50 *
51 * Hydra_Software_Devel/23   9/21/11 10:17a gmullen
52 * SW7425-1323: Merged to Hydra
53 *
54 * Hydra_Software_Devel/SW7425-1323/1   9/21/11 10:02a gmullen
55 * SW7425-1323: Potential workaround.
56 *
57 * Hydra_Software_Devel/22   9/12/11 10:50a gmullen
58 * SWDTV-8330: Ported fix to 40nm chips
59 *
60 * Hydra_Software_Devel/21   8/11/11 2:07p gmullen
61 * SW7346-382: Removed check on LastDesc pointer in _AddDescriptors()
62 *
63 * Hydra_Software_Devel/20   8/4/11 5:06p gmullen
64 * SW7346-382: Merged to Hydra
65 *
66 * Hydra_Software_Devel/SW7346-382/2   8/4/11 4:51p gmullen
67 * SW7346-382: Force resync on first descriptor when in bypass mode
68 *
69 * Hydra_Software_Devel/SW7346-382/1   8/2/11 11:12a gmullen
70 * SW7346-382: Use the hw designer's recommended config for ES
71 *
72 * Hydra_Software_Devel/19   8/4/11 10:00a gmullen
73 * SW7231-308: Merged fix to Hydra
74 *
75 * Hydra_Software_Devel/SW7231-308/1   8/4/11 9:55a gmullen
76 * SW7231-308: Temporarily disable pacing during channel stop
77 *
78 * Hydra_Software_Devel/18   8/3/11 10:44a gmullen
79 * SW7346-392: Changed index check to fix Coverity warning
80 *
81 * Hydra_Software_Devel/17   6/3/11 4:34p gmullen
82 * SW7425-653: Merged changes to Hydra branch
83 *
84 * Hydra_Software_Devel/SW7425-653/1   6/2/11 10:35a gmullen
85 * SW7425-653: Added non-realtime transcoding support
86 *
87 * Hydra_Software_Devel/16   5/12/11 4:59p gmullen
88 * SW7231-128: Merged to mainline
89 *
90 * Hydra_Software_Devel/SW7231-128/1   5/10/11 1:40p gmohile
91 * SW7231-128 : Add power management support
92 *
93 * Hydra_Software_Devel/15   4/11/11 9:15a gmullen
94 * SW7346-119: Merged fix to mainline
95 *
96 * Hydra_Software_Devel/SW7346-119/1   4/7/11 3:43p gmullen
97 * SW7346-119: Disable CC checking when enabling all-pass mode. Restore
98 * when exiting all-pass
99 *
100 * Hydra_Software_Devel/14   3/29/11 3:45p gmullen
101 * SW7125-785: Re-arm pacing, if enabled, when resuming from micro pause
102 *
103 * Hydra_Software_Devel/13   3/11/11 1:07p gmullen
104 * SW7346-112: Merged to mainline
105 *
106 * Hydra_Software_Devel/SW7346-112/1   3/11/11 9:39a gmullen
107 * SW7346-112: Recalc blockout when packet length is changed
108 *
109 * Hydra_Software_Devel/12   3/7/11 3:09p gmullen
110 * SW7425-153: Merged to mainline
111 *
112 * Hydra_Software_Devel/SW7425-153/1   3/7/11 3:07p gmullen
113 * SW7425-153: Fixed blockout calc and disabled usage of spare bandwidth
114 *
115 * Hydra_Software_Devel/11   1/28/11 9:41a gmullen
116 * SW7425-15: Allow spare bandwidth in playback during packetization. PR
117 * 29510 is fixed in the 40nm cores
118 *
119 * Hydra_Software_Devel/10   12/21/10 9:22a gmullen
120 * SW7425-15: Set LLD type in SetSettings()
121 *
122 * Hydra_Software_Devel/9   12/16/10 4:41p gmullen
123 * SW7425-15: Fixed compilation error on 7344 builds
124 *
125 * Hydra_Software_Devel/8   12/16/10 3:17p gmullen
126 * SW7425-15: Added PES pacing to GetSettings call
127 *
128 * Hydra_Software_Devel/6   12/6/10 10:01a gmullen
129 * SW7422-117: Disable pausing from XC buffer to flush data on playback
130 * stopping
131 *
132 * Hydra_Software_Devel/5   11/12/10 3:28p gmullen
133 * SW7425-15: Removed 1-byte buffer restriction
134 *
135 * Hydra_Software_Devel/4   11/12/10 11:11a gmullen
136 * SW7425-15: Changes to descriptor handling. Also disable CC checking and
137 * enable CC generation during packetization
138 *
139 * Hydra_Software_Devel/3   10/28/10 6:01p gmullen
140 * SW7425-15: Ported files
141 *
142 * Hydra_Software_Devel/2   10/28/10 2:08p gmullen
143 * SW7422-20: Checkin ported files
144 *
145 * Hydra_Software_Devel/115   10/19/10 10:08a gmullen
146 * SW7125-480: Fixed incorrect macro usage. Was clearing all pending
147 * interrupts
148 *
149 * Hydra_Software_Devel/114   9/7/10 5:36p gmullen
150 * SW7420-1045: Updated RS buffer blockouts in _SetBitRate() to handle
151 * MPOD usage
152 *
153 * Hydra_Software_Devel/113   8/30/10 5:24p gmullen
154 * SW7403-924: Protected access to the PID and SPID table from other
155 * modules in the PI
156 *
157 * Hydra_Software_Devel/112   7/28/10 1:12p gmullen
158 * SW7630-81: Default RaveOutputOnly = true, since this part doesn't have
159 * XC buffers
160 *
161 * Hydra_Software_Devel/111   7/27/10 5:11p gmullen
162 * SW3548-3013: Added error checking to BMEM allocs
163 *
164 * Hydra_Software_Devel/110   7/4/10 5:33p gmullen
165 * SW7630-81: Added support for QUICK
166 *
167 * Hydra_Software_Devel/109   5/13/10 12:07p gmullen
168 * SWBLURAY-20102: Fixed typo
169 *
170 * Hydra_Software_Devel/108   5/13/10 9:45a gmullen
171 * SWBLURAY-20102: Use interrupt status reg to get out-of-sync status
172 *
173 * Hydra_Software_Devel/107   4/20/10 8:08a gmullen
174 * SW7125-350: Merged fix to Hydra_Software_Devel
175 *
176 * Hydra_Software_Devel/SW7125-350/1   4/19/10 10:42a gmullen
177 * SW7125-350: Reset playback parser when packetizing is disabled
178 *
179 * Hydra_Software_Devel/106   3/26/10 3:37p gmullen
180 * SW7405-1883: Use both DESC_NOT_DONE and FINISHED to determine if a
181 * descriptor chain has finished
182 *
183 * Hydra_Software_Devel/105   2/16/10 6:05p gmullen
184 * SW7405-3926: Restore sync mode if channel stopping times out
185 *
186 * Hydra_Software_Devel/104   1/14/10 3:34p piyushg
187 * SW7335-664: Restoring the BAND_HOLD_EN values for RAVE contexts
188 * after BXPT_Playback_StopChannel processing.
189 *
190 * Hydra_Software_Devel/103   12/16/09 3:26p gmullen
191 * SW7325-665: Added support for 32-bit timestamp mode
192 *
193 * Hydra_Software_Devel/102   11/20/09 3:20p gmullen
194 * SW7630-54: Update BCHP checks in BXPT_Playback_DisablePacketizers for
195 * the 7630 and 7635
196 *
197 * Hydra_Software_Devel/101   11/19/09 5:12p gmullen
198 * SW7408-9: Fixed macro name again
199 *
200 * Hydra_Software_Devel/100   11/19/09 4:39p gmullen
201 * SW7408-9: Fixed macro name
202 *
203 * Hydra_Software_Devel/99   11/18/09 5:11p gmullen
204 * SW7408-9: Enabled descriptor read chicken bit
205 *
206 * Hydra_Software_Devel/98   11/17/09 3:07p gmullen
207 * SW7408-9: Finished adding 7408 support to XPT
208 *
209 * Hydra_Software_Devel/97   11/11/09 11:01a gmullen
210 * SW7550-16: Enabled AGRESSIVE_DATA_READ chicken-bit.
211 *
212 * Hydra_Software_Devel/96   11/3/09 9:33a gmullen
213 * SW7405-3308: Swapped interrupt macros for TEI and Parser Length
214 * interrupts
215 *
216 * Hydra_Software_Devel/95   10/22/09 9:30a gmullen
217 * SW7630-46: Added DVD change for BXPT_Playback_CheckHeadDescriptor
218 *
219 * Hydra_Software_Devel/94   10/1/09 11:12a gmullen
220 * SW7405-3102: ResetPacing in Setting struct incorrectly set if pacing is
221 * enabled
222 *
223 * Hydra_Software_Devel/93   9/29/09 11:58a gmullen
224 * SW7405-3102: Pacing auto reset can be disabled through
225 * Get/SetChannelSettings()
226 *
227 * Hydra_Software_Devel/92   9/16/09 1:42p gmullen
228 * SW35230-2: Fixed compilation errors on 35230 builds.
229 *
230 * Hydra_Software_Devel/91   9/9/09 8:06a piyushg
231 * SW7630-30: Add 7630 XPT PI support.
232 * Added directory element "7630".
233 *
234 * Hydra_Software_Devel/90   8/11/09 10:39a piyushg
235 * PR55216: Added initial 7340 XPT support.
236 *
237 * Hydra_Software_Devel/89   8/5/09 4:52p piyushg
238 * PR55545: Add 7125 XPT PI support
239 * Added file element "bxpt_rave_ihex.c".
240 * Added file element "bxpt_rave_ihex.h".
241 *
242 * Hydra_Software_Devel/88   7/31/09 3:25p piyushg
243 * PR56771: Add support for 7342.
244 *
245 * Hydra_Software_Devel/87   7/31/09 2:44p gmullen
246 * PR54331: Added 35130 to XPT support.
247 *
248 * Hydra_Software_Devel/86   7/15/09 3:05p gmullen
249 * PR56760: Fixed warning in non-debug builds.
250 *
251 * Hydra_Software_Devel/85   7/14/09 10:22a piyushg
252 * PR56771: Add XPT PI code for 7342.
253 *
254 * Hydra_Software_Devel/84   7/13/09 10:01a gmullen
255 * PR56760: Added dummy descriptor and wait until dummy desc is consumed.
256 *
257 * Hydra_Software_Devel/83   6/18/09 11:11a gmullen
258 * PR56110: Checked for mesg support.
259 *
260 * Hydra_Software_Devel/82   6/17/09 6:46p gmullen
261 * PR56110: Added support.xpt/7550/uif_image/a0
262 *
263 * Hydra_Software_Devel/81   6/2/09 10:29a gmullen
264 * PR51821: Merged workaround to mainline.
265 *
266 * Hydra_Software_Devel/80   5/28/09 2:11p gmullen
267 * PR55549: Added support for PCR-based pacing.
268 *
269 * Hydra_Software_Devel/79   4/20/09 2:31p gmullen
270 * PR48905: Disable band hold temporarily at playback stop.
271 *
272 * Hydra_Software_Devel/PR48905/1   4/20/09 12:51p gmullen
273 * PR48905: Disable band hold temporarily at playback stop.
274 *
275 * Hydra_Software_Devel/78   4/16/09 3:39p gmullen
276 * PR54222: Merged 7002-specific changes to mainline. Created symlinks for
277 * 7002 files back to 7400.
278 *
279 * Hydra_Software_Devel/77   4/13/09 5:00p gmullen
280 * PR54061: Enable PES SID, SubSID, and SID Extension extraction for all
281 * types of PES filtering.
282 *
283 * Hydra_Software_Devel/76   4/7/09 5:25p piyushg
284 * PR52986: Add support for 7635
285 * Added directory element "7635".
286 *
287 * Hydra_Software_Devel/75   2/18/09 10:49a piyushg
288 * PR52189: Added hooks for Get/Set PACING_OFFSET_ADJ_DIS bit.
289 *
290 * Hydra_Software_Devel/74   2/5/09 5:53p piyushg
291 * PR43563: Keeping the PARSER_PKT_LENGTH as 0xBC
292 * during ES packetization.
293 *
294 * Hydra_Software_Devel/73   1/27/09 1:09p gmullen
295 * PR51625: Added 7336 support
296 *
297 * Hydra_Software_Devel/72   12/15/08 2:36p gmullen
298 * PR48908: Removed power management code from XPT PI.
299 *
300 * Hydra_Software_Devel/71   12/9/08 4:42p gmullen
301 * PR47755: Fixed compilation error in packetizer code.
302 *
303 * Hydra_Software_Devel/70   11/26/08 4:15p gmullen
304 * PR47755: Added support for 7420.
305 *
306 * Hydra_Software_Devel/69   11/13/08 10:49a gmullen
307 * PR48835: Fixed typo in BDBG message
308 *
309 * Hydra_Software_Devel/68   11/12/08 6:37p piyushg
310 * PR48187: Reverting back the changes done in Rev. 63 (PR47968).
311 * This fix was introducing other bugs and is not a clean solution
312 * for back to back playback issue. Various "time out" related bugs
313 * should not happen now.
314 *
315 * Hydra_Software_Devel/68   11/12/08 6:35p piyushg
316 * PR48187: Reverting back the changes done in Rev. 63 (PR47968).
317 * This fix was introducing other bugs and is not a clean solution
318 * for back to back playback issue. Various "time out" related bugs
319 * should not happen now.
320 *
321 * Hydra_Software_Devel/67   11/12/08 3:10p gmullen
322 * PR48835: BXPT_Playback_SetChannelPacketSettings now takes a struct.
323 *
324 * Hydra_Software_Devel/66   11/3/08 9:44a gmullen
325 * PR48616: Enabled callbacks in _SetChannelSettings.
326 *
327 * Hydra_Software_Devel/65   10/29/08 1:59p gmullen
328 * PR48511: Disable packetizers on channel close.
329 *
330 * Hydra_Software_Devel/64   10/28/08 4:58p gmullen
331 * PR46544: Added power management support, default to disabled for now.
332 *
333 * Hydra_Software_Devel/63   10/17/08 9:42a gmullen
334 * PR47968: Wait for BUSY to clear before starting channel
335 *
336 * Hydra_Software_Devel/62   10/9/08 11:35a gmullen
337 * PR47745: Added BXPT_Playback_GetPacketizerDefaults().
338 *
339 * Hydra_Software_Devel/61   9/18/08 9:15a gmullen
340 * PR47063: Fixed compiler complaint: Done label was unused.
341 *
342 * Hydra_Software_Devel/60   9/17/08 5:31p gmullen
343 * PR47063: Merge changes to mainline
344 *
345 * Hydra_Software_Devel/wince_7400/1   4/1/08 10:23a gmullen
346 * PR41135: Removed incorrect arugment check in
347 * BXPT_Playback_PacketizeStream
348 *
349 * Hydra_Software_Devel/59   9/17/08 5:02p gmullen
350 * PR47065: Added PCR-based pacing support,
351 *
352 * Hydra_Software_Devel/58   8/12/08 12:37p gmullen
353 * PR45610: Returned BERR_NOT_SUPPORTED on certain chips if buffer length
354 * is 0 or 1.
355 *
356 * Hydra_Software_Devel/57   8/12/08 8:00a gmullen
357 * PR45618: Enabled support for ForceRestamping bool in parser config.
358 *
359 * Hydra_Software_Devel/56   7/16/08 3:44p gmullen
360 * PR37867: Merged playback mux code to Hydra_Software_Devel
361 *
362 * Hydra_Software_Devel/55   7/8/08 6:40p gmullen
363 * PR44037: Cleared program stream mode and enable bits before loading new
364 * values.
365 *
366 * Hydra_Software_Devel/54   6/5/08 6:07a gmullen
367 * PR43325: Used BXPT_MAX_PLAYBACK_RATE define in SetBitRate()
368 *
369 * Hydra_Software_Devel/53   5/27/08 10:27a gmullen
370 * PR43039: Fixed un-initialized AllPass bool.
371 *
372 * Hydra_Software_Devel/52   4/10/08 3:36p gmullen
373 * PR38954: Updated number of playbacks, added HDDVI support to PCR API,
374 * and added packetizer support.
375 *
376 * Hydra_Software_Devel/51   3/13/08 11:53a piyushg
377 * PR40136: Keeping the legacy context packetizing for ES streams only.
378 *
379 * Hydra_Software_Devel/50   2/19/08 5:03p gmullen
380 * PR39728: Memset ChannelSettings struct to 0.
381 *
382 * Hydra_Software_Devel/49   1/9/08 11:17a mward
383 * PR37062: Increased time to drain internal buffers helps 7118 when
384 * stopping DVD VOB playback.
385 *
386 * Hydra_Software_Devel/48   1/8/08 1:25p katrep
387 * PR36546: Reset the SPID table only for the pid channnels connected to
388 * the current playback parser during BXPT_Playback_DisablePacketizers
389 * call.Diabled legacy context packetzing on the new chips.
390 *
391 * Hydra_Software_Devel/SanJose_CDI_Devel/2   12/17/07 6:38p shuang
392 * PR37867:Merge Jethead patch in order to support DirecTV AM21 project
393 * which ATSC data will input through USB interface.
394 * Merge Magnum Phase 7.0.
395 *
396 * Hydra_Software_Devel/47   12/5/07 4:52p gmullen
397 * PR37062: Pause playback before stopping to drain internal buffers.
398 *
399 * Hydra_Software_Devel/46   12/4/07 6:23p mward
400 * PR37908: Use 7401 DVD LPCM support for 7118.
401 *
402 * Hydra_Software_Devel/45   11/30/07 5:38p gmullen
403 * PR37062: BXPT_Playback_DisablePacketizers() uses SetDvdMode() in
404 * addition to normal packeizer shutdown for 7401
405 *
406 * Hydra_Software_Devel/44   11/30/07 11:49a gmullen
407 * PR37062: Changed LPCM support to DVD Mode.
408 *
409 * Hydra_Software_Devel/43   11/28/07 9:01a gmullen
410 * PR37062: Added support for LPCM on the 7401.
411 *
412 * Hydra_Software_Devel/42   11/27/07 3:02p piyushg
413 * PR35926: Initializing the ResetPacing field in the call to
414 * BXPT_Playback_GetChannelDefaultSettings. Fix for the Coverity
415 * Defect ID:4053
416 *
417 * Hydra_Software_Devel/42   11/27/07 2:59p piyushg
418 * PR35926: Initializing the ResetPacing field in the call to
419 * BXPT_Playback_GetChannelDefaultSettings. Fix for the
420 * Coverity Defect ID:4053
421 *
422 * Hydra_Software_Devel/41   11/15/07 7:19p piyushg
423 * PR35829: Toggle PACING_START bit when TS_RANGE_ERROR interupt
424 * occurs. Earlier PACING_EN and PACING_AUTO_EN were also being
425 * reset and set which was causing a brief marcoblock in the TTS
426 * stream. This also fixes PR36443.
427 *
428 * Hydra_Software_Devel/40   9/27/07 2:05p gmullen
429 * PR35380: 7400 support was missing from
430 * BXPT_Playback_DisablePacketizers()
431 *
432 * Hydra_Software_Devel/39   9/7/07 6:53p katrep
433 * PR27642: Use the new stream filtering using spid for 7405. utilize the
434 * new hw features.
435 *
436 * Hydra_Software_Devel/38   8/31/07 3:50p gmullen
437 * PR34504: Added substream filtering.
438 *
439 * Hydra_Software_Devel/37   8/21/07 5:21p gmullen
440 * PR34222: Added DisableTimestampParityCheck bool to
441 * BXPT_Playback_ChannelSettings struct.
442 *
443 * Hydra_Software_Devel/36   8/2/07 12:18p gmullen
444 * PR33743: Fixed timebase comparison.
445 *
446 * Hydra_Software_Devel/35   8/2/07 11:36a katrep
447 * PR29510: For 7440 allow to allocated extra bandwidth & disable spare BW
448 * flag to hide the HW issue.
449 *
450 * Hydra_Software_Devel/34   8/1/07 3:38p gmullen
451 * PR33710: pepSpecial arbiter settings for 7440. Also support playback
452 * data direct to RAVE.
453 *
454 * Hydra_Software_Devel/33   7/26/07 1:58a katrep
455 * PR29510: For HD/BD PD spare BW is needed, backed out the changes made
456 * in #30 , only for 7440
457 *
458 * Hydra_Software_Devel/32   7/13/07 4:09p piyushg
459 * PR32218: PACING_START bit is reset whenever
460 * TS_RANGE_ERROR interrupt occurs.
461 *
462 * Hydra_Software_Devel/32   7/13/07 4:03p piyushg
463 * PR32218: Reset PACING_START bit when TS_RANGE_ERROR
464 * interupt occurs.
465 *
466 * Hydra_Software_Devel/31   7/1/07 1:09p katrep
467 * PR31880: Cleanup packetization state for 7440 on channel close.
468 *
469 * Hydra_Software_Devel/30   6/1/07 3:21p gmullen
470 * PR29510: Disabled spare bandwidth usage when packetizer is enabled.
471 *
472 * Hydra_Software_Devel/29   5/17/07 2:17p gmullen
473 * PR30877: Added support for dedicated playback heap handle.
474 *
475 * Hydra_Software_Devel/28   4/25/07 4:22p gmullen
476 * PR29688: Added AcceptNulls and AcceptAdapt00 support to parser config
477 *
478 * Hydra_Software_Devel/27   4/23/07 9:32a gmullen
479 * PR30083: Removed check of BUSY bit from BXPT_Playback_StopChannel
480 *
481 * Hydra_Software_Devel/26   3/15/07 7:23p katrep
482 * PR28320: Fixed the previous version.
483 *
484 * Hydra_Software_Devel/25   3/15/07 5:12p katrep
485 * PR28320: Expose PsMode and PackHdrConfig for all the chips which
486 * support it.
487 *
488 * Hydra_Software_Devel/24   1/9/07 11:38a gmullen
489 * PR26962: Added compile directive for 7403 to
490 * BXPT_Playback_DisablePacketizers.
491 *
492 * Hydra_Software_Devel/23   12/12/06 10:27a katrep
493 * PR23114: Fixed bug with BXPT_Playback_PacketizeStream for 7440.
494 *
495 * Hydra_Software_Devel/22   11/22/06 4:58p gmullen
496 * PR26109: Updated for 7403.
497 *
498 * Hydra_Software_Devel/21   11/21/06 3:59p gmullen
499 * PR26109: Ported files to 7403.
500 *
501 * Hydra_Software_Devel/20   11/2/06 8:40a gmullen
502 * PR23189: Added 3563 support.
503 *
504 * Hydra_Software_Devel/19   10/4/06 3:34p katrep
505 * PR23114: Use Pcketize pid table for PES all mode. Do not use the
506 * context as it will be dropped in the future chips.
507 *
508 * Hydra_Software_Devel/18   10/2/06 11:07a gmullen
509 * PR24504: Added BXPT_Playback_GetIntId().
510 *
511 * Hydra_Software_Devel/17   9/19/06 10:36a katrep
512 * PR23114: fixed compile error for 7401
513 *
514 * Hydra_Software_Devel/16   9/18/06 4:43p katrep
515 * PR23114: Include/drop pack hdr and select the insersion in TS payload
516 * or adaptaion field.
517 *
518 * Hydra_Software_Devel/15   9/18/06 12:12p katrep
519 * PR23114: Disable context enable for PES as context pt is used.
520 *
521 * Hydra_Software_Devel/14   9/15/06 4:28p katrep
522 * PR23114: Added PsMode to Channel Settings ,updated SyncMode comments.
523 *
524 * Hydra_Software_Devel/13   9/5/06 1:24p katrep
525 * PR23114: Fixed ES and PES MAP all playback for 7440
526 *
527 * Hydra_Software_Devel/12   8/29/06 10:15a gmullen
528 * PR20624: Fixed endian bug on 7118.
529 *
530 * Hydra_Software_Devel/11   8/17/06 6:43p katrep
531 * PR23114: Removed compiler warning for non 7440 platfroms
532 *
533 * Hydra_Software_Devel/10   8/17/06 6:01p katrep
534 * PR23114: Added Support for 7440 chip
535 *
536 * Hydra_Software_Devel/9   7/20/06 6:31p katrep
537 * PR18998: Fixed compiler warning. Unused variable
538 *
539 * Hydra_Software_Devel/8   7/20/06 5:30p katrep
540 * PR22365: Added better mangement of XC buffer client BW for playback.XC
541 * buf for PB is given max BW & BW throtle is done at PB engine.Spare BW
542 * enabllag is used to provide more BW for PB if available.
543 *
544 * Hydra_Software_Devel/7   7/10/06 9:32a gmullen
545 * PR18998: Fixed void * dereference warning.
546 *
547 * Hydra_Software_Devel/6   6/27/06 7:33p katrep
548 * PR21798: Do not reset pb parser configurations when the packetizer is
549 * disabled.Coz the settings may be required for DircTV PB.
550 *
551 * Hydra_Software_Devel/5   6/20/06 6:24p katrep
552 * PR20184: Adding fixes for PR 20597,20184
553 *
554 * Hydra_Software_Devel/4   6/7/06 2:49p katrep
555 * PR20631: disbaled endian control bit toggle for 7401B0+ chips
556 *
557 * Hydra_Software_Devel/3   4/19/06 5:36p gmullen
558 * PR21119: Added BXPT_Playback_DisablePacketizers()
559 *
560 * Hydra_Software_Devel/2   2/1/06 10:19a gmullen
561 * PR18998: Fixed overflow issue in RAVE ITB/CDB, added support for PB
562 * channels.
563 *
564 * Hydra_Software_Devel/7   12/13/05 4:47p jgarrett
565 * PR 18388: Fixing ES/PES -> TS Playback problem.  Packetizer was being
566 * left on due to a logic bug in the packetizer disable routine of BXPT.
567 *
568 * Hydra_Software_Devel/6   11/28/05 3:42p gmullen
569 * PR17861: StopChannel() was corrupting buffer endianness control. Fixed.
570 *
571 * Hydra_Software_Devel/5   10/20/05 11:14a gmullen
572 * PR15309: Added support for PES and ES playback.
573 *
574 * Hydra_Software_Devel/4   10/17/05 10:37a gmullen
575 * PR15309: Added ES support and AllPass mode for PB parsers.
576 *
577 * Hydra_Software_Devel/3   10/6/05 11:23a gmullen
578 * PR15309: Fixed audio support.
579 *
580 * Hydra_Software_Devel/2   9/21/05 2:17p gmullen
581 * PR15309: Added support for AAC HE and AC3+ audio, fixed bug in playback
582 * PI, modified RAVE PI to support channel change and reset.
583 *
584 * Hydra_Software_Devel/1   7/28/05 3:40p gmullen
585 * PR15309: Initial version for building.
586 *
587 ***************************************************************************/
588
589#include "bstd.h"
590#include "bkni.h"
591#include "bxpt_priv.h"
592#include "bxpt_playback.h"
593#include "bxpt_xcbuf_priv.h"
594#include "bxpt_spid.h"
595
596#include "bchp_xpt_pb0.h"
597#include "bchp_xpt_fe.h"
598
599#include "bxpt.h"
600#include "bchp_xpt_pb1.h"
601
602#if BCHP_PWR_SUPPORT
603#include "bchp_pwr.h"
604#endif
605
606#if BXPT_HAS_TSMUX
607#include "bchp_xpt_pb_top.h"
608#endif
609
610#define PB_PARSER_REG_STEPSIZE  ( BCHP_XPT_PB1_CTRL1 - BCHP_XPT_PB0_CTRL1 )
611
612#if( BDBG_DEBUG_BUILD == 1 )
613BDBG_MODULE( xpt_playback );
614#endif
615
616#define BXPT_P_PLAYBACK_DEFAULT_USE_PCR_TIMEBASE        false
617#define BXPT_P_PLAYBACK_DEFAULT_TIMESTAMP_MODE          BXPT_TimestampMode_e30_2U_Mod300   
618#define BXPT_PB_MAX_SYNC_LENGTH                         ( 256 )
619#define FLUSH_COUNTDOWN                                 ( 10 )     
620
621
622static BERR_Code BXPT_Playback_P_CreateDesc( BXPT_Handle hXpt, BXPT_PvrDescriptor * const Desc, uint8_t *Buffer, 
623    uint32_t BufferLength, bool IntEnable, BXPT_PvrDescriptor * const NextDesc );
624
625static void TsRangeErrorIsr ( void *hPb , int Param2);
626
627static BERR_Code CalcAndSetBlockout( 
628    BXPT_Playback_Handle hPb,   /* [in] Handle for the playback channel */
629    uint32_t BitRate            /* [in] Rate, in bits per second. */
630    );
631
632BERR_Code BXPT_Playback_GetTotalChannels(
633    BXPT_Handle hXpt,           /* [in] Handle for this transport */
634    unsigned int *TotalChannels     /* [out] The number of playback channels. */
635    )
636{
637    BERR_Code ExitCode = BERR_SUCCESS;
638
639    BDBG_ASSERT( hXpt );
640   
641    *TotalChannels = hXpt->MaxPlaybacks;
642
643    return( ExitCode );
644}
645
646
647BERR_Code BXPT_Playback_GetChannelDefaultSettings(
648    BXPT_Handle hXpt,           /* [in] Handle for this transport */
649    unsigned int ChannelNo,         /* [in] Which channel to get defaults from. */
650    BXPT_Playback_ChannelSettings *ChannelSettings /* [out] The defaults */
651    )
652{
653    BERR_Code ExitCode = BERR_SUCCESS;
654
655    BDBG_ASSERT( hXpt );
656    BDBG_ASSERT( ChannelSettings );
657
658    if( ChannelNo >= hXpt->MaxPlaybacks )
659    {
660        /* Bad PID channel number. Complain. */
661        BDBG_ERR(( "ChannelNo %lu is out of range!", ( unsigned long ) ChannelNo ));
662        ExitCode = BERR_TRACE( BERR_INVALID_PARAMETER );
663    }
664    else
665    {
666        BKNI_Memset( (void *) ChannelSettings, 0, sizeof(*ChannelSettings) );
667        ChannelSettings->UsePcrTimeBase = BXPT_P_PLAYBACK_DEFAULT_USE_PCR_TIMEBASE;
668        ChannelSettings->WhichPcrToUse = 0;
669        ChannelSettings->TimestampEn = false;
670        ChannelSettings->TimestampMode = BXPT_P_PLAYBACK_DEFAULT_TIMESTAMP_MODE;
671        ChannelSettings->PacketLength = 188;
672        ChannelSettings->SyncMode = BXPT_PB_SYNC_MPEG_BLIND;
673        ChannelSettings->RaveOutputOnly = false;
674        ChannelSettings->DisableTimestampParityCheck = false;
675        ChannelSettings->SwapBytes = false;     /* Input file is also big-endian. Don't swap */
676    }
677
678    ChannelSettings->PcrBasedPacing = false;   /* Use legacy 4-byte timestamp pacing */
679    ChannelSettings->PcrPacingPid = 0x1FFF;
680    ChannelSettings->Use32BitTimestamps = false;       
681
682#if BXPT_HAS_TSMUX
683    /* Defaults, to keep existing behavior. */
684    ChannelSettings->PesBasedPacing = false;   
685    ChannelSettings->Use8WordDesc = false;   
686#endif
687
688    return( ExitCode );
689}
690
691BERR_Code BXPT_Playback_OpenChannel(
692    BXPT_Handle hXpt,                           /* [in] Handle for this transport */
693    BXPT_Playback_Handle *PlaybackHandle,   /* [out] Handle for opened record channel */
694    unsigned int ChannelNo,                         /* [in] Which channel to open. */
695    BXPT_Playback_ChannelSettings *ChannelSettings /* [in] The defaults to use */
696    )
697{
698    uint32_t Reg;
699
700    uint32_t BaseAddr = 0;
701    BERR_Code ExitCode = BERR_SUCCESS;
702    BXPT_Playback_Handle hPb = NULL;
703    BINT_Id TsRangeErrorIntId;                                           
704    BXPT_PidChannel_CC_Config DefaultCcConfig = { false, false, false, 0 };
705
706    BDBG_ASSERT( hXpt );
707    BDBG_ASSERT( ChannelSettings );
708
709
710    /*
711    ** Use the address of the first register in the playback block as the
712    ** base address of the entire block.
713    */           
714    if( ChannelNo >= BXPT_NUM_PLAYBACKS )
715    {
716        /* Bad playback channel number. Complain. */
717        BDBG_ERR(( "ChannelNo %lu is out of range!", ( unsigned long ) ChannelNo ));
718        ExitCode = BERR_TRACE( BERR_INVALID_PARAMETER );
719        goto Done;
720    }
721    BaseAddr = BCHP_XPT_PB0_CTRL1 + ( ChannelNo * PB_PARSER_REG_STEPSIZE );
722
723    /* Create the playback handle. */
724    hPb = &hXpt->PlaybackHandles[ ChannelNo ];
725    hPb->hChip = hXpt->hChip;
726    hPb->hRegister = hXpt->hRegister;
727    hPb->BaseAddr = BaseAddr;
728    hPb->ChannelNo = ChannelNo;
729    hPb->LastDescriptor = 0;
730    hPb->Running = false;
731    hPb->vhXpt = hXpt;
732    hPb->SyncMode = BXPT_PB_SYNC_MPEG_BLIND;
733    hPb->BitRate = 27000000;
734    hPb->IsParserInAllPass = false;
735    hPb->CcConfigBeforeAllPass = DefaultCcConfig;
736    hPb->ForceResync = 0;
737
738#if BXPT_HAS_TSMUX
739    hPb->PacingLoadMap = 0;
740    hPb->PacingCount = 0;
741    hPb->PacingLoadNeeded = false;
742#endif
743
744    /* If they've got a separate heap for playback, use it */
745    if( hXpt->hPbHeap )
746        hPb->hMemory = hXpt->hPbHeap;
747    else
748        hPb->hMemory = hXpt->hMemory;
749
750    TsRangeErrorIntId = BXPT_Playback_GetIntId( hPb, BXPT_PbInt_eTsRangeErr );
751
752    BINT_CreateCallback(
753        &hPb->hPbIntCallback,
754        hXpt->hInt,
755        TsRangeErrorIntId,
756        TsRangeErrorIsr,
757        ( void * ) hPb,
758        0 );
759
760    if ( ChannelSettings->ResetPacing) 
761    {
762        hPb->ResetPacingOnTsRangeError = true;
763        BINT_EnableCallback( hPb->hPbIntCallback );
764    } 
765    else
766    {
767        hPb->ResetPacingOnTsRangeError = false;
768        BINT_DisableCallback( hPb->hPbIntCallback );
769    }
770
771    /* Restore all the stuff they could have changed through the API. */
772    Reg = (
773        BCHP_FIELD_DATA( XPT_PB0_CTRL1, WAKE_MODE, 0 ) |
774        BCHP_FIELD_DATA( XPT_PB0_CTRL1, RUN, 0 ) |
775        BCHP_FIELD_DATA( XPT_PB0_CTRL1, WAKE, 0 ) 
776    );
777
778    /* Anand's playback hw fix didn't catch one corner case. Turn on the chicken bit. */
779    #if 0
780    Reg |= ( BCHP_FIELD_DATA( XPT_PB0_CTRL1, AGRESSIVE_DESC_READ, 1 ) );
781    #endif
782
783    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL1, Reg ); 
784
785    /* Now load the defaults they passed in. */
786    BXPT_Playback_SetChannelSettings( hPb, ChannelSettings );
787
788    /* Create the dummy descriptor and buffer */   
789    hPb->DummyDescriptor = BMEM_AllocAligned( hPb->hMemory, sizeof( BXPT_PvrDescriptor ), 4, 0 ); 
790    if( !hPb->DummyDescriptor )
791    {
792        BDBG_ERR(( "DummyDescriptor alloc failed!" ));
793        ExitCode = BERR_TRACE( BERR_OUT_OF_DEVICE_MEMORY );
794        goto ErrorCleanUp;
795    }
796    hPb->DummyBuffer = BMEM_AllocAligned( hPb->hMemory, 2, 0, 0 );
797    if( !hPb->DummyBuffer )
798    {
799        BDBG_ERR(( "DummyBuffer alloc failed!" ));
800        BMEM_Free( hPb->hMemory, hPb->DummyDescriptor );
801        ExitCode = BERR_TRACE( BERR_OUT_OF_DEVICE_MEMORY );
802        goto ErrorCleanUp;
803    }
804    hPb->DummyBuffer[ 0 ] = hPb->DummyBuffer[ 1 ] = 0x55; 
805    BXPT_Playback_CreateDesc( hXpt, hPb->DummyDescriptor, hPb->DummyBuffer, 2, false, false, NULL );
806 
807    hPb->Opened = true;
808    *PlaybackHandle = hPb;
809   
810    Done:
811    return( ExitCode );
812
813    ErrorCleanUp:
814    BINT_DisableCallback( hPb->hPbIntCallback );
815    BINT_DestroyCallback( hPb->hPbIntCallback );
816    return( ExitCode );
817}
818
819void BXPT_Playback_CloseChannel(
820    BXPT_Playback_Handle PlaybackHandle /* [in] Handle for the channel to close*/
821    )
822{
823    /* Stop the channel. */
824    uint32_t Reg = (
825        BCHP_FIELD_DATA( XPT_PB0_CTRL1, WAKE_MODE, 0 ) |
826        BCHP_FIELD_DATA( XPT_PB0_CTRL1, RUN, 0 ) |
827        BCHP_FIELD_DATA( XPT_PB0_CTRL1, WAKE, 0 ) 
828    );
829
830    BINT_DestroyCallback( PlaybackHandle->hPbIntCallback );
831    BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1, Reg ); 
832
833    /* Clean up all previous Packetization state, if any. */
834    BXPT_Playback_DisablePacketizers( PlaybackHandle );
835
836    BMEM_Free( PlaybackHandle->hMemory, PlaybackHandle->DummyDescriptor );
837    BMEM_Free( PlaybackHandle->hMemory, PlaybackHandle->DummyBuffer );
838   
839    PlaybackHandle->Opened = false;
840}
841
842void TsRangeErrorIsr( void *hPb, int Param2 )
843{
844    uint32_t Reg; 
845
846    BDBG_ASSERT( hPb );
847
848    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL2 ); 
849
850    /*
851    ** Init the Pacing bitfields to 0. The PB_PACING_START bit must transistion from 0 to 1
852    ** in order to arm the pacing logic.
853    */
854    Reg &= ~( BCHP_MASK( XPT_PB0_CTRL2, PACING_START ) );
855
856    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL2, Reg );
857
858    Reg |= ( BCHP_FIELD_DATA( XPT_PB0_CTRL2, PACING_START, 1 ) ); 
859
860    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL2, Reg );
861    BSTD_UNUSED( Param2 );
862    return;
863}
864
865BERR_Code BXPT_Playback_SetChannelSettings(
866    BXPT_Playback_Handle hPb,       /* [in] Handle for the playback channel. */
867    const BXPT_Playback_ChannelSettings *ChannelSettings /* [in] New settings to use */
868    )
869{
870    uint32_t Reg, TimeBaseSel;
871
872    unsigned int PacketLength = 188;    /* Use MPEG length as the default. */
873    BERR_Code ExitCode = BERR_SUCCESS;
874
875    BDBG_ASSERT( hPb );
876    BDBG_ASSERT( ChannelSettings );
877
878    hPb->SyncMode = ChannelSettings->SyncMode;
879
880    if( ChannelSettings->PacketLength > BXPT_PB_MAX_SYNC_LENGTH )
881    {
882        BDBG_ERR(( "Packet length %d too long! Clamped to %d", ChannelSettings->PacketLength, BXPT_PB_MAX_SYNC_LENGTH )); 
883        PacketLength = BXPT_PB_MAX_SYNC_LENGTH;
884        ExitCode = BERR_TRACE( BERR_INVALID_PARAMETER );
885    }
886    else
887    {
888        PacketLength = ChannelSettings->PacketLength;
889    }
890
891    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL3 );
892    Reg &= ~( 
893        BCHP_MASK( XPT_PB0_CTRL3, SYNC_LENGTH ) 
894        );
895    Reg |= (
896        BCHP_FIELD_DATA( XPT_PB0_CTRL3, SYNC_LENGTH, PacketLength )
897        );
898    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL3, Reg ); 
899
900    /* Need to recalculate the blockout value if the sync length has changed. */
901    CalcAndSetBlockout( hPb, hPb->BitRate );
902
903    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL2 );
904    Reg &= ~( 
905        BCHP_MASK( XPT_PB0_CTRL2, SYNC_EXT_MODE ) |
906        BCHP_MASK( XPT_PB0_CTRL2, ENDIAN_CTRL ) |
907        BCHP_MASK( XPT_PB0_CTRL2, TS_PARITY_CHECK_DIS ) | 
908        BCHP_MASK( XPT_PB0_CTRL2, TIMESTAMP_EN ) |
909        BCHP_MASK( XPT_PB0_CTRL2, PROGRAM_STREAM_MODE ) |
910        BCHP_MASK( XPT_PB0_CTRL2, PROGRAM_STREAM_EN )
911        | 
912                BCHP_MASK( XPT_PB0_CTRL2, PACING_OFFSET_ADJ_DIS )
913        );
914
915    Reg |= (
916        BCHP_FIELD_DATA( XPT_PB0_CTRL2, SYNC_EXT_MODE, ChannelSettings->SyncMode ) |
917        BCHP_FIELD_DATA( XPT_PB0_CTRL2, TS_PARITY_CHECK_DIS, ChannelSettings->DisableTimestampParityCheck == true ? 1 : 0 ) |
918        BCHP_FIELD_DATA( XPT_PB0_CTRL2, ENDIAN_CTRL, ChannelSettings->SwapBytes == true ? 1 : 0 ) |
919        BCHP_FIELD_DATA( XPT_PB0_CTRL2, TIMESTAMP_EN, ChannelSettings->TimestampEn == true ? 1 : 0 ) |
920                BCHP_FIELD_DATA( XPT_PB0_CTRL2, PACING_OFFSET_ADJ_DIS, ChannelSettings->PacingOffsetAdjustDisable == true ? 1 : 0 )
921        );
922        Reg |= BCHP_FIELD_DATA( XPT_PB0_CTRL2, PROGRAM_STREAM_MODE, ChannelSettings->PsMode );
923        if( ChannelSettings->PackHdrConfig != BXPT_Playback_PackHdr_Drop)
924        {
925            Reg |= BCHP_FIELD_DATA( XPT_PB0_CTRL2, PROGRAM_STREAM_EN, 1 ); 
926        }
927    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL2, Reg ); 
928
929    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL4 );
930    Reg &= ~( 
931        BCHP_MASK( XPT_PB0_CTRL4, OUTPUT_PIPE_SEL ) |
932        BCHP_MASK( XPT_PB0_CTRL4, TIMEBASE_SEL ) |
933        BCHP_MASK( XPT_PB0_CTRL4, TIMESTAMP_MODE )| 
934        BCHP_MASK( XPT_PB0_CTRL4, PKTZ_PACK_HDR_INSERT_EN ) 
935        );
936
937    if( ChannelSettings->UsePcrTimeBase == false )
938    {
939        /* Use the free running 27 MHz clock. */
940        TimeBaseSel = 0;
941    }
942    else
943    {
944        if( ChannelSettings->WhichPcrToUse > BXPT_NUM_PCRS ) 
945        {
946            /* Bad PCR module number. Complain, and default to free running 27 MHz clock. */
947            BDBG_ERR(( "WhichPcrToUse %lu is out of range!", ( unsigned long ) ChannelSettings->WhichPcrToUse ));
948            ExitCode = BERR_TRACE( BERR_INVALID_PARAMETER );
949            TimeBaseSel = 0;
950        }
951   
952        TimeBaseSel = ChannelSettings->WhichPcrToUse + 1;
953    }
954
955    Reg |= (
956        BCHP_FIELD_DATA( XPT_PB0_CTRL4, OUTPUT_PIPE_SEL, ChannelSettings->RaveOutputOnly == true ? 1 : 0 ) |
957        BCHP_FIELD_DATA( XPT_PB0_CTRL4, TIMEBASE_SEL, TimeBaseSel ) |
958        BCHP_FIELD_DATA( XPT_PB0_CTRL4, TIMESTAMP_MODE, ChannelSettings->TimestampMode ) 
959        );
960    if (ChannelSettings->PackHdrConfig == BXPT_Playback_PackHdr_Adaptation_Insert)
961    {
962        Reg |= BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_PACK_HDR_INSERT_EN, 1 ); 
963    }
964
965    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL4, Reg ); 
966
967    /* PCR-based pacing */
968    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL2 );
969    Reg &= ~( 
970        BCHP_MASK( XPT_PB0_CTRL2, PACING_TYPE ) |   
971        BCHP_MASK( XPT_PB0_CTRL2, TIMESTAMP_MODE_32BIT ) 
972        );
973    if( ChannelSettings->PcrBasedPacing == true )
974    {
975        Reg |= (
976            BCHP_FIELD_DATA( XPT_PB0_CTRL2, PACING_TYPE, 1 ) |
977            BCHP_FIELD_DATA( XPT_PB0_CTRL2, TIMESTAMP_MODE_32BIT, 1 )
978            );
979    }
980
981#if BXPT_HAS_TSMUX
982    else if( ChannelSettings->PesBasedPacing == true )
983    {
984        Reg |= (
985            BCHP_FIELD_DATA( XPT_PB0_CTRL2, PACING_TYPE, 2 )
986            );
987    }
988#endif
989
990    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL2, Reg ); 
991
992    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_PACING_PCR_PID );
993    Reg &= ~( 
994        BCHP_MASK( XPT_PB0_PACING_PCR_PID, PACING_PCR_PID ) 
995        );
996    Reg |= (
997        BCHP_FIELD_DATA( XPT_PB0_PACING_PCR_PID, PACING_PCR_PID, ChannelSettings->PcrPacingPid )
998        );
999    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_PACING_PCR_PID, Reg ); 
1000
1001    /* Don't overwrite TIMESTAMP_MODE_32BIT if PCR pacing is in use */
1002    if( ChannelSettings->PcrBasedPacing == false )
1003    {
1004        Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL2 );
1005        Reg &= ~( BCHP_MASK( XPT_PB0_CTRL2, TIMESTAMP_MODE_32BIT ) );
1006        Reg |= ( BCHP_FIELD_DATA( XPT_PB0_CTRL2, TIMESTAMP_MODE_32BIT, ChannelSettings->Use32BitTimestamps == true ? 1 : 0 ) );
1007        BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL2, Reg ); 
1008    }
1009
1010    if ( ChannelSettings->ResetPacing) 
1011    {
1012        hPb->ResetPacingOnTsRangeError = true;
1013        BINT_EnableCallback( hPb->hPbIntCallback );
1014    } 
1015    else
1016    {
1017        hPb->ResetPacingOnTsRangeError = false;
1018        BINT_DisableCallback( hPb->hPbIntCallback );
1019    }
1020
1021#if BXPT_HAS_TSMUX
1022    /* Set LLD Type */
1023    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL1 );
1024    Reg &= ~( BCHP_MASK( XPT_PB0_CTRL1, LLD_TYPE ) );
1025    Reg |= ( BCHP_FIELD_DATA( XPT_PB0_CTRL1, LLD_TYPE, ChannelSettings->Use8WordDesc == true ? 1 : 0 ) );
1026    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL1, Reg );
1027#endif
1028
1029    return( ExitCode );
1030}
1031
1032BERR_Code BXPT_Playback_GetChannelSettings(
1033    BXPT_Playback_Handle hPb,       /* [in] Handle for the playback channel. */
1034    BXPT_Playback_ChannelSettings *ChannelSettings /* [out] The current settings  */
1035    )
1036{
1037    uint32_t Reg;
1038
1039    uint32_t Timebase = 0;
1040    BERR_Code ExitCode = BERR_SUCCESS;
1041
1042    BDBG_ASSERT( hPb );
1043    BDBG_ASSERT( ChannelSettings );
1044
1045    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL3 );
1046    ChannelSettings->PacketLength = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL3, SYNC_LENGTH );
1047
1048    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL2 );
1049    ChannelSettings->SyncMode = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL2, SYNC_EXT_MODE );
1050    ChannelSettings->SwapBytes = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL2, ENDIAN_CTRL ) ? true : false;
1051    ChannelSettings->TimestampEn = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL2, TIMESTAMP_EN ) ? true : false;
1052    ChannelSettings->DisableTimestampParityCheck = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL2, TS_PARITY_CHECK_DIS ) ? true : false;
1053        ChannelSettings->ResetPacing = hPb->ResetPacingOnTsRangeError;
1054        ChannelSettings->PacingOffsetAdjustDisable = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL2, PACING_OFFSET_ADJ_DIS ) ? true : false;
1055    ChannelSettings->Use32BitTimestamps = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL2, TIMESTAMP_MODE_32BIT ) ? true : false;
1056
1057    ChannelSettings->PsMode = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL2, PROGRAM_STREAM_MODE ); 
1058    if( !BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL2, PROGRAM_STREAM_EN ) )
1059        ChannelSettings->PackHdrConfig = BXPT_Playback_PackHdr_Drop;
1060    else
1061        ChannelSettings->PackHdrConfig = BXPT_Playback_PackHdr_Payload_Insert;
1062
1063    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL4 );
1064    ChannelSettings->TimestampMode = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL4, TIMESTAMP_MODE );
1065    ChannelSettings->RaveOutputOnly = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL4, OUTPUT_PIPE_SEL ) ? true : false;
1066    Timebase = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL4, TIMEBASE_SEL );
1067
1068    /*
1069    ** In the Timebase check below, note that the hardware maps timebases with DPCR0 given a value of 1,
1070    ** DPCR1 is 2, etc. Thus, the check below is > as opposed to >=
1071    */
1072    if( Timebase == 0 )
1073        ChannelSettings->UsePcrTimeBase = false; 
1074    else if( Timebase > BXPT_NUM_PCRS )   
1075    {
1076        BDBG_ERR(( "Invalid timebase %u configured in hardware.", ( unsigned long ) Timebase ));
1077        ChannelSettings->UsePcrTimeBase = false; 
1078    }
1079    else
1080    {
1081        ChannelSettings->UsePcrTimeBase = true; 
1082        ChannelSettings->WhichPcrToUse = Timebase - 1; 
1083    }
1084
1085    if( ChannelSettings->PackHdrConfig != BXPT_Playback_PackHdr_Drop )
1086    {
1087        if( BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL4, PKTZ_PACK_HDR_INSERT_EN ) )
1088            ChannelSettings->PackHdrConfig = BXPT_Playback_PackHdr_Adaptation_Insert;
1089    }
1090
1091    /* PCR-based pacing */
1092    ChannelSettings->PcrBasedPacing = false;
1093#if BXPT_HAS_TSMUX
1094    ChannelSettings->PesBasedPacing = false;
1095#endif
1096    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL2 );
1097    switch( BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL2, PACING_TYPE ) )
1098    {
1099        case 1:
1100        ChannelSettings->PcrBasedPacing = true;
1101        break;
1102
1103#if BXPT_HAS_TSMUX
1104        case 2:
1105        ChannelSettings->PesBasedPacing = true;
1106        break;
1107#endif
1108
1109        case 0:
1110        default:
1111        /* Do nothing. Timestamp mode is the hw default. */
1112        break;
1113    }
1114
1115    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_PACING_PCR_PID );
1116    ChannelSettings->PcrPacingPid = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_PACING_PCR_PID, PACING_PCR_PID );
1117
1118#if BXPT_HAS_TSMUX
1119    /* Get the LLD Type */
1120    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL1 );
1121    ChannelSettings->Use8WordDesc = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL1, LLD_TYPE ) ? true : false;
1122#endif
1123
1124    return( ExitCode );
1125}
1126
1127#ifdef ENABLE_PLAYBACK_MUX
1128BERR_Code BXPT_Playback_SetChannelPacketSettings(
1129        BXPT_Playback_Handle hPb,                                                                  /* [in] Handle for the playback channel. */
1130    const BXPT_Playback_ChannelPacketSettings *ChannelSettings /* [in] New settings to use */
1131        )
1132{
1133        uint32_t Reg;
1134
1135        unsigned int PacketLength = 188;        /* Use MPEG length as the default. */
1136        BERR_Code ExitCode = BERR_SUCCESS;
1137
1138        BDBG_ASSERT( hPb );
1139
1140        hPb->SyncMode = ChannelSettings->SyncMode;
1141
1142        if( ChannelSettings->PacketLength > BXPT_PB_MAX_SYNC_LENGTH )
1143        {
1144                BDBG_ERR(( "Packet length %d too long! Clamped to %d", ChannelSettings->PacketLength, BXPT_PB_MAX_SYNC_LENGTH )); 
1145                PacketLength = BXPT_PB_MAX_SYNC_LENGTH;
1146                ExitCode = BERR_TRACE( BERR_INVALID_PARAMETER );
1147        }
1148        else
1149        {
1150                PacketLength = ChannelSettings->PacketLength;
1151        }
1152
1153        /*set the packet length*/                             
1154        Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL3 );
1155        Reg &= ~(BCHP_MASK( XPT_PB0_CTRL3, SYNC_LENGTH ));
1156        Reg |= (BCHP_FIELD_DATA( XPT_PB0_CTRL3, SYNC_LENGTH, PacketLength ));
1157        BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL3, Reg ); 
1158
1159    /* Need to recalc the blockout if the packet size has changed */
1160    CalcAndSetBlockout( hPb, hPb->BitRate );
1161
1162        /*set the packet sync*/
1163        Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL2 );
1164        Reg &= ~( 
1165            BCHP_MASK( XPT_PB0_CTRL2, SYNC_EXT_MODE ) |
1166            BCHP_MASK( XPT_PB0_CTRL2, TIMESTAMP_EN ) |
1167            BCHP_MASK( XPT_PB0_CTRL2, TS_PARITY_CHECK_DIS )
1168        );
1169 
1170        Reg |= (BCHP_FIELD_DATA( XPT_PB0_CTRL2, SYNC_EXT_MODE, ChannelSettings->SyncMode ));
1171        if (ChannelSettings->TimestampEn == true) {
1172                Reg |= (BCHP_FIELD_DATA( XPT_PB0_CTRL2, TIMESTAMP_EN, 1 ));
1173        }
1174        if (ChannelSettings->DisableTimestampParityCheck == true) {
1175                Reg |= (BCHP_FIELD_DATA( XPT_PB0_CTRL2, TS_PARITY_CHECK_DIS, 1 ));
1176        }
1177
1178        BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL2, Reg ); 
1179
1180
1181        return( ExitCode );
1182}
1183#endif /*ENABLE_PLAYBACK_MUX*/
1184     
1185BERR_Code BXPT_Playback_GetChannelStatus(
1186    BXPT_Playback_Handle hPb,           /* [in] Handle for the playback channel. */
1187    BXPT_Playback_ChannelStatus *Status /* [out] Channel status. */
1188    )
1189{
1190    uint32_t Reg, CurrDescReg, CurrDescNotDone, IntEnReg;
1191   
1192    BERR_Code ExitCode = BERR_SUCCESS;
1193
1194    BDBG_ASSERT( hPb );
1195    BDBG_ASSERT( Status );
1196
1197    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL1 );
1198    Status->Busy = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL1, BUSY ) ? true : false;
1199    Status->Run = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL1, RUN ) ? true : false;
1200
1201    CurrDescReg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CURR_DESC_ADDR );
1202    CurrDescNotDone = BCHP_GET_FIELD_DATA( CurrDescReg, XPT_PB0_CURR_DESC_ADDR, CURR_DESC_NOT_DONE );
1203    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL1 );
1204    Status->Finished = ~CurrDescNotDone && BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL1, FINISHED ) && Status->Run; 
1205   
1206    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_INTR );
1207    Status->OutOfSync = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_INTR, SE_OUT_OF_SYNC_INT ) ? true : false;
1208
1209    /* We can clear the status bit here if the interrupt isn't enabled */
1210    IntEnReg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_INTR_EN );
1211    if( !BCHP_GET_FIELD_DATA( IntEnReg, XPT_PB0_INTR, SE_OUT_OF_SYNC_INT ))
1212    {
1213        Reg = ~( 
1214            BCHP_MASK( XPT_PB0_INTR, SE_OUT_OF_SYNC_INT ) 
1215        );
1216        BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_INTR, Reg );
1217    }
1218
1219    return( ExitCode ); 
1220}
1221     
1222BERR_Code BXPT_Playback_GetCurrentBufferAddress(
1223    BXPT_Playback_Handle hPb,   /* [in] Handle for the playback channel */
1224    uint32_t *Address                       /* [out] The address read from hardware. */
1225    )
1226{
1227    uint32_t Reg;
1228
1229    BERR_Code ExitCode = BERR_SUCCESS;
1230
1231    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CURR_BUFF_ADDR ); 
1232    *Address = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CURR_BUFF_ADDR, CURR_BUFF_ADDR );
1233
1234    return( ExitCode );
1235}
1236
1237BERR_Code BXPT_Playback_GetCurrentDescriptorAddress(
1238    BXPT_Playback_Handle hPb,   /* [in] Handle for the playback channel */
1239    BXPT_PvrDescriptor **LastDesc       /* [in] Address of the current descriptor. */
1240    )
1241{
1242    uint32_t Reg, CurrentDescAddr;
1243    void *UserDescAddr;
1244
1245    BERR_Code ExitCode = BERR_SUCCESS;
1246
1247    BDBG_ASSERT( hPb );
1248
1249    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CURR_DESC_ADDR );
1250    CurrentDescAddr = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CURR_DESC_ADDR, CURR_DESC_ADDR );
1251    CurrentDescAddr <<= 4;  /* Convert to byte-address. */
1252    BMEM_ConvertOffsetToAddress( hPb->hMemory, CurrentDescAddr, ( void ** ) &UserDescAddr );
1253    *LastDesc = ( BXPT_PvrDescriptor * ) UserDescAddr;
1254                                                                               
1255    return( ExitCode );
1256}
1257
1258BERR_Code BXPT_Playback_CreateDesc( 
1259    BXPT_Handle hXpt,                       /* [in] Handle for this transport */
1260    BXPT_PvrDescriptor * const Desc,        /* [in] Descriptor to initialize */ 
1261    uint8_t *Buffer,                        /* [in] Data buffer. */
1262    uint32_t BufferLength,                  /* [in] Size of buffer (in bytes). */
1263    bool IntEnable,                         /* [in] Interrupt when done? */
1264    bool ReSync,                            /* [in] Re-sync extractor engine? */
1265    BXPT_PvrDescriptor * const NextDesc     /* [in] Next descriptor, or NULL */
1266    )
1267{
1268    BERR_Code RetCode;
1269   
1270    BDBG_ASSERT( Desc );
1271
1272    RetCode = BXPT_Playback_P_CreateDesc( hXpt, Desc, Buffer, BufferLength, IntEnable, NextDesc );
1273
1274    if( RetCode == BERR_SUCCESS && ReSync == true )
1275        Desc->Flags |= TRANS_DESC_FORCE_RESYNC_FLAG;
1276
1277    return RetCode; 
1278}
1279
1280void BXPT_SetLastDescriptorFlag(
1281    BXPT_PvrDescriptor * const Desc     /* [in] Descriptor to initialize */ 
1282    )
1283{
1284    BDBG_ASSERT( Desc );
1285
1286    /*  Set the Last Descriptor bit. */
1287    Desc->NextDescAddr = TRANS_DESC_LAST_DESCR_IND;
1288}
1289
1290#if BXPT_HAS_TSMUX
1291static void LoadPacingCounter(
1292    BXPT_Playback_Handle hPb   /* [in] Handle for the playback channel */
1293    )
1294{
1295    if( hPb->PacingLoadNeeded ) 
1296    {
1297        uint32_t Reg = hPb->PacingLoadMap;   
1298
1299        /* Done to intentionally clear LD_STC_MUX_DELAY_DIFF */
1300        Reg &= ~( BCHP_MASK( XPT_PB_TOP_PACING_COUNT_RELOAD_CTRL, LD_STC_MUX_DELAY_DIFF ) );
1301
1302        BREG_Write32( hPb->hRegister, BCHP_XPT_PB_TOP_PACING_COUNT_WR_VALUE, hPb->PacingCount );
1303        BREG_Write32( hPb->hRegister, BCHP_XPT_PB_TOP_PACING_COUNT_RELOAD_CTRL, Reg );
1304        hPb->PacingLoadNeeded = false;
1305    }
1306}
1307#endif
1308
1309BERR_Code BXPT_Playback_AddDescriptors( 
1310    BXPT_Playback_Handle hPb,   /* [in] Handle for the playback channel */
1311    BXPT_PvrDescriptor *LastDesc,   /* [in] Last descriptor in new chain */
1312    BXPT_PvrDescriptor *FirstDesc   /* [in] First descriptor in new chain */
1313    )
1314{
1315    uint32_t Reg;
1316    uint32_t DescPhysAddr;   
1317
1318    BERR_Code ExitCode = BERR_SUCCESS;
1319    BXPT_PvrDescriptor *LastDescriptor = ( BXPT_PvrDescriptor * ) hPb->LastDescriptor;
1320
1321    BDBG_ASSERT( FirstDesc );
1322
1323    /* When the sync extractor is in bypass mode, the first descriptor must have it's FORCE_RESYNC flag set. */
1324    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL2 );
1325    if( !LastDescriptor && BXPT_PB_SYNC_BYPASS == BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL2, SYNC_EXT_MODE ) )
1326    {
1327        FirstDesc->Flags |= TRANS_DESC_FORCE_RESYNC_FLAG;
1328    }
1329
1330    if( hPb->ForceResync ) 
1331    {
1332        /* cycle through all descriptors and set force_resync flag */
1333        BXPT_PvrDescriptor *Desc = FirstDesc;
1334        BXPT_PvrDescriptor *HeadOfChain = FirstDesc;
1335
1336        do 
1337        {
1338            Desc->Flags |= TRANS_DESC_FORCE_RESYNC_FLAG;
1339
1340            if( Desc->NextDescAddr == TRANS_DESC_LAST_DESCR_IND ) 
1341                break;
1342
1343            BMEM_ConvertOffsetToAddress( hPb->hMemory, Desc->NextDescAddr, ( void ** ) &Desc );
1344        } 
1345        while( Desc != HeadOfChain );
1346    }
1347
1348#if 0
1349    /* Walk through the list list, dumping each descriptor's contents */
1350    {
1351        #define FLAG_STR_LEN 40
1352        char FlagsStr[ FLAG_STR_LEN ];
1353
1354        BXPT_PvrDescriptor *Desc = FirstDesc;
1355        BXPT_PvrDescriptor *HeadOfChain = FirstDesc;
1356
1357        do
1358        {
1359            #include  <stdio.h>
1360
1361            /*
1362            FILE *Fp;
1363            void *Buffer;
1364
1365            Fp = fopen( "videos/pb_dump.mpg", "wb" );
1366            BMEM_ConvertOffsetToAddress( hPb->hMemory, Desc->BufferStartAddr, ( void ** ) &Buffer );
1367            fwrite( Buffer, 1, sizeof (char), Fp );
1368            fclose( Fp );
1369            */
1370
1371            BMEM_Heap_FlushCache( hPb->hMemory, (void *) Desc, sizeof( BXPT_PvrDescriptor) );
1372
1373            BKNI_Snprintf( FlagsStr, FLAG_STR_LEN, "%s%s",
1374                     Desc->Flags & TRANS_DESC_FORCE_RESYNC_FLAG ? "Force Resync,": "",
1375                     Desc->Flags & TRANS_DESC_INT_FLAG ? "Interrupt": ""
1376                     );
1377            BDBG_MSG(( "Desc 0x%08lX: BufferStartAddr 0x%08lX, BufferLength %u, Flags 0x%08lX (%s), NextDescAddr 0x%08lX",
1378                       Desc, Desc->BufferStartAddr, Desc->BufferLength, Desc->Flags, FlagsStr, Desc->NextDescAddr ));
1379
1380            if( Desc->NextDescAddr == TRANS_DESC_LAST_DESCR_IND )
1381                break;
1382            BMEM_ConvertOffsetToAddress( hPb->hMemory, Desc->NextDescAddr, ( void ** ) &Desc );
1383        }
1384        while( Desc != HeadOfChain );
1385    }
1386#endif
1387
1388#if BXPT_HAS_TSMUX
1389    LoadPacingCounter( hPb );
1390#endif
1391
1392    if( LastDescriptor )
1393    {
1394        /* Channel has a linked-list loaded already. Append this descriptor to the end and use WAKE_MODE = 0 (resume from the last descriptor). */
1395
1396        /* Set the last descriptor in the chain to point to the descriptor we're adding. */
1397        BMEM_ConvertAddressToOffset( hPb->hMemory, ( void * ) FirstDesc, &DescPhysAddr );
1398        LastDescriptor->NextDescAddr = ( uint32_t ) DescPhysAddr;
1399
1400        /* SWDTV-8330: read register after uncache memory write operation to maintain consistency */
1401        Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL1 ); 
1402        Reg &= ~ ( BCHP_MASK( XPT_PB0_CTRL1, WAKE_MODE ) );
1403        Reg |= BCHP_FIELD_DATA( XPT_PB0_CTRL1, WAKE, 1 );
1404        BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL1, Reg );
1405    }
1406    else
1407    {
1408        /* Channel does not have a linked-list loaded. Point the FIRST_DESC_ADDR to this descriptor and set RUN */
1409        BMEM_ConvertAddressToOffset( hPb->hMemory, ( void * ) FirstDesc, &DescPhysAddr );
1410
1411        Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_FIRST_DESC_ADDR );
1412        Reg &= ~( BCHP_MASK( XPT_PB0_FIRST_DESC_ADDR, FIRST_DESC_ADDR ) );
1413
1414        /*
1415        ** The descriptor address field in the hardware register is wants the address
1416        ** in 16-byte blocks. See the RDB HTML for details. So, we must shift the
1417        ** address 4 bits to the right before writing it to the hardware. Note that
1418        ** the RDB macros will shift the value 4 bits to the left, since the address
1419        ** bitfield starts at bit 4. Confusing, but thats what the hardware and the
1420        ** RDB macros require to make this work.
1421        */
1422        DescPhysAddr >>= 4;
1423        Reg |= BCHP_FIELD_DATA( XPT_PB0_FIRST_DESC_ADDR, FIRST_DESC_ADDR, DescPhysAddr ); 
1424        BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_FIRST_DESC_ADDR, Reg );
1425
1426        Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL1 ); 
1427        Reg &= ~ ( 
1428                  BCHP_MASK( XPT_PB0_CTRL1, WAKE_MODE ) |
1429                  BCHP_MASK( XPT_PB0_CTRL1, WAKE ) |
1430                  BCHP_MASK( XPT_PB0_CTRL1, RUN ) 
1431        );
1432        Reg |= (
1433                BCHP_FIELD_DATA( XPT_PB0_CTRL1, WAKE_MODE, 1 ) |   
1434                BCHP_FIELD_DATA( XPT_PB0_CTRL1, WAKE, 1 ) |
1435                BCHP_FIELD_DATA( XPT_PB0_CTRL1, RUN, 1 )
1436        ); 
1437        BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL1, Reg );
1438    }
1439
1440    hPb->LastDescriptor = ( uint32_t ) LastDesc;
1441    return ExitCode;
1442}
1443
1444BERR_Code BXPT_Playback_StartChannel( 
1445    BXPT_Playback_Handle PlaybackHandle     /* [in] Handle for the playback channel */
1446    )
1447{
1448    uint32_t Reg;
1449
1450    BERR_Code ExitCode = BERR_SUCCESS;
1451
1452    BDBG_ASSERT( PlaybackHandle );
1453
1454    BDBG_MSG(( "Starting playback channel %d", ( unsigned long ) PlaybackHandle->ChannelNo )); 
1455
1456    if( PlaybackHandle->Running == true )
1457    {
1458        BDBG_ERR(( "Playback channel %d cannot be started because it's already running!", 
1459            ( unsigned long ) PlaybackHandle->ChannelNo )); 
1460        ExitCode = BERR_TRACE( BXPT_ERR_CHANNEL_ALREADY_RUNNING );
1461    }
1462
1463#ifdef BCHP_PWR_RESOURCE_XPT_PLAYBACK
1464    if( PlaybackHandle->Running == false ) 
1465    {
1466        BCHP_PWR_AcquireResource(PlaybackHandle->hChip, BCHP_PWR_RESOURCE_XPT_PLAYBACK);
1467    }
1468#endif
1469
1470    /* Check if we have buffers already loaded for this channel */
1471    if( PlaybackHandle->LastDescriptor )
1472    {
1473        /* Since we already have some buffers loaded, we can start the pvr channel */
1474        Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1 ); 
1475        Reg |= BCHP_FIELD_DATA( XPT_PB0_CTRL1, RUN, 1 ); 
1476        BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1, Reg );
1477    }   
1478
1479    /* Need to enable the parser band. */
1480    Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_PARSER_CTRL1 );
1481    Reg |= (
1482        BCHP_FIELD_DATA( XPT_PB0_PARSER_CTRL1, PARSER_ENABLE, 1 ) 
1483    );
1484    BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_PARSER_CTRL1, Reg ); 
1485
1486    PlaybackHandle->Running = true;
1487
1488    return( ExitCode );
1489}
1490
1491
1492BERR_Code BXPT_Playback_StopChannel( 
1493    BXPT_Playback_Handle PlaybackHandle     /* [in] Handle for the playback channel */
1494    )
1495{
1496    volatile uint32_t Reg;
1497    uint32_t PacingEn;
1498
1499    BERR_Code ExitCode = BERR_SUCCESS;
1500
1501    BDBG_ASSERT( PlaybackHandle );
1502
1503    BDBG_MSG(( "Stopping playback channel %d", ( unsigned long ) PlaybackHandle->ChannelNo )); 
1504
1505    if( PlaybackHandle->Running == false )
1506    {
1507        BDBG_ERR(( "Playback channel %d cannot be stopped because it's not running!", 
1508            ( unsigned long ) PlaybackHandle->ChannelNo )); 
1509        ExitCode = BERR_TRACE( BXPT_ERR_CHANNEL_ALREADY_STOPPED );
1510    }
1511
1512    Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2 ); 
1513    PacingEn = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL2, PACING_EN );
1514    Reg &= ~( 
1515        BCHP_MASK( XPT_PB0_CTRL2, PACING_EN ) 
1516        );
1517    BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2, Reg );
1518
1519    /* Stop the channel hardware */
1520    Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1 ); 
1521    Reg |= (
1522        BCHP_FIELD_DATA( XPT_PB0_CTRL1, DISCARD_DMA_DATA, 1 ) 
1523    ); 
1524    BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1, Reg );
1525    {
1526        int Wait;
1527
1528        /* Disable pausing from the XC buffer. Allows data to drain */
1529        BXPT_XcBuf_P_EnablePlaybackPausing( (BXPT_Handle) PlaybackHandle->vhXpt, PlaybackHandle->ChannelNo, false );   
1530        for( Wait = 0; Wait < 100; Wait++ ) 
1531        {
1532            BKNI_Delay( 1 );  /* Busy wait for 1 uS */
1533        }
1534
1535        /* Re-enable pausing from the XC buffer. Prevents overflows in RAVE. */
1536        BXPT_XcBuf_P_EnablePlaybackPausing( (BXPT_Handle) PlaybackHandle->vhXpt, PlaybackHandle->ChannelNo, true );   
1537    }
1538
1539    Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1 ); 
1540    Reg &= ~( BCHP_MASK( XPT_PB0_CTRL1, RUN ) );
1541    Reg |= (
1542        BCHP_FIELD_DATA( XPT_PB0_CTRL1, RUN, 0 )
1543    ); 
1544    BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1, Reg );
1545
1546    /* Clear the first desc addr (for cleaner debugging) */
1547    Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_FIRST_DESC_ADDR );
1548    Reg &= ~( BCHP_MASK( XPT_PB0_FIRST_DESC_ADDR, FIRST_DESC_ADDR ) );
1549    BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_FIRST_DESC_ADDR, Reg );
1550
1551    /* Clear the host pause. This shouldn't be restored, though. */
1552    Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2 );
1553    Reg &= ~( 
1554        BCHP_MASK( XPT_PB0_CTRL2, MICRO_PAUSE ) 
1555        );
1556    BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2, Reg );
1557
1558    PlaybackHandle->LastDescriptor = 0;     
1559
1560#if 1
1561    /* Keep this around, just in case. */
1562    {
1563        uint32_t Busy;
1564        int WaitCount;
1565        uint32_t FirstDescAddr, SyncExtMode;
1566        uint32_t DescPhysAddr;   
1567        uint32_t DescNotDone;
1568
1569        /* Wait for the BUSY bit to clear. */
1570        WaitCount = 100;          /* 100 uS max wait before we declare failure */
1571        do
1572        {
1573            Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1 );
1574            Busy = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL1, BUSY ) ? true : false;
1575   
1576            if( Busy )
1577            {
1578                WaitCount--;
1579                if( !WaitCount )
1580                {
1581                    BDBG_ERR(( "Playback channel %d timed-out waiting for BUSY bit to clear", 
1582                        ( unsigned long ) PlaybackHandle->ChannelNo )); 
1583                    ExitCode = BERR_TRACE( BERR_TIMEOUT );
1584                    goto Done;
1585                }
1586     
1587                BKNI_Delay( 1 );  /* Busy wait for 1 uS */
1588            }
1589        }
1590        while( Busy );
1591
1592        Done:
1593        BKNI_Delay( 10 );   /* Wait 10 uS; */
1594        Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_FIRST_DESC_ADDR );
1595        FirstDescAddr = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_FIRST_DESC_ADDR, FIRST_DESC_ADDR );
1596        Reg &= ~( BCHP_MASK( XPT_PB0_FIRST_DESC_ADDR, FIRST_DESC_ADDR ) );
1597        BMEM_ConvertAddressToOffset( PlaybackHandle->hMemory, ( void * ) PlaybackHandle->DummyDescriptor, &DescPhysAddr );
1598        DescPhysAddr >>= 4;
1599        Reg |= BCHP_FIELD_DATA( XPT_PB0_FIRST_DESC_ADDR, FIRST_DESC_ADDR, DescPhysAddr ); 
1600        BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_FIRST_DESC_ADDR, Reg );
1601
1602        Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2 );
1603        SyncExtMode = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL2, SYNC_EXT_MODE );
1604        Reg &= ~BCHP_MASK( XPT_PB0_CTRL2, SYNC_EXT_MODE );
1605        Reg |= BCHP_FIELD_DATA( XPT_PB0_CTRL2, SYNC_EXT_MODE, 3 );
1606        BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2, Reg );
1607 
1608        Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1 );
1609        Reg |= BCHP_FIELD_DATA( XPT_PB0_CTRL1, RUN, 1 );
1610        BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1, Reg );
1611
1612        WaitCount = 100;          /* 100 uS max wait before we declare failure */
1613        do
1614        {
1615            Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CURR_DESC_ADDR );
1616            DescNotDone = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CURR_DESC_ADDR, CURR_DESC_NOT_DONE );
1617   
1618            if( DescNotDone )
1619            {
1620                WaitCount--;
1621                if( !WaitCount )
1622                {
1623                    BDBG_ERR(( "Playback channel %d timed-out waiting for CURR_DESC_NOT_DONE bit to clear", 
1624                        ( unsigned long ) PlaybackHandle->ChannelNo )); 
1625                    ExitCode = BERR_TRACE( BERR_TIMEOUT );
1626                    goto Done2;
1627                }
1628     
1629                BKNI_Delay( 1 );  /* Busy wait for 1 uS */
1630            }
1631
1632        }
1633        while( DescNotDone ); 
1634
1635        Done2:       
1636        Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1 );
1637        Reg &= ~( BCHP_MASK( XPT_PB0_CTRL1, RUN ) );
1638        BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1, Reg );
1639
1640        WaitCount = 100;          /* 100 uS max wait before we declare failure */
1641        do
1642        {
1643            Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1 );
1644            Busy = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL1, BUSY ) ? true : false;
1645   
1646            if( Busy )
1647            {
1648                WaitCount--;
1649                if( !WaitCount )
1650                {
1651                    BDBG_ERR(( "Playback channel %d timed-out waiting for BUSY bit to clear, 2nd loop", 
1652                        ( unsigned long ) PlaybackHandle->ChannelNo )); 
1653                    ExitCode = BERR_TRACE( BERR_TIMEOUT );
1654                    goto Done3;
1655                }
1656     
1657                BKNI_Delay( 1 );  /* Busy wait for 1 uS */
1658            }
1659        }
1660        while( Busy );
1661       
1662        Done3:
1663        Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_FIRST_DESC_ADDR );
1664        Reg &= ~( BCHP_MASK( XPT_PB0_FIRST_DESC_ADDR, FIRST_DESC_ADDR ) );
1665        Reg |= BCHP_FIELD_DATA( XPT_PB0_FIRST_DESC_ADDR, FIRST_DESC_ADDR, FirstDescAddr ); 
1666        BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_FIRST_DESC_ADDR, Reg );
1667
1668        Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2 );
1669        Reg &= ~BCHP_MASK( XPT_PB0_CTRL2, SYNC_EXT_MODE );
1670        Reg |= BCHP_FIELD_DATA( XPT_PB0_CTRL2, SYNC_EXT_MODE, SyncExtMode );
1671        BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2, Reg );
1672    }
1673#endif
1674
1675    /* Need to disable the parser band. */
1676    Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_PARSER_CTRL1 );
1677    Reg &= ~(
1678        BCHP_MASK( XPT_PB0_PARSER_CTRL1, PARSER_ENABLE ) 
1679    );
1680    BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_PARSER_CTRL1, Reg ); 
1681
1682    /* Stop dropping data in the DMA buffers. */
1683    Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1 ); 
1684    Reg &= ~( BCHP_MASK( XPT_PB0_CTRL1, DISCARD_DMA_DATA ) );
1685    BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1, Reg );
1686
1687    /* Restore the pacing enable. */
1688    if( PacingEn ) 
1689    {
1690        Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2 ); 
1691        Reg |= (
1692            BCHP_FIELD_DATA( XPT_PB0_CTRL2, PACING_EN, 1 ) 
1693            );
1694        BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2, Reg );
1695    }
1696
1697#ifdef BCHP_PWR_RESOURCE_XPT_PLAYBACK
1698    if (PlaybackHandle->Running) {
1699        BCHP_PWR_ReleaseResource(PlaybackHandle->hChip, BCHP_PWR_RESOURCE_XPT_PLAYBACK);
1700    }
1701#endif
1702
1703    PlaybackHandle->Running = false;
1704
1705    return( ExitCode );
1706}
1707
1708
1709BERR_Code BXPT_Playback_Pause( 
1710    BXPT_Playback_Handle PlaybackHandle     /* [in] Handle for the playback channel */
1711    )
1712{
1713    uint32_t Reg;
1714
1715    BERR_Code ExitCode = BERR_SUCCESS;
1716
1717    BDBG_ASSERT( PlaybackHandle );
1718
1719    Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2 ); 
1720    Reg &= ~( BCHP_MASK( XPT_PB0_CTRL2, MICRO_PAUSE ) );
1721    Reg |= BCHP_FIELD_DATA( XPT_PB0_CTRL2, MICRO_PAUSE, 1 ); 
1722    BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2, Reg );
1723
1724    return( ExitCode );
1725}
1726
1727
1728BERR_Code BXPT_Playback_Resume( 
1729    BXPT_Playback_Handle PlaybackHandle     /* [in] Handle for the playback channel */
1730    )
1731{
1732    uint32_t Reg;
1733
1734    BERR_Code ExitCode = BERR_SUCCESS;
1735
1736    BDBG_ASSERT( PlaybackHandle );
1737
1738    Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2 ); 
1739    if( BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL2, PACING_EN ) ) 
1740    {
1741        TsRangeErrorIsr( PlaybackHandle, 0 );
1742    }
1743
1744    /* Reread the register, since TsRangeErrorIsr() modifies it. */
1745    Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2 ); 
1746    Reg &= ~( BCHP_MASK( XPT_PB0_CTRL2, MICRO_PAUSE ) );
1747    Reg |= BCHP_FIELD_DATA( XPT_PB0_CTRL2, MICRO_PAUSE, 0 ); 
1748    BXPT_Playback_P_WriteReg( PlaybackHandle, BCHP_XPT_PB0_CTRL2, Reg );
1749
1750    return( ExitCode );
1751}                                                             
1752
1753BERR_Code BXPT_Playback_SetBitRate( 
1754    BXPT_Playback_Handle hPb,   /* [in] Handle for the playback channel */
1755    uint32_t BitRate            /* [in] Rate, in bits per second. */
1756    )
1757{
1758    BDBG_ASSERT( hPb );
1759
1760    if( BitRate < BXPT_MIN_PLAYBACK_RATE ) 
1761    {
1762        BDBG_ERR(( "Minimum playback rate is %u bps. Rate will be clamped to that value", BXPT_MIN_PLAYBACK_RATE ));
1763        BitRate = BXPT_MIN_PLAYBACK_RATE;
1764    }
1765    else if ( BitRate > BXPT_MAX_PLAYBACK_RATE ) 
1766    {
1767        BDBG_ERR(( "Maximum playback rate is %u bps. Rate will be clamped to that value", BXPT_MAX_PLAYBACK_RATE ));
1768        BitRate = BXPT_MAX_PLAYBACK_RATE;
1769    }
1770
1771    hPb->BitRate = BitRate;
1772    return CalcAndSetBlockout( hPb, BitRate );
1773}
1774
1775BERR_Code CalcAndSetBlockout( 
1776    BXPT_Playback_Handle hPb,   /* [in] Handle for the playback channel */
1777    uint32_t BitRate            /* [in] Rate, in bits per second. */
1778    )
1779{
1780    uint32_t Reg, SyncLen, BoCount;
1781
1782    BERR_Code ExitCode = BERR_SUCCESS;
1783
1784    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL3 );
1785    SyncLen = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL3, SYNC_LENGTH );
1786
1787#if BXPT_SW7425_1323_WORKAROUND
1788    {
1789        BXPT_Handle lhXpt = (BXPT_Handle) hPb->vhXpt;
1790
1791        if( lhXpt->DoWorkaround )
1792            BitRate = BitRate <= 30000000 ? BitRate : 30000000; 
1793    }
1794#endif
1795
1796    if(SyncLen == 0xB8)
1797        SyncLen = 0xBC;
1798
1799    /* Do the math in units of 10kbps to avoid overflowing the 24-bit blockout bitfield in the register. */
1800    BoCount = (10800 * SyncLen * 8) / ( BitRate / 10000 );
1801
1802    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_BLOCKOUT ); 
1803    Reg &= ~( 
1804         BCHP_MASK( XPT_PB0_BLOCKOUT, BO_COUNT ) |
1805         BCHP_MASK( XPT_PB0_BLOCKOUT, BO_SPARE_BW_EN )
1806         );
1807    Reg |= (
1808        BCHP_FIELD_DATA( XPT_PB0_BLOCKOUT, BO_COUNT, BoCount ) 
1809        ); 
1810    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_BLOCKOUT, Reg );
1811
1812    return( ExitCode );
1813}
1814
1815
1816BERR_Code BXPT_Playback_CheckHeadDescriptor( 
1817    BXPT_Playback_Handle PlaybackHandle,    /* [in] Handle for the playback channel */
1818    BXPT_PvrDescriptor *Desc,       /* [in] Descriptor to check. */
1819    bool *InUse,                    /* [out] Is descriptor in use? */
1820    uint32_t *BufferSize            /* [out] Size of the buffer (in bytes). */
1821    )
1822{
1823    uint32_t Reg, ChanBusy, CurrentDescNotDone, CurrentDescAddr, CandidateDescPhysAddr;
1824    uint32_t DescFinish;
1825
1826    BERR_Code ExitCode = BERR_SUCCESS;
1827
1828    BDBG_ASSERT( PlaybackHandle );
1829
1830    /*
1831    ** Check if the current descriptor being processed by the
1832    ** playback hardware is the first on our hardware list
1833    ** (which means this descriptor is still being used)
1834    */
1835    Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CURR_DESC_ADDR );
1836    CurrentDescNotDone = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CURR_DESC_ADDR, CURR_DESC_NOT_DONE );
1837    DescFinish = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CURR_DESC_ADDR, FINISHED_SHADOW ) ;
1838    DescFinish = (~CurrentDescNotDone && DescFinish) ;
1839    CurrentDescAddr = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CURR_DESC_ADDR, CURR_DESC_ADDR );
1840    CurrentDescAddr <<= 4;  /* Convert to byte-addressing */
1841
1842    Reg = BXPT_Playback_P_ReadReg( PlaybackHandle, BCHP_XPT_PB0_CTRL1 );
1843    ChanBusy = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL1, BUSY );
1844   
1845    BMEM_ConvertAddressToOffset( PlaybackHandle->hMemory, ( void * ) Desc, &CandidateDescPhysAddr );
1846
1847    if( CurrentDescAddr == CandidateDescPhysAddr )
1848    {
1849/*        if( ChanBusy && CurrentDescNotDone ) */
1850        if( !DescFinish )
1851        {
1852            /* The candidate descriptor is being used by hardware. */
1853            *InUse = true;
1854        }
1855        else
1856        {
1857            *InUse = false;
1858        }
1859    }
1860    else
1861    {
1862        /*
1863        ** The candidate descriptor isn't being processed. If this is the head descriptor
1864        ** we can conclude that the hardware is finished with the descriptor.
1865        */
1866        *InUse = false;
1867
1868#if 0
1869/* Keep this around, just in case */
1870        if (Desc->NextDescAddr == 1)
1871        {
1872           /* If there's no next descriptor and the current descriptor isn't the head descriptor,
1873            * the head descriptor hasn't been read by the HW yet.  It's still InUse.
1874            */
1875           *InUse = true;
1876        }
1877        else
1878        {
1879            /* Check if our head descriptor is after the current one */
1880            BXPT_PvrDescriptor *  CurrentHwDesc;
1881            BMEM_ConvertOffsetToAddress( PlaybackHandle->hMemory, CurrentDescAddr, ( void * ) &CurrentHwDesc );
1882           
1883            /* If the head descriptor is the next descriptor, its still InUse */
1884            if (CurrentHwDesc->NextDescAddr == CandidateDescPhysAddr){
1885                *InUse = true;
1886            }
1887        }
1888#endif
1889    }
1890
1891    if( *InUse == false )
1892    {
1893        *BufferSize = Desc->BufferLength;
1894    }
1895    else
1896    {
1897        *BufferSize = 0;
1898    }
1899
1900    return( ExitCode );
1901}
1902
1903BERR_Code BXPT_Playback_GetTimestampUserBits(
1904    BXPT_Playback_Handle hPb,   /* [in] Handle for the playback channel */
1905    unsigned int *Bits                          /* [out] The user bits read from hardware. */
1906    )
1907{
1908    uint32_t Reg;
1909
1910    BERR_Code ExitCode = BERR_SUCCESS;
1911
1912    BDBG_ASSERT( hPb );
1913
1914    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL4 );
1915    *Bits = ( int ) ( BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL4, TIMESTAMP_USER_BITS ) & 0xFF );
1916
1917    return( ExitCode );
1918}
1919
1920BERR_Code BXPT_Playback_ConfigPacing(
1921    BXPT_Playback_Handle hPb,   /* [in] Handle for the playback channel */
1922    BXPT_PacingControl Mode                 /* [in] New mode for pacing. */
1923    )
1924{
1925    uint32_t Reg; 
1926
1927    BERR_Code ExitCode = BERR_SUCCESS;
1928
1929    BDBG_ASSERT( hPb );
1930
1931    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL2 ); 
1932
1933    /*
1934    ** Init the Pacing bitfields to 0. The PB_PACING_START bit must transistion from 0 to 1
1935    ** later on in order to arm the pacing logic.
1936    */
1937    Reg &= ~( 
1938        BCHP_MASK( XPT_PB0_CTRL2, PACING_START ) |
1939        BCHP_MASK( XPT_PB0_CTRL2, PACING_EN ) |
1940        BCHP_MASK( XPT_PB0_CTRL2, PACING_AUTOSTART_EN ) 
1941        );
1942
1943    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL2, Reg );
1944
1945    if( Mode == BXPT_PacingControl_eStart )
1946    {
1947        Reg |= (
1948            BCHP_FIELD_DATA( XPT_PB0_CTRL2, PACING_START, 1 ) |
1949            BCHP_FIELD_DATA( XPT_PB0_CTRL2, PACING_EN, 1 ) |
1950
1951            /*
1952            ** Autostart will re-arm the pacing logic automatically if a
1953            ** force-resync condition occurrs.
1954            */ 
1955            BCHP_FIELD_DATA( XPT_PB0_CTRL2, PACING_AUTOSTART_EN, 1 )
1956        ); 
1957    }
1958
1959    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL2, Reg );
1960
1961    return( ExitCode );
1962}
1963
1964BERR_Code BXPT_Playback_SetPacingErrorBound(
1965    BXPT_Playback_Handle hPb,       /* [in] Handle for the playback channel */
1966    unsigned long MaxTsError        /* [in] Maximum timestamp error. */
1967    )
1968{
1969    uint32_t Reg;
1970
1971    BERR_Code ExitCode = BERR_SUCCESS;
1972
1973    BDBG_ASSERT( hPb );
1974
1975    /* Newer chips */
1976    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_TS_ERR_BOUND_EARLY );
1977    Reg &= ~( 
1978        BCHP_MASK( XPT_PB0_TS_ERR_BOUND_EARLY, TS_ERR_BOUND ) 
1979        );
1980    Reg |= (
1981        BCHP_FIELD_DATA( XPT_PB0_TS_ERR_BOUND_EARLY, TS_ERR_BOUND, MaxTsError )
1982    ); 
1983    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_TS_ERR_BOUND_EARLY, Reg ); 
1984
1985    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_TS_ERR_BOUND_LATE );
1986    Reg &= ~( 
1987        BCHP_MASK( XPT_PB0_TS_ERR_BOUND_LATE, TS_ERR_BOUND ) 
1988        );
1989    Reg |= (
1990        BCHP_FIELD_DATA( XPT_PB0_TS_ERR_BOUND_LATE, TS_ERR_BOUND, MaxTsError )
1991    ); 
1992    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_TS_ERR_BOUND_LATE, Reg ); 
1993
1994    return( ExitCode );
1995}
1996
1997void BXPT_Playback_GetPacketizerDefaults(
1998    const BXPT_Playback_PacketizeConfig *Cfg   /* [in] Config to initialize */
1999    )
2000{
2001    BDBG_ASSERT( Cfg );
2002    BKNI_Memset( (void *) Cfg, 0, sizeof( BXPT_Playback_PacketizeConfig ) );
2003}
2004
2005BERR_Code BXPT_Playback_PacketizeStream(
2006    BXPT_Playback_Handle hPb,                   /* [in] Handle for the playback channel */
2007    unsigned Context,                           /* [in] Which context to map the packets to. */
2008    const BXPT_Playback_PacketizeConfig *Cfg,   /* [in] Configuration for this context */
2009    bool Enable                                 /* [in] Start or stop packetization. */
2010    )
2011{
2012    /* In _CloseChannel(), disable all the packetizers */
2013    unsigned Index;
2014    uint32_t Reg, RegAddr;
2015    int32_t i;
2016    BXPT_Spid_eChannelFilter SidFilter;
2017    BXPT_Handle hXpt;
2018    BXPT_PidChannel_CC_Config ccConfig;
2019
2020    BERR_Code ExitCode = BERR_SUCCESS;
2021
2022    BDBG_ASSERT( hPb );
2023    BDBG_ASSERT( Cfg );
2024
2025    hXpt = (BXPT_Handle)hPb->vhXpt;
2026
2027    if( Enable == true )
2028    {
2029        RegAddr = BCHP_XPT_PB0_PKTZ_CONTEXT0 + ( 4 * Context );
2030
2031        Reg = BXPT_Playback_P_ReadReg( hPb, RegAddr );
2032        Reg &= ~( 
2033            BCHP_MASK( XPT_PB0_PKTZ_CONTEXT0, PID ) |
2034            BCHP_MASK( XPT_PB0_PKTZ_CONTEXT0, CH_NUM ) |
2035            BCHP_MASK( XPT_PB0_PKTZ_CONTEXT0, PES_STREAM_ID ) 
2036        );
2037        BXPT_Playback_P_WriteReg( hPb, RegAddr, Reg ); 
2038
2039        Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL2 );
2040        Reg &= ~( 
2041                 BCHP_MASK( XPT_PB0_CTRL2, SYNC_EXT_MODE ) 
2042        );
2043        if (Cfg->PacketizerMode == BXPT_Playback_PacketizerMode_Es) 
2044        {
2045            hPb->ForceResync = true; /* for ES playback, the FORCE_RESYNC flag must be set for all descriptors. see SW7425-1672 */
2046            Reg &= ~( 
2047                 BCHP_MASK( XPT_PB0_CTRL2, PROGRAM_STREAM_EN )
2048            );
2049            Reg |= (
2050                BCHP_FIELD_DATA( XPT_PB0_CTRL2, SYNC_EXT_MODE, BXPT_PB_SYNC_BYPASS ) 
2051            );
2052        }
2053        else
2054        {
2055            hPb->ForceResync = false;
2056            Reg |= (
2057                BCHP_FIELD_DATA( XPT_PB0_CTRL2, SYNC_EXT_MODE, BXPT_PB_SYNC_PES )
2058            );
2059        }
2060        BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL2, Reg ); 
2061
2062        Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_PARSER_CTRL1 );
2063        Reg &= ~( 
2064            BCHP_MASK( XPT_PB0_PARSER_CTRL1, PARSER_PACKET_TYPE ) |
2065            BCHP_MASK( XPT_PB0_PARSER_CTRL1, PARSER_PKT_LENGTH ) |
2066            BCHP_MASK( XPT_PB0_PARSER_CTRL1, PARSER_ACCEPT_NULL_PKT_PRE_MPOD ) 
2067            );
2068        Reg |= (
2069            BCHP_FIELD_DATA( XPT_PB0_PARSER_CTRL1, PARSER_PACKET_TYPE, 0x00 ) |
2070            BCHP_FIELD_DATA( XPT_PB0_PARSER_CTRL1, PARSER_PKT_LENGTH, 0xBC ) |
2071            BCHP_FIELD_DATA( XPT_PB0_PARSER_CTRL1, PARSER_ACCEPT_NULL_PKT_PRE_MPOD, 1 )
2072            );
2073        BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_PARSER_CTRL1, Reg );
2074
2075        Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL4 );
2076        Reg &= ~( 
2077            BCHP_MASK( XPT_PB0_CTRL4, PKTZ_PUSI_SET_DIS ) |
2078            BCHP_MASK( XPT_PB0_CTRL4, PKTZ_CONTEXT_EN ) |
2079            BCHP_MASK( XPT_PB0_CTRL4, PACKETIZE_EN )|
2080            BCHP_MASK( XPT_PB0_CTRL4, PKTZ_PT_EN ) 
2081            );
2082
2083        switch(Cfg->PacketizerMode)
2084        {
2085        case BXPT_Playback_PacketizerMode_Es:
2086            SidFilter.Mode = BXPT_Spid_eChannelFilterMode_StreamIdRange;
2087            SidFilter.FilterConfig.StreamIdRange.Hi = 0xFF;
2088            SidFilter.FilterConfig.StreamIdRange.Lo = 0x00;
2089            BXPT_Spid_P_ConfigureChannelFilter(hXpt,Cfg->ChannelNum,SidFilter);
2090            Reg |= ( 
2091                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_PUSI_SET_DIS, 1 ) |
2092                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_SUB_ID_EN, 0 ) |
2093                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_STREAM_ID_EXT_EN, 0 ) |
2094                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_PT_EN, 1 )
2095            );
2096            break;
2097
2098        case BXPT_Playback_PacketizerMode_Pes_MapAll:
2099            /* Reg |= BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_CONTEXT_EN, 1 );*/
2100            SidFilter.Mode = BXPT_Spid_eChannelFilterMode_StreamIdRange;
2101            SidFilter.FilterConfig.StreamIdRange.Hi = 0xff;
2102            SidFilter.FilterConfig.StreamIdRange.Lo = 0x00;
2103            BXPT_Spid_P_ConfigureChannelFilter(hXpt,Cfg->ChannelNum,SidFilter);
2104            Reg |= ( 
2105                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_SUB_ID_EN, 1 ) |
2106                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_STREAM_ID_EXT_EN, 1 ) |
2107                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_PT_EN, 1 )
2108            );
2109            break;
2110
2111        case BXPT_Playback_PacketizerMode_Pes_Sid:       
2112            SidFilter.Mode = BXPT_Spid_eChannelFilterMode_StreamId;
2113            SidFilter.FilterConfig.StreamId = Cfg->FilterConfig.StreamId;
2114            BXPT_Spid_P_ConfigureChannelFilter(hXpt,Cfg->ChannelNum,SidFilter);
2115            Reg |= ( 
2116                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_SUB_ID_EN, 1 ) |
2117                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_STREAM_ID_EXT_EN, 1 ) |
2118                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_PT_EN, 1 )
2119            );
2120            break;
2121
2122        case BXPT_Playback_PacketizerMode_Pes_SidRange: 
2123            SidFilter.Mode = BXPT_Spid_eChannelFilterMode_StreamIdRange;
2124            SidFilter.FilterConfig.StreamIdRange.Hi = Cfg->FilterConfig.StreamIdRange.Hi;
2125            SidFilter.FilterConfig.StreamIdRange.Lo = Cfg->FilterConfig.StreamIdRange.Lo;
2126            BXPT_Spid_P_ConfigureChannelFilter(hXpt,Cfg->ChannelNum,SidFilter);
2127            Reg |= ( 
2128                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_SUB_ID_EN, 1 ) |
2129                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_STREAM_ID_EXT_EN, 1 ) |
2130                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_PT_EN, 1 )
2131            );
2132            break;
2133
2134        case BXPT_Playback_PacketizerMode_Pes_SidExtension: 
2135            SidFilter.Mode = BXPT_Spid_eChannelFilterMode_StreamIdExtension;
2136            SidFilter.FilterConfig.StreamIdAndExtension.Id = Cfg->FilterConfig.StreamIdAndExtension.Id;
2137            SidFilter.FilterConfig.StreamIdAndExtension.Extension = Cfg->FilterConfig.StreamIdAndExtension.Extension;
2138            BXPT_Spid_P_ConfigureChannelFilter(hXpt,Cfg->ChannelNum,SidFilter);
2139            Reg |= ( 
2140                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_SUB_ID_EN, 1 ) |
2141                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_STREAM_ID_EXT_EN, 1 ) |
2142                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_PT_EN, 1 )
2143            );
2144            break;
2145
2146        case BXPT_Playback_PacketizerMode_Pes_SidSubSid:
2147            SidFilter.Mode = BXPT_Spid_eChannelFilterMode_SubStreamId;
2148            SidFilter.FilterConfig.StreamIdAndSubStreamId.Id = Cfg->FilterConfig.StreamIdAndSubStreamId.Id;
2149            SidFilter.FilterConfig.StreamIdAndSubStreamId.SubStreamId = Cfg->FilterConfig.StreamIdAndSubStreamId.SubStreamId;
2150            BXPT_Spid_P_ConfigureChannelFilter(hXpt,Cfg->ChannelNum,SidFilter);
2151            Reg |= ( 
2152                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_SUB_ID_EN, 1 ) |
2153                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_STREAM_ID_EXT_EN, 1 ) |
2154                BCHP_FIELD_DATA( XPT_PB0_CTRL4, PKTZ_PT_EN, 1 )
2155            );
2156            break;
2157       }
2158        Reg |= BCHP_FIELD_DATA( XPT_PB0_CTRL4, PACKETIZE_EN, 1 );
2159        BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL4, Reg ); 
2160
2161        /* Disable CC checking, but enable CC generation in the full parser. */
2162        BXPT_GetPidChannel_CC_Config( hXpt, Cfg->ChannelNum, &ccConfig );
2163        ccConfig.Primary_CC_CheckEnable = false;
2164        ccConfig.Generate_CC_Enable = true;
2165        BXPT_SetPidChannel_CC_Config( hXpt, Cfg->ChannelNum, &ccConfig );
2166    }
2167    else
2168    {
2169        hPb->ForceResync = false;
2170
2171        RegAddr = BCHP_XPT_PB0_PKTZ_CONTEXT0 + ( 4 * Context );
2172        Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_PKTZ_CONTEXT0 );
2173        Reg &= ~( 
2174            BCHP_MASK( XPT_PB0_PKTZ_CONTEXT0, PID ) |
2175            BCHP_MASK( XPT_PB0_PKTZ_CONTEXT0, CH_NUM ) |
2176            BCHP_MASK( XPT_PB0_PKTZ_CONTEXT0, PES_STREAM_ID ) 
2177            );
2178        BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_PKTZ_CONTEXT0, Reg ); 
2179
2180        SidFilter.Mode = BXPT_Spid_eChannelFilterMode_Disable;
2181        BXPT_Spid_P_ConfigureChannelFilter(hXpt,Cfg->ChannelNum,SidFilter);
2182
2183        BXPT_GetPidChannel_CC_Config( hXpt, Cfg->ChannelNum, &ccConfig );
2184        ccConfig.Primary_CC_CheckEnable = true;
2185        ccConfig.Generate_CC_Enable = false;
2186        BXPT_SetPidChannel_CC_Config( hXpt, Cfg->ChannelNum, &ccConfig );
2187       
2188        /*
2189        ** SCheck the packetizer in each SPID/PID channel. If all the channels that are mapped to
2190        ** this playback are Invalid, disable packetizing at the PB control reg.
2191        */
2192       for( Index = 0; Index < BXPT_NUM_PID_CHANNELS; Index++ )
2193        {
2194                unsigned int Band, Pid;
2195            bool IsPlayback;         
2196
2197            BXPT_GetPidChannelConfig( hXpt, Index, &Pid, &Band, &IsPlayback );
2198
2199            RegAddr = BCHP_XPT_FE_SPID_TABLE_i_ARRAY_BASE + ( 4 * Index );
2200            Reg = BREG_Read32( hXpt->hRegister, RegAddr );
2201
2202            i = BCHP_GET_FIELD_DATA( Reg, XPT_FE_SPID_TABLE_i, SPID_MODE );
2203
2204            /* if this pid channnel is used for spid functions or disabled */
2205            if((i >= BXPT_Spid_eChannelMode_Disable && i <= BXPT_Spid_eChannelMode_Remap)
2206            && Band == hPb->ChannelNo && IsPlayback )
2207                continue;
2208            else
2209                break;
2210        }
2211
2212        if( Index == BXPT_NUM_PID_CHANNELS )
2213        {
2214            /* All contexts where invalid, so disable packetizer in the PB control reg. */
2215            Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL4 );
2216            Reg &= ~( 
2217                BCHP_MASK( XPT_PB0_CTRL4, PKTZ_CONTEXT_EN ) |
2218                BCHP_MASK( XPT_PB0_CTRL4, PACKETIZE_EN ) |
2219                BCHP_MASK( XPT_PB0_CTRL4, PKTZ_PT_EN )
2220                );
2221            BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL4, Reg ); 
2222
2223            Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_PARSER_CTRL1 );
2224            Reg &= ~( 
2225                BCHP_MASK( XPT_PB0_PARSER_CTRL1, PARSER_PACKET_TYPE ) |
2226                BCHP_MASK( XPT_PB0_PARSER_CTRL1, PARSER_PKT_LENGTH ) |
2227                BCHP_MASK( XPT_PB0_PARSER_CTRL1, PARSER_ACCEPT_NULL_PKT_PRE_MPOD ) 
2228                );
2229            Reg |= (
2230                BCHP_FIELD_DATA( XPT_PB0_PARSER_CTRL1, PARSER_PKT_LENGTH, 0xBC ) 
2231                );
2232            BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_PARSER_CTRL1, Reg ); 
2233
2234            Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL2 );
2235            Reg &= ~( 
2236                BCHP_MASK( XPT_PB0_CTRL2, SYNC_EXT_MODE )
2237            );
2238            Reg |= (
2239                BCHP_FIELD_DATA( XPT_PB0_CTRL2, SYNC_EXT_MODE, BXPT_PB_SYNC_MPEG_BLIND )
2240            );
2241            BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL2, Reg ); 
2242        }
2243    }
2244
2245    return( ExitCode );
2246}
2247
2248 
2249BERR_Code BXPT_Playback_DisablePacketizers(
2250    BXPT_Playback_Handle hPb                    /* [in] Handle for the playback channel */
2251    )
2252{ 
2253    uint32_t Reg, RegAddr;
2254    unsigned Index;
2255
2256    BERR_Code ExitCode = BERR_SUCCESS;
2257
2258    {
2259        int32_t i;
2260        BXPT_Handle hXpt = (BXPT_Handle)hPb->vhXpt;
2261
2262        for( Index = 0; Index < BXPT_NUM_PID_CHANNELS; Index++ )
2263        {
2264            /* if the pid channel input is this parser band cleanup the SPID table */
2265            RegAddr = BCHP_XPT_FE_PID_TABLE_i_ARRAY_BASE + ( 4 * Index ); 
2266            Reg = BREG_Read32( hXpt->hRegister, RegAddr );
2267   
2268            if(!BCHP_GET_FIELD_DATA( Reg, XPT_FE_PID_TABLE_i,PLAYBACK_FE_SEL))
2269                continue;
2270            /* pb parser is the input */
2271            if(BCHP_GET_FIELD_DATA( Reg, XPT_FE_PID_TABLE_i,PLAYBACK_BAND_PARSER_PID_CHANNEL_INPUT_SELECT)!= hPb->ChannelNo)
2272                continue;
2273   
2274            RegAddr = BCHP_XPT_FE_SPID_TABLE_i_ARRAY_BASE + ( 4 * Index );
2275            Reg = BREG_Read32( hXpt->hRegister, RegAddr );
2276   
2277            i = BCHP_GET_FIELD_DATA( Reg, XPT_FE_SPID_TABLE_i, SPID_MODE );
2278   
2279            /* if this pid channnel is used for spid functions or disabled */
2280            if(i >= BXPT_Spid_eChannelMode_Disable && i <= BXPT_Spid_eChannelMode_Remap)
2281                    continue;
2282            else
2283            {
2284                Reg &= ~( 
2285                BCHP_MASK( XPT_FE_SPID_TABLE_i, SPID_MODE ) |
2286                BCHP_MASK( XPT_FE_SPID_TABLE_i, STREAM_ID_RANGE_STREAM_ID_HI ) |
2287                BCHP_MASK( XPT_FE_SPID_TABLE_i, STREAM_ID_RANGE_STREAM_ID_LO )
2288                );
2289   
2290                BREG_Write32( hXpt->hRegister, RegAddr, Reg );
2291            }
2292        }
2293    }
2294
2295    RegAddr = BCHP_XPT_PB0_PKTZ_CONTEXT0 + ( 4 * Index );
2296    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_PKTZ_CONTEXT0 );
2297    Reg &= ~( 
2298        BCHP_MASK( XPT_PB0_PKTZ_CONTEXT0, PID ) |
2299        BCHP_MASK( XPT_PB0_PKTZ_CONTEXT0, CH_NUM ) |
2300        BCHP_MASK( XPT_PB0_PKTZ_CONTEXT0, PES_STREAM_ID ) 
2301        );
2302    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_PKTZ_CONTEXT0, Reg ); 
2303
2304    /* Disable packetizer in the PB control reg. */
2305    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL4 );                         
2306    Reg &= ~( 
2307        BCHP_MASK( XPT_PB0_CTRL4, PKTZ_CONTEXT_EN ) |
2308        BCHP_MASK( XPT_PB0_CTRL4, PACKETIZE_EN ) |
2309        BCHP_MASK( XPT_PB0_CTRL4, PKTZ_PT_EN )|
2310        BCHP_MASK( XPT_PB0_CTRL4, PKTZ_SUB_ID_EN )|
2311        BCHP_MASK( XPT_PB0_CTRL4, PKTZ_STREAM_ID_EXT_EN )
2312        );
2313    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL4, Reg ); 
2314
2315    /* These parser settings are always loaded when BXPT_Playback_PacketizeStream() is called. */
2316    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_PARSER_CTRL1 );
2317    Reg &= ~( 
2318        BCHP_MASK( XPT_PB0_PARSER_CTRL1, PARSER_PACKET_TYPE ) |
2319        BCHP_MASK( XPT_PB0_PARSER_CTRL1, PARSER_PKT_LENGTH ) |
2320        BCHP_MASK( XPT_PB0_PARSER_CTRL1, PARSER_ACCEPT_NULL_PKT_PRE_MPOD ) 
2321        );
2322    Reg |= (
2323        BCHP_FIELD_DATA( XPT_PB0_PARSER_CTRL1, PARSER_PKT_LENGTH, 0xBC ) 
2324        );
2325    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_PARSER_CTRL1, Reg );
2326
2327    return ExitCode;
2328}
2329
2330BERR_Code BXPT_Playback_GetParserConfig(
2331    BXPT_Playback_Handle hPb,                   /* [in] Handle for the playback channel */
2332    BXPT_Playback_ParserConfig *ParserConfig    /* [out] The current settings */
2333    )
2334{
2335    uint32_t Reg;
2336    BXPT_Handle hXpt;
2337
2338    BERR_Code ExitCode = BERR_SUCCESS;
2339
2340    BDBG_ASSERT( hPb );
2341    BDBG_ASSERT( ParserConfig );
2342
2343    hXpt = ( BXPT_Handle ) hPb->vhXpt;
2344
2345    /* The parser config registers are at consecutive addresses. */
2346    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_PARSER_CTRL1 );
2347   
2348    ParserConfig->ErrorInputIgnore = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_PARSER_CTRL1, PARSER_ERROR_INPUT_TEI_IGNORE );
2349    ParserConfig->AllPass = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_PARSER_CTRL1, PARSER_ALL_PASS_CTRL_PRE_MPOD );
2350    ParserConfig->AcceptNulls = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_PARSER_CTRL1, PARSER_ACCEPT_NULL_PKT_PRE_MPOD );
2351 
2352    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL4 );
2353    ParserConfig->ForceRestamping = BCHP_GET_FIELD_DATA( Reg, XPT_PB0_CTRL4, PARSER_FORCE_RESTAMP );
2354
2355#if BCHP_XPT_FULL_PID_PARSER_PBP_ACCEPT_ADAPT_00_PB0_ACCEPT_ADP_00_MASK != 0x00000001 || BXPT_NUM_PLAYBACKS > 32
2356    #error "PI NEEDS UPDATING"
2357#else
2358        Reg = BREG_Read32( hPb->hRegister, BCHP_XPT_FULL_PID_PARSER_PBP_ACCEPT_ADAPT_00 );
2359        ParserConfig->AcceptAdapt00 = (Reg >> hPb->ChannelNo) & 0x01 ? true : false;
2360#endif
2361
2362    return( ExitCode );
2363}
2364
2365BERR_Code BXPT_Playback_SetParserConfig(
2366    BXPT_Playback_Handle hPb,                   /* [in] Handle for the playback channel */
2367    const BXPT_Playback_ParserConfig *ParserConfig  /* [in] The new settings */
2368    )
2369{
2370    uint32_t Reg;
2371    BXPT_Handle hXpt;
2372
2373    BERR_Code ExitCode = BERR_SUCCESS;
2374
2375    BDBG_ASSERT( hPb );
2376    BDBG_ASSERT( ParserConfig );
2377
2378    hXpt = ( BXPT_Handle ) hPb->vhXpt;
2379
2380    /* The parser config registers are at consecutive addresses. */
2381    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_PARSER_CTRL1 );
2382   
2383    /* Clear all the bits we are about to change. */
2384    Reg &= ~(
2385        BCHP_MASK( XPT_PB0_PARSER_CTRL1, PARSER_ERROR_INPUT_TEI_IGNORE ) |
2386        BCHP_MASK( XPT_PB0_PARSER_CTRL1, PARSER_ALL_PASS_CTRL_PRE_MPOD ) |
2387        BCHP_MASK( XPT_PB0_PARSER_CTRL1, PARSER_ACCEPT_NULL_PKT_PRE_MPOD ) 
2388    );
2389
2390    /* Now set the new values. */
2391    Reg |= (
2392        BCHP_FIELD_DATA( XPT_PB0_PARSER_CTRL1, PARSER_ERROR_INPUT_TEI_IGNORE, ParserConfig->ErrorInputIgnore ) |
2393        BCHP_FIELD_DATA( XPT_PB0_PARSER_CTRL1, PARSER_ALL_PASS_CTRL_PRE_MPOD, ParserConfig->AllPass == true ? 1 : 0 ) |
2394        BCHP_FIELD_DATA( XPT_PB0_PARSER_CTRL1, PARSER_ACCEPT_NULL_PKT_PRE_MPOD, ParserConfig->AcceptNulls ) 
2395    );
2396
2397    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_PARSER_CTRL1, Reg ); 
2398
2399    if( ParserConfig->AllPass && false == hPb->IsParserInAllPass )
2400    {
2401        BXPT_PidChannel_CC_Config AllCcDisabled = { false, false, false, 0 };
2402
2403        /* Remember the config before entering all-pass. */
2404        BXPT_GetPidChannel_CC_Config( hXpt, hPb->ChannelNo + BXPT_GET_PLAYBACK_ALLPASS_CHNL(hPb->ChannelNo) , &hPb->CcConfigBeforeAllPass );
2405
2406        /* Now disable the CC checks */
2407        BXPT_SetPidChannel_CC_Config( hXpt, hPb->ChannelNo + BXPT_GET_PLAYBACK_ALLPASS_CHNL(hPb->ChannelNo), &AllCcDisabled );
2408        hPb->IsParserInAllPass = true;
2409    }
2410    else if( false == ParserConfig->AllPass ) 
2411    {
2412        /* Restore the config we had before entering all-pass. */
2413        BXPT_SetPidChannel_CC_Config( hXpt, hPb->ChannelNo + BXPT_GET_PLAYBACK_ALLPASS_CHNL(hPb->ChannelNo), &hPb->CcConfigBeforeAllPass );
2414        hPb->IsParserInAllPass = false;
2415    }
2416
2417    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL4 );
2418    Reg &= ~( BCHP_MASK( XPT_PB0_CTRL4, PARSER_FORCE_RESTAMP ) );
2419    Reg |= ( BCHP_FIELD_DATA( XPT_PB0_CTRL4, PARSER_FORCE_RESTAMP, ParserConfig->ForceRestamping ) );
2420    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL4, Reg ); 
2421
2422#if BCHP_XPT_FULL_PID_PARSER_PBP_ACCEPT_ADAPT_00_PB0_ACCEPT_ADP_00_MASK != 0x00000001 || BXPT_NUM_PLAYBACKS > 32
2423    #error "PI NEEDS UPDATING"
2424#else
2425                Reg = BREG_Read32( hXpt->hRegister, BCHP_XPT_FULL_PID_PARSER_PBP_ACCEPT_ADAPT_00 );
2426                Reg &= ~(0x01 << hPb->ChannelNo);
2427        if( ParserConfig->AcceptAdapt00 ) 
2428            Reg |= (0x01 << hPb->ChannelNo);
2429                BREG_Write32( hXpt->hRegister, BCHP_XPT_FULL_PID_PARSER_PBP_ACCEPT_ADAPT_00, Reg );
2430#endif
2431
2432    return( ExitCode );
2433}
2434
2435void BXPT_Playback_P_WriteReg(
2436    BXPT_Playback_Handle PlaybackHandle,    /* [in] Handle for the playback channel */
2437    uint32_t Pb0RegAddr,
2438    uint32_t RegVal
2439    )
2440{
2441    /*
2442    ** The address is the offset of the register from the beginning of the
2443    ** block, plus the base address of the block ( which changes from
2444    ** channel to channel ).
2445    */
2446    uint32_t RegAddr = Pb0RegAddr - BCHP_XPT_PB0_CTRL1 + PlaybackHandle->BaseAddr;
2447
2448    BREG_Write32( PlaybackHandle->hRegister, RegAddr, RegVal );
2449}       
2450
2451
2452uint32_t BXPT_Playback_P_ReadReg(
2453    BXPT_Playback_Handle PlaybackHandle,    /* [in] Handle for the playback channel */
2454    uint32_t Pb0RegAddr
2455    )
2456{
2457    /*
2458    ** The address is the offset of the register from the beginning of the
2459    ** block, plus the base address of the block ( which changes from
2460    ** channel to channel ).
2461    */
2462    uint32_t RegAddr = Pb0RegAddr - BCHP_XPT_PB0_CTRL1 + PlaybackHandle->BaseAddr;
2463
2464    return( BREG_Read32( PlaybackHandle->hRegister, RegAddr ));
2465}
2466
2467
2468BERR_Code BXPT_Playback_P_CreateDesc( 
2469    BXPT_Handle hXpt,                       /* [in] Handle for this transport */
2470    BXPT_PvrDescriptor * const Desc,        /* [in] Descriptor to initialize */ 
2471    uint8_t *Buffer,                        /* [in] Data buffer. */
2472    uint32_t BufferLength,                  /* [in] Size of buffer (in bytes). */
2473    bool IntEnable,                         /* [in] Interrupt when done? */
2474    BXPT_PvrDescriptor * const NextDesc     /* [in] Next descriptor, or NULL */
2475    )
2476{
2477    uint32_t BufferPhysicalAddr;
2478    uint32_t ThisDescPhysicalAddr;
2479    BMEM_Handle hHeap;
2480
2481    BERR_Code ExitCode = BERR_SUCCESS;
2482                                                               
2483    BDBG_ASSERT( hXpt );
2484    BDBG_ASSERT( Desc );
2485    BDBG_ASSERT( Buffer );
2486
2487    if( hXpt->hPbHeap )
2488        hHeap = hXpt->hPbHeap;
2489    else
2490        hHeap = hXpt->hMemory;
2491
2492    BMEM_ConvertAddressToOffset( hHeap, ( void * ) Buffer, &BufferPhysicalAddr );
2493
2494    /* Verify that the descriptor we're creating sits on a 16-byte boundary. */
2495    BMEM_ConvertAddressToOffset( hHeap, ( void * ) Desc, &ThisDescPhysicalAddr );
2496    if( ThisDescPhysicalAddr % 16 )
2497    {
2498        BDBG_ERR(( "Desc is not 16-byte aligned!" ));
2499        ExitCode = BERR_TRACE( BERR_INVALID_PARAMETER );
2500    }
2501
2502    /* Load the descriptor's buffer address, length, and flags. */
2503    Desc->BufferStartAddr = BufferPhysicalAddr;
2504    Desc->BufferLength = BufferLength;
2505
2506    /* Clear everything, then set the ones we want below. */
2507    Desc->Flags = 0;                                                                       
2508
2509    if( IntEnable )
2510        Desc->Flags |= TRANS_DESC_INT_FLAG;
2511
2512    /* Load the pointer to the next descriptor in the chain, if there is one. */
2513    if( NextDesc != 0 )
2514    {
2515        /* There is a another descriptor in the chain after this one. */
2516        uint32_t NextDescPhysAddr;
2517
2518        BMEM_ConvertAddressToOffset( hHeap, ( void * ) NextDesc, &NextDescPhysAddr );
2519        if( NextDescPhysAddr % 16 )
2520        {
2521            BDBG_ERR(( "NextDescDesc is not 32-bit aligned!" ));
2522            ExitCode = BERR_TRACE( BERR_INVALID_PARAMETER );
2523        }
2524
2525        /* Next descriptor address must be 16-byte aligned. */
2526        NextDescPhysAddr &= ~( 0xF );
2527        Desc->NextDescAddr = NextDescPhysAddr;
2528    }
2529    else                 
2530    {
2531        /* There is NOT another descriptor. Set the Last Descriptor bit. */
2532        BXPT_SetLastDescriptorFlag( Desc );
2533    }
2534
2535    return( ExitCode );
2536}
2537
2538#ifdef ENABLE_PLAYBACK_MUX
2539void BXPT_Playback_SetDescBuf( 
2540        BXPT_Handle hXpt,                                               /* [in] Handle for this transport */
2541        BXPT_PvrDescriptor * const Desc,                /* [in] Descriptor to initialize */ 
2542        uint8_t *Buffer,                                                /* [in] Data buffer. */
2543        uint32_t BufferLength                                   /* [in] Size of buffer (in bytes). */
2544        )
2545{
2546        BMEM_ConvertAddressToOffset(hXpt->hMemory, ( void * ) Buffer, &(Desc->BufferStartAddr));
2547        Desc->BufferLength = BufferLength;
2548}
2549#endif /*ENABLE_PLAYBACK_MUX*/
2550
2551BINT_Id BXPT_Playback_GetIntId(
2552    BXPT_Playback_Handle hPb,                   /* [in] Handle for the playback channel */
2553    BXPT_Playback_Int PbInt
2554    )
2555{
2556    uint32_t RegAddr; 
2557
2558    BDBG_ASSERT( hPb );
2559   
2560    RegAddr = BCHP_XPT_PB0_INTR - BCHP_XPT_PB0_CTRL1 + hPb->BaseAddr;
2561    return BCHP_INT_ID_CREATE( RegAddr, PbInt );
2562}
2563
2564#if BXPT_HAS_TSMUX
2565
2566void BXPT_Playback_GetMuxingInfo(
2567    BXPT_Playback_Handle hPb,                   /* [in] Handle for the playback channel */
2568    BXPT_Playback_MuxingInfo *Info
2569    )
2570{
2571    BDBG_ASSERT( hPb );
2572    BDBG_ASSERT( Info );
2573
2574    Info->uiPacingCounter = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_PACING_COUNTER );
2575}
2576
2577BERR_Code BXPT_Playback_P_SetPacingSpeed( 
2578    BXPT_Playback_Handle hPb,                   /* [in] Handle for the playback channel */
2579    unsigned Speed
2580    )
2581{
2582    uint32_t Reg;
2583
2584    unsigned PacingSpeedBitField = 0;
2585    BERR_Code ExitCode = BERR_SUCCESS;
2586                                                               
2587    BDBG_ASSERT( hPb );
2588
2589    switch( Speed )
2590    {
2591        case 1: PacingSpeedBitField = 0; break;
2592        case 2: PacingSpeedBitField = 1; break;
2593        case 4: PacingSpeedBitField = 2; break;
2594        case 8: PacingSpeedBitField = 3; break;
2595        case 16: PacingSpeedBitField = 4; break;
2596        case 32: PacingSpeedBitField = 5; break;
2597        case 64: PacingSpeedBitField = 6; break;
2598        case 128: PacingSpeedBitField = 7; break;
2599
2600        default: 
2601        BDBG_ERR(( "Invalid pacing speed %u", Speed ));
2602        ExitCode = BERR_TRACE( BERR_INVALID_PARAMETER );
2603        goto Done;
2604        break;
2605    }
2606
2607    Reg = BXPT_Playback_P_ReadReg( hPb, BCHP_XPT_PB0_CTRL2 );
2608    Reg &= ~( BCHP_MASK( XPT_PB0_CTRL2, PACING_SPEED ) );
2609    Reg |= ( BCHP_FIELD_DATA( XPT_PB0_CTRL2, PACING_SPEED, PacingSpeedBitField ) );
2610    BXPT_Playback_P_WriteReg( hPb, BCHP_XPT_PB0_CTRL2, Reg );
2611
2612    Done:
2613    return ExitCode;
2614}
2615
2616void BXPT_Playback_P_SetPacingCount(
2617    BXPT_Playback_Handle hPb,                   /* [in] Handle for the playback channel */
2618    unsigned PacingLoadMap,
2619    unsigned PacingCount
2620    )
2621{
2622    hPb->PacingLoadMap = PacingLoadMap;
2623    hPb->PacingCount = PacingCount;
2624    hPb->PacingLoadNeeded = true;
2625}
2626
2627#endif
2628
2629
2630
2631
Note: See TracBrowser for help on using the repository browser.