[coreboot] [PATCH] sb600: new way to load initial verb
Bao, Zheng
Zheng.Bao at amd.com
Mon Mar 8 09:20:27 CET 2010
The original way to load initial verb is quite inflexible.
The format of the command is:
CAd 31:28 - codec address
NID 27:20 - Nid
Verb 19:0 - Verb data
Each Nid has 4 byte data to write. It has to write one at a time.
0x01471c10, //1st byte 10
0x01471d40, //2nd byte 40
0x01471e01, //3rd byte 01
0x01471f01, //4th byte 01
The new code in sb600_hda.c and the code structure are quite
preliminary. When it is almost done and can satisfy everybody, We can
define the pin configuration code at mainboard.
#define CODEC_PIN_CONFIG_FILE "codec/alc_882.h"
or
config CODEC_PIN_CONFIG_FILE
string
default "codec/alc_882.h"
depends on BOARD_AMD_DBM690T
Now I am wondering if it is legal provide the intial pin configuration
code in coreboot. If it is legal, how can we get it? The 882 code is
got from CIM.
Signed-off-by: Zheng Bao <zheng.bao at amd.com>
Index: src/codec/alc_882.h
===================================================================
--- src/codec/alc_882.h (revision 0)
+++ src/codec/alc_882.h (revision 0)
@@ -0,0 +1,12 @@
+ {0x14, 0x01014010},
+ {0x15, 0x01011012},
+ {0x16, 0x01016011},
+ {0x17, 0x01012014},
+ {0x18, 0x01A19030},
+ {0x19, 0x411111F0},
+ {0x1a, 0x01813080},
+ {0x1b, 0x411111F0},
+ {0x1C, 0x411111F0},
+ {0x1d, 0x411111F0},
+ {0x1e, 0x01441150},
+ {0x1f, 0x01C46160},
Index: src/southbridge/amd/sb600/sb600_hda.c
===================================================================
--- src/southbridge/amd/sb600/sb600_hda.c (revision 5195)
+++ src/southbridge/amd/sb600/sb600_hda.c (working copy)
@@ -90,68 +90,19 @@
return 0;
}
-static u32 cim_verb_data[] = {
- 0x01471c10,
- 0x01471d40,
- 0x01471e01,
- 0x01471f01,
-/* 1 */
- 0x01571c12,
- 0x01571d10,
- 0x01571e01,
- 0x01571f01,
-/* 2 */
- 0x01671c11,
- 0x01671d60,
- 0x01671e01,
- 0x01671f01,
-/* 3 */
- 0x01771c14,
- 0x01771d20,
- 0x01771e01,
- 0x01771f01,
-/* 4 */
- 0x01871c30,
- 0x01871d90,
- 0x01871ea1,
- 0x01871f01,
-/* 5 */
- 0x01971cf0,
- 0x01971d11,
- 0x01971e11,
- 0x01971f41,
-/* 6 */
- 0x01a71c80,
- 0x01a71d30,
- 0x01a71e81,
- 0x01a71f01,
-/* 7 */
- 0x01b71cf0,
- 0x01b71d11,
- 0x01b71e11,
- 0x01b71f41,
-/* 8 */
- 0x01c71cf0,
- 0x01c71d11,
- 0x01c71e11,
- 0x01c71f41,
-/* 9 */
- 0x01d71cf0,
- 0x01d71d11,
- 0x01d71e11,
- 0x01d71f41,
-/* 10 */
- 0x01e71c50,
- 0x01e71d11,
- 0x01e71e44,
- 0x01e71f01,
-/* 11 */
- 0x01f71c60,
- 0x01f71d61,
- 0x01f71ec4,
- 0x01f71f01,
+typedef struct _pin_config_codec_entry {
+ u8 nid;
+ u32 pin_config;
+} pin_config_codec_entry;
+
+static pin_config_codec_entry pin_config_file[] = {
+#ifdef CODEC_PIN_CONFIG_FILE
+ #include CODEC_PIN_CONFIG_FILE
+#endif
+ {-1, -1}
};
-static u32 find_verb(u32 viddid, u32 ** verb)
+
+static void find_verb(u32 viddid, pin_config_codec_entry ** verb)
{
device_t azalia_dev = dev_find_slot(0, PCI_DEVFN(0x14, 2));
struct southbridge_amd_sb600_config *cfg =
@@ -159,12 +110,13 @@
printk_debug("Dev=%s\n", dev_path(azalia_dev));
printk_debug("Default viddid=%x\n", cfg->hda_viddid);
printk_debug("Reading viddid=%x\n", viddid);
+
+ *verb = NULL;
if (!cfg)
- return 0;
+ return;
if (viddid != cfg->hda_viddid)
- return 0;
- *verb = (u32 *) cim_verb_data;
- return sizeof(cim_verb_data) / sizeof(u32);
+ return;
+ *verb = pin_config_file;
}
/**
@@ -214,9 +166,8 @@
static void codec_init(u8 * base, int addr)
{
- u32 dword;
- u32 *verb;
- u32 verb_size;
+ u32 dword, dword1, pin_config;
+ pin_config_codec_entry *verb=NULL;
int i;
/* 1 */
@@ -233,23 +184,32 @@
/* 2 */
printk_debug("codec viddid: %08x\n", dword);
- verb_size = find_verb(dword, &verb);
+ find_verb(dword, &verb);
- if (!verb_size) {
+ if (verb == NULL) {
printk_debug("No verb!\n");
return;
}
- printk_debug("verb_size: %d\n", verb_size);
/* 3 */
- for (i = 0; i < verb_size; i++) {
- if (wait_for_ready(base) == -1)
- return;
+ for (verb; verb->nid != 0xFF; verb++) {
+ dword = addr << 28 | verb->nid << 20 | 7 << 16;
+ pin_config = verb->pin_config;
- write32(base + 0x60, verb[i]);
+ for (i = 4; i > 0; i--, pin_config >>= 8) {
+ if (wait_for_ready(base) == -1)
+ return;
- if (wait_for_valid(base) == -1)
- return;
+ if (verb->nid != 1)
+ dword1 = dword | ((0x20 - i) & 0xFF) <<
8;
+ else
+ dword1 = dword | ((0x24 - i) & 0xFF) <<
8;
+ dword1 |= (pin_config & 0xFF);
+ write32(base + 0x60, dword1);
+
+ if (wait_for_valid(base) == -1)
+ return;
+ }
}
printk_debug("verb loaded!\n");
}
-----Original Message-----
From: coreboot-bounces at coreboot.org
[mailto:coreboot-bounces at coreboot.org] On Behalf Of Carl-Daniel
Hailfinger
Sent: Friday, March 05, 2010 10:03 PM
To: Stefan Reinauer
Cc: coreboot at coreboot.org
Subject: Re: [coreboot] [PATCH] sb600: don't load verb for codec
On 05.03.2010 11:13, Stefan Reinauer wrote:
> On 3/5/10 10:29 AM, Bao, Zheng wrote:
>
>> Don't load verb in BIOS stage. It is not BIOS's responsibility.
>>
>>
> Who is responsible for that, then?
>
> On i945 I definitely don't get sound on most systems if I don't load
the
> verb in coreboot. I also don't think the Linux drivers do it.
>
>> And we can not have verb for every single codec.
>>
>>
> Have a look at the i82801gx southbridge; I think it was based on the
> sb600 code, but I changed it so I can have a per mainboard verb table.
>
I think we should try to mirror the behaviour of the vendor BIOS. The
Linux kernel source has some interesting info about HD Audio:
http://www.mjmwired.net/kernel/Documentation/sound/alsa/HD-Audio.txt
Regards,
Carl-Daniel
--
"I do consider assignment statements and pointer variables to be among
computer science's most valuable treasures."
-- Donald E. Knuth
--
coreboot mailing list: coreboot at coreboot.org
http://www.coreboot.org/mailman/listinfo/coreboot
-------------- next part --------------
A non-text attachment was scrubbed...
Name: sb600_load_verb_new.patch
Type: application/octet-stream
Size: 4448 bytes
Desc: sb600_load_verb_new.patch
URL: <http://www.coreboot.org/pipermail/coreboot/attachments/20100308/36c77d15/attachment.obj>
More information about the coreboot
mailing list