blob: 1d7d0f9d7f42565ef391c8f0791e13c21f7009ef [file] [log] [blame]
Frank Vibrans2b4c8312011-02-14 18:30:54 +00001/**
2 * @file
3 *
4 * Config Southbridge HD Audio Controller
5 *
6 *
7 *
8 * @xrefitem bom "File Content Label" "Release Content"
9 * @e project: CIMx-SB
10 * @e sub-project:
11 * @e \$Revision:$ @e \$Date:$
12 *
13 */
14
15/*
16 *****************************************************************************
17 *
18 * Copyright (c) 2011, Advanced Micro Devices, Inc.
19 * All rights reserved.
Edward O'Callaghanef5981b2014-07-06 19:20:52 +100020 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000021 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 * * Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * * Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
Edward O'Callaghanef5981b2014-07-06 19:20:52 +100028 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
29 * its contributors may be used to endorse or promote products derived
Frank Vibrans2b4c8312011-02-14 18:30:54 +000030 * from this software without specific prior written permission.
Edward O'Callaghanef5981b2014-07-06 19:20:52 +100031 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000032 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Edward O'Callaghanef5981b2014-07-06 19:20:52 +100042 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000043 * ***************************************************************************
44 *
45 */
46
47
48#include "SBPLATFORM.h"
49#include "cbtypes.h"
50
51//
52// Declaration of local functions
53//
54
55VOID configureAzaliaPinCmd (IN AMDSBCFG* pConfig, IN UINT32 ddBAR0, IN UINT8 dbChannelNum);
56VOID configureAzaliaSetConfigD4Dword (IN CODECENTRY* tempAzaliaCodecEntryPtr, IN UINT32 ddChannelNum, IN UINT32 ddBAR0);
57
58/**
59 * Pin Config for ALC880, ALC882 and ALC883.
60 *
61 *
62 *
63 */
Elyes HAOUASad1456f2019-06-22 09:52:12 +020064static const CODECENTRY AzaliaCodecAlc882Table[] =
Frank Vibrans2b4c8312011-02-14 18:30:54 +000065{
66 {0x14, 0x01014010},
67 {0x15, 0x01011012},
68 {0x16, 0x01016011},
69 {0x17, 0x01012014},
70 {0x18, 0x01A19030},
71 {0x19, 0x411111F0},
72 {0x1a, 0x01813080},
73 {0x1b, 0x411111F0},
74 {0x1C, 0x411111F0},
75 {0x1d, 0x411111F0},
76 {0x1e, 0x01441150},
77 {0x1f, 0x01C46160},
78 {0xff, 0xffffffff}
79};
80
81/**
82 * Pin Config for ALC0262.
83 *
84 *
85 *
86 */
Elyes HAOUASad1456f2019-06-22 09:52:12 +020087static const CODECENTRY AzaliaCodecAlc262Table[] =
Frank Vibrans2b4c8312011-02-14 18:30:54 +000088{
89 {0x14, 0x01014010},
90 {0x15, 0x411111F0},
91 {0x16, 0x411111F0},
92 {0x18, 0x01A19830},
93 {0x19, 0x02A19C40},
94 {0x1a, 0x01813031},
95 {0x1b, 0x02014C20},
96 {0x1c, 0x411111F0},
97 {0x1d, 0x411111F0},
98 {0x1e, 0x0144111E},
99 {0x1f, 0x01C46150},
100 {0xff, 0xffffffff}
101};
102
103/**
104 * Pin Config for ALC0269.
105 *
106 *
107 *
108 */
Elyes HAOUASad1456f2019-06-22 09:52:12 +0200109static const CODECENTRY AzaliaCodecAlc269Table[] =
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000110{
111 {0x12, 0x99A30960},
112 {0x14, 0x99130110},
113 {0x15, 0x0221401F},
114 {0x16, 0x99130120},
115 {0x18, 0x01A19850},
116 {0x19, 0x02A15951},
117 {0x1a, 0x01813052},
118 {0x1b, 0x0181405F},
119 {0x1d, 0x40134601},
120 {0x1e, 0x01441130},
121 {0x11, 0x18567140},
122 {0x20, 0x0030FFFF},
123 {0xff, 0xffffffff}
124};
125
126/**
127 * Pin Config for ALC0861.
128 *
129 *
130 *
131 */
Elyes HAOUASad1456f2019-06-22 09:52:12 +0200132static const CODECENTRY AzaliaCodecAlc861Table[] =
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000133{
134 {0x01, 0x8086C601},
135 {0x0B, 0x01014110},
136 {0x0C, 0x01813140},
137 {0x0D, 0x01A19941},
138 {0x0E, 0x411111F0},
139 {0x0F, 0x02214420},
140 {0x10, 0x02A1994E},
141 {0x11, 0x99330142},
142 {0x12, 0x01451130},
143 {0x1F, 0x411111F0},
144 {0x20, 0x411111F0},
145 {0x23, 0x411111F0},
146 {0xff, 0xffffffff}
147};
148
149/**
150 * Pin Config for ALC0889.
151 *
152 *
153 *
154 */
Elyes HAOUASad1456f2019-06-22 09:52:12 +0200155static const CODECENTRY AzaliaCodecAlc889Table[] =
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000156{
157 {0x11, 0x411111F0},
158 {0x14, 0x01014010},
159 {0x15, 0x01011012},
160 {0x16, 0x01016011},
161 {0x17, 0x01013014},
162 {0x18, 0x01A19030},
163 {0x19, 0x411111F0},
164 {0x1a, 0x411111F0},
165 {0x1b, 0x411111F0},
166 {0x1C, 0x411111F0},
167 {0x1d, 0x411111F0},
168 {0x1e, 0x01442150},
169 {0x1f, 0x01C42160},
170 {0xff, 0xffffffff}
171};
172
173/**
174 * Pin Config for ADI1984.
175 *
176 *
177 *
178 */
Elyes HAOUASad1456f2019-06-22 09:52:12 +0200179static const CODECENTRY AzaliaCodecAd1984Table[] =
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000180{
181 {0x11, 0x0221401F},
182 {0x12, 0x90170110},
183 {0x13, 0x511301F0},
184 {0x14, 0x02A15020},
185 {0x15, 0x50A301F0},
186 {0x16, 0x593301F0},
187 {0x17, 0x55A601F0},
188 {0x18, 0x55A601F0},
189 {0x1A, 0x91F311F0},
190 {0x1B, 0x014511A0},
191 {0x1C, 0x599301F0},
192 {0xff, 0xffffffff}
193};
194
195/**
196 * FrontPanel Config table list
197 *
198 *
199 *
200 */
Elyes HAOUASad1456f2019-06-22 09:52:12 +0200201static const CODECENTRY FrontPanelAzaliaCodecTableList[] =
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000202{
203 {0x19, 0x02A19040},
204 {0x1b, 0x02214020},
205 {0xff, 0xffffffff}
206};
207
208/**
209 * Current HD Audio support codec list
210 *
211 *
212 *
213 */
Elyes HAOUASad1456f2019-06-22 09:52:12 +0200214static const CODECTBLLIST azaliaCodecTableList[] =
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000215{
216 {0x010ec0880, (CODECENTRY*)&AzaliaCodecAlc882Table[0]},
217 {0x010ec0882, (CODECENTRY*)&AzaliaCodecAlc882Table[0]},
218 {0x010ec0883, (CODECENTRY*)&AzaliaCodecAlc882Table[0]},
219 {0x010ec0885, (CODECENTRY*)&AzaliaCodecAlc882Table[0]},
220 {0x010ec0889, (CODECENTRY*)&AzaliaCodecAlc889Table[0]},
221 {0x010ec0262, (CODECENTRY*)&AzaliaCodecAlc262Table[0]},
222 {0x010ec0269, (CODECENTRY*)&AzaliaCodecAlc269Table[0]},
223 {0x010ec0861, (CODECENTRY*)&AzaliaCodecAlc861Table[0]},
224 {0x011d41984, (CODECENTRY*)&AzaliaCodecAd1984Table[0]},
225 { (UINT32) 0x0FFFFFFFF, (CODECENTRY*) (UINTN)0x0FFFFFFFF}
226};
227
228/**
229 * azaliaInitBeforePciEnum - Config HD Audio Before PCI emulation
230 *
231 *
232 *
233 * @param[in] pConfig Southbridge configuration structure pointer.
234 *
235 */
236VOID
237azaliaInitBeforePciEnum (
238 IN AMDSBCFG* pConfig
239 )
240{
241 if ( pConfig->AzaliaController == 1 ) {
242 RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEB, AccWidthUint8, ~BIT0, 0);
243 } else {
244 RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEB, AccWidthUint8, ~BIT0, BIT0);
245 if ( pConfig->BuildParameters.HdAudioMsi) {
246 RWPCI ((AZALIA_BUS_DEV_FUN << 16) + SB_AZ_REG44, AccWidthUint32 | S3_SAVE, ~BIT8, BIT8);
247 RWPCI ((AZALIA_BUS_DEV_FUN << 16) + SB_AZ_REG60, AccWidthUint32 | S3_SAVE, ~BIT16, BIT16);
248 }
249 }
250}
251
252/**
253 * azaliaInitAfterPciEnum - Config HD Audio after PCI emulation
254 *
255 *
256 *
257 * @param[in] pConfig Southbridge configuration structure pointer.
258 *
259 */
260VOID
261azaliaInitAfterPciEnum (
262 IN AMDSBCFG* pConfig
263 )
264{
265 UINT8 Data;
266 UINT8 i;
267 UINT8 dbEnableAzalia;
268 UINT8 dbPinRouting;
269 UINT8 dbChannelNum;
270 UINT8 dbTempVariable;
271 UINT16 dwTempVariable;
272 UINT32 ddBAR0;
273 UINT32 ddTempVariable;
274 dbEnableAzalia = 0;
275 dbChannelNum = 0;
276 dbTempVariable = 0;
277 dwTempVariable = 0;
278 ddBAR0 = 0;
279 ddTempVariable = 0;
280
281 if ( pConfig->AzaliaController == 1 ) {
282 return;
283 }
284
285 if ( pConfig->AzaliaController != 1 ) {
286 RWPCI ((AZALIA_BUS_DEV_FUN << 16) + SB_AZ_REG04, AccWidthUint8 | S3_SAVE, ~BIT1, BIT1);
Aaron Durbind907a342014-01-30 22:20:01 -0600287 if ( pConfig->BuildParameters.AzaliaSsid != 0 ) {
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000288 RWPCI ((AZALIA_BUS_DEV_FUN << 16) + SB_AZ_REG2C, AccWidthUint32 | S3_SAVE, 0x00, pConfig->BuildParameters.AzaliaSsid);
Edward O'Callaghanef5981b2014-07-06 19:20:52 +1000289 }
Frank Vibrans2b4c8312011-02-14 18:30:54 +0000290 ReadPCI ((AZALIA_BUS_DEV_FUN << 16) + SB_AZ_REG10, AccWidthUint32, &ddBAR0);
291 if ( ddBAR0 != 0 ) {
292 if ( ddBAR0 != 0xFFFFFFFF ) {
293 ddBAR0 &= ~(0x03FFF);
294 dbEnableAzalia = 1;
295 }
296 }
297 }
298
299 if ( dbEnableAzalia ) {
300 // Get SDIN Configuration
301 if ( pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin0 == 2 ) {
302 RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG167, AccWidthUint8, 0, 0x3E);
303 RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG167, AccWidthUint8, 0, 0x00);
304 } else {
305 RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG167, AccWidthUint8, 0, 0x0);
306 RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG167, AccWidthUint8, 0, 0x01);
307 }
308 if ( pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin1 == 2 ) {
309 RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG168, AccWidthUint8, 0, 0x3E);
310 RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG168, AccWidthUint8, 0, 0x00);
311 } else {
312 RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG168, AccWidthUint8, 0, 0x0);
313 RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG168, AccWidthUint8, 0, 0x01);
314 }
315 if ( pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin2 == 2 ) {
316 RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG169, AccWidthUint8, 0, 0x3E);
317 RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG169, AccWidthUint8, 0, 0x00);
318 } else {
319 RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG169, AccWidthUint8, 0, 0x0);
320 RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG169, AccWidthUint8, 0, 0x01);
321 }
322 if ( pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin3 == 2 ) {
323 RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG170, AccWidthUint8, 0, 0x3E);
324 RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG170, AccWidthUint8, 0, 0x00);
325 } else {
326 RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG170, AccWidthUint8, 0, 0x0);
327 RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG170, AccWidthUint8, 0, 0x01);
328 }
329 // INT#A Azalia resource
330 Data = 0x93; // Azalia APIC index
331 WriteIO (SB_IOMAP_REGC00, AccWidthUint8, &Data);
332 Data = 0x10; // IRQ16 (INTA#)
333 WriteIO (SB_IOMAP_REGC01, AccWidthUint8, &Data);
334
335 i = 11;
336 do {
337 ReadMEM ( ddBAR0 + SB_AZ_BAR_REG08, AccWidthUint8 | S3_SAVE, &dbTempVariable);
338 dbTempVariable |= BIT0;
339 WriteMEM (ddBAR0 + SB_AZ_BAR_REG08, AccWidthUint8 | S3_SAVE, &dbTempVariable);
340 SbStall (1000);
341 ReadMEM (ddBAR0 + SB_AZ_BAR_REG08, AccWidthUint8 | S3_SAVE, &dbTempVariable);
342 i--;
343 } while ((! (dbTempVariable & BIT0)) && (i > 0) );
344
345 if ( i == 0 ) {
346 return;
347 }
348
349 SbStall (1000);
350 ReadMEM ( ddBAR0 + SB_AZ_BAR_REG0E, AccWidthUint16, &dwTempVariable);
351 if ( dwTempVariable & 0x0F ) {
352
353 //atleast one azalia codec found
354 // ?? E0 is not real register what we expect. we have change to GPIO/and program GPIO Mux
355 //ReadMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGE0, AccWidthUint8, &dbPinRouting);
356 dbPinRouting = pConfig->AZALIACONFIG.AzaliaSdinPin;
357 do {
358 if ( ( ! (dbPinRouting & BIT0) ) && (dbPinRouting & BIT1) ) {
359// dbChannelNum = 3;
360 configureAzaliaPinCmd (pConfig, ddBAR0, dbChannelNum);
361 }
362 dbPinRouting >>= 2;
363 dbChannelNum++;
364 } while ( dbChannelNum != 4 );
365 } else {
366 //No Azalia codec found
367 if ( pConfig->AzaliaController != 2 ) {
368 dbEnableAzalia = 0; //set flag to disable Azalia
369 }
370 }
371 }
372
373 if ( dbEnableAzalia ) {
374 //redo clear reset
375 do {
376 dwTempVariable = 0;
377 WriteMEM ( ddBAR0 + SB_AZ_BAR_REG0C, AccWidthUint16 | S3_SAVE, &dwTempVariable);
378 ReadMEM (ddBAR0 + SB_AZ_BAR_REG08, AccWidthUint8 | S3_SAVE, &dbTempVariable);
379 dbTempVariable &= ~(BIT0);
380 WriteMEM (ddBAR0 + SB_AZ_BAR_REG08, AccWidthUint8 | S3_SAVE, &dbTempVariable);
381 ReadMEM (ddBAR0 + SB_AZ_BAR_REG08, AccWidthUint8 | S3_SAVE, &dbTempVariable);
382 } while ( dbTempVariable & BIT0 );
383
384 if ( pConfig->AzaliaSnoop == 1 ) {
385 RWPCI ((AZALIA_BUS_DEV_FUN << 16) + SB_AZ_REG42, AccWidthUint8 | S3_SAVE, 0xFF, BIT1 + BIT0);
386 }
387 } else {
388 //disable Azalia controller
389 RWPCI ((AZALIA_BUS_DEV_FUN << 16) + SB_AZ_REG04, AccWidthUint16 | S3_SAVE, 0, 0);
390 // RWPMIO (SB_PMIO_REG59, AccWidthUint8 | S3_SAVE, ~BIT3, 0);
391 RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEB, AccWidthUint8, ~BIT0, 0);
392 // RWPCI ((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REGFC, AccWidthUint8 | S3_SAVE, 0, 0x55);
393 RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEB, AccWidthUint8, ~BIT0, 0);
394 }
395}
396
397/**
398 * configureAzaliaPinCmd - Configuration HD Audio PIN Command
399 *
400 *
401 * @param[in] pConfig Southbridge configuration structure pointer.
402 * @param[in] ddBAR0 HD Audio BAR0 base address.
403 * @param[in] dbChannelNum Channel Number.
404 *
405 */
406VOID
407configureAzaliaPinCmd (
408 IN AMDSBCFG* pConfig,
409 IN UINT32 ddBAR0,
410 IN UINT8 dbChannelNum
411 )
412{
413 UINT32 ddTempVariable;
414 UINT32 ddChannelNum;
415 CODECTBLLIST* ptempAzaliaOemCodecTablePtr;
416 CODECENTRY* tempAzaliaCodecEntryPtr;
417
418 if ( (pConfig->AzaliaPinCfg) != 1 ) {
419 return;
420 }
421
422 ddChannelNum = dbChannelNum << 28;
423 ddTempVariable = 0xF0000;
424 ddTempVariable |= ddChannelNum;
425
426 WriteMEM (ddBAR0 + SB_AZ_BAR_REG60, AccWidthUint32 | S3_SAVE, &ddTempVariable);
427 SbStall (600);
428 ReadMEM (ddBAR0 + SB_AZ_BAR_REG64, AccWidthUint32 | S3_SAVE, &ddTempVariable);
429
430 if ( ((pConfig->AZOEMTBL.pAzaliaOemCodecTablePtr) == NULL) || ((pConfig->AZOEMTBL.pAzaliaOemCodecTablePtr) == ((CODECTBLLIST*) (UINTN)0xFFFFFFFF))) {
431 ptempAzaliaOemCodecTablePtr = (CODECTBLLIST*) FIXUP_PTR (&azaliaCodecTableList[0]);
432 } else {
433 ptempAzaliaOemCodecTablePtr = (CODECTBLLIST*) pConfig->AZOEMTBL.pAzaliaOemCodecTablePtr;
434 }
435
436 while ( ptempAzaliaOemCodecTablePtr->CodecID != 0xFFFFFFFF ) {
437 if ( ptempAzaliaOemCodecTablePtr->CodecID == ddTempVariable ) {
438 break;
439 } else {
440 ++ptempAzaliaOemCodecTablePtr;
441 }
442 }
443
444 if ( ptempAzaliaOemCodecTablePtr->CodecID != 0xFFFFFFFF ) {
445 tempAzaliaCodecEntryPtr = (CODECENTRY*) ptempAzaliaOemCodecTablePtr->CodecTablePtr;
446
447 if ( ((pConfig->AZOEMTBL.pAzaliaOemCodecTablePtr) == NULL) || ((pConfig->AZOEMTBL.pAzaliaOemCodecTablePtr) == ((CODECTBLLIST*) (UINTN)0xFFFFFFFF)) ) {
448 tempAzaliaCodecEntryPtr = (CODECENTRY*) FIXUP_PTR (tempAzaliaCodecEntryPtr);
449 }
450 configureAzaliaSetConfigD4Dword (tempAzaliaCodecEntryPtr, ddChannelNum, ddBAR0);
451 if ( pConfig->AzaliaFrontPanel != 1 ) {
452 if ( (pConfig->AzaliaFrontPanel == 2) || (pConfig->FrontPanelDetected == 1) ) {
453 if ( ((pConfig->AZOEMFPTBL.pAzaliaOemFpCodecTablePtr) == NULL) || ((pConfig->AZOEMFPTBL.pAzaliaOemFpCodecTablePtr) == (VOID*) (UINTN)0xFFFFFFFF) ) {
454 tempAzaliaCodecEntryPtr = (CODECENTRY*) FIXUP_PTR (&FrontPanelAzaliaCodecTableList[0]);
455 } else {
456 tempAzaliaCodecEntryPtr = (CODECENTRY*) pConfig->AZOEMFPTBL.pAzaliaOemFpCodecTablePtr;
457 }
458 configureAzaliaSetConfigD4Dword (tempAzaliaCodecEntryPtr, ddChannelNum, ddBAR0);
459 }
460 }
461 }
462}
463
464/**
465 * configureAzaliaSetConfigD4Dword - Configuration HD Audio Codec table
466 *
467 *
468 * @param[in] tempAzaliaCodecEntryPtr HD Audio Codec table structure pointer.
469 * @param[in] ddChannelNum HD Audio Channel Number.
470 * @param[in] ddBAR0 HD Audio BAR0 base address.
471 *
472 */
473VOID
474configureAzaliaSetConfigD4Dword (
475 IN CODECENTRY* tempAzaliaCodecEntryPtr,
476 IN UINT32 ddChannelNum,
477 IN UINT32 ddBAR0
478 )
479{
480 UINT8 dbtemp1;
481 UINT8 dbtemp2;
482 UINT8 i;
483 UINT32 ddtemp;
484 UINT32 ddtemp2;
485 ddtemp = 0;
486 ddtemp2 = 0;
487 while ( (tempAzaliaCodecEntryPtr->Nid) != 0xFF ) {
488 dbtemp1 = 0x20;
489 if ( (tempAzaliaCodecEntryPtr->Nid) == 0x1 ) {
490 dbtemp1 = 0x24;
491 }
492
493 ddtemp = tempAzaliaCodecEntryPtr->Nid;
494 ddtemp &= 0xff;
495 ddtemp <<= 20;
496 ddtemp |= ddChannelNum;
497
498 ddtemp |= (0x700 << 8);
499 for ( i = 4; i > 0; i-- ) {
500 do {
501 ReadMEM (ddBAR0 + SB_AZ_BAR_REG68, AccWidthUint32, &ddtemp2);
502 } while ( ddtemp2 & BIT0 );
503
504 dbtemp2 = (UINT8) (( (tempAzaliaCodecEntryPtr->Byte40) >> ((4 - i) * 8 ) ) & 0xff);
505 ddtemp = (ddtemp & 0xFFFF0000) + ((dbtemp1 - i) << 8) + dbtemp2;
506 WriteMEM (ddBAR0 + SB_AZ_BAR_REG60, AccWidthUint32 | S3_SAVE, &ddtemp);
507 SbStall (60);
508 }
509 ++tempAzaliaCodecEntryPtr;
510 }
511}
512