Sorry for the delay.. Way too much to do and so little time..
Fixed the spotted issues and added 1ms delay to match the BKDG while waiting
for BAR+0xe to set its bits.
Dan Lykowski
Signed-off-by: Dan Lykowski<[email protected]>
________________________________
From: "Li, Maggie" <[email protected]>
To: Carl-Daniel Hailfinger <[email protected]>
Cc: Dan Lykowski <[email protected]>; Marc Jones <[email protected]>;
[email protected]
Sent: Sunday, February 1, 2009 7:47:15 PM
Subject: RE: [coreboot] SB600 HDA can't find codec fix
Carl,
I see. Pci_find_device is more reliable than dev_find_slot. However, we didn't
use the former in our SB600 and RS690 code. There are many places to be
modified if needed.
Best regards
Maggie li
-----Original Message-----
From: Carl-Daniel Hailfinger [mailto:[email protected]]
Sent: Monday, February 02, 2009 10:26 AM
To: Li, Maggie
Cc: Dan Lykowski; Marc Jones; [email protected]
Subject: Re: [coreboot] SB600 HDA can't find codec fix
Hi Maggie,
while your point about pci_find_device is valid, I think that
dev_find_device is the function Dan should choose. It allows us to
address the PCI devices even if their bus locations are shifted which is
possible with some AMD chipsets and may also be true for boards with
multiple chipsets.
In general, we want to use functions which can deal with non-default bus
topologies.
On 02.02.2009 02:48, Li, Maggie wrote:
> Dan,
>
>
>
> I read the RRG spec, just as you said, you should use 0xF in file sb600_hda.c
> to get the current audio codec, that is to say,
>
> dword &= 0xF;
> if (!dword)
> goto no_codec;
>
>
>
> pci_locate_device is really should be used in early setup. Device_t is the
> type of u32 at that time. After this stage, you should use dev_find_slot. In
> file sb600_sata.c, “/* sm_dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0)
> */ “ gives you misunderstanding about how to get the SMBus and it should be
> removed. You can submit a patch about sata and I will ack it. Thanks.
>
I'd prefer to use dev_find_device there as well.
Regards,
Carl-Daniel
--
http://www.hailfinger.org/
Index: src/southbridge/amd/sb600/sb600_hda.c
===================================================================
--- src/southbridge/amd/sb600/sb600_hda.c (revision 3929)
+++ src/southbridge/amd/sb600/sb600_hda.c (working copy)
@@ -35,23 +35,27 @@
u32 dword;
int count;
+ /* Write (val & ~mask) to port */
val &= mask;
dword = readl(port);
dword &= ~mask;
dword |= val;
writel(dword, port);
+ /* Wait for readback of register to
+ * match what was just written to it
+ */
count = 50;
do {
+ /* Wait 1ms based on BKDG wait time */
+ mdelay(1);
dword = readl(port);
dword &= mask;
- udelay(100);
} while ((dword != val) && --count);
+ /* Timeout occured */
if (!count)
return -1;
-
- udelay(540);
return 0;
}
@@ -59,32 +63,31 @@
{
u32 dword;
- /* 1 */
- set_bits(base + 0x08, 1, 1);
+ /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
+ if (set_bits(base + 0x08, 1, 0) == -1)
+ goto no_codec;
- /* 2 */
- dword = readl(base + 0x0e);
- dword |= 7;
- writel(dword, base + 0x0e);
+ /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
+ if (set_bits(base + 0x08, 1, 1) == -1)
+ goto no_codec;
- /* 3 */
- set_bits(base + 0x08, 1, 0);
+ /* Delay for 1 ms since the BKDG does */
+ mdelay(1);
- /* 4 */
- set_bits(base + 0x08, 1, 1);
-
- /* 5 */
+ /* Read in Codec location (BAR + 0xe)[3..0]*/
dword = readl(base + 0xe);
- dword &= 7;
-
- /* 6 */
- if (!dword) {
- set_bits(base + 0x08, 1, 0);
- printk_debug("No codec!\n");
- return 0;
- }
+ dword &= 0x0F;
+ if (!dword)
+ goto no_codec;
+
return dword;
+no_codec:
+ /* Codec Not found */
+ /* Put HDA back in reset (BAR + 0x8) [0] */
+ set_bits(base + 0x08, 1, 0);
+ printk_debug("No codec!\n");
+ return 0;
}
static u32 cim_verb_data[] = {
@@ -262,20 +265,37 @@
static void hda_init(struct device *dev)
{
+ u8 byte;
+ u32 dword;
u8 *base;
struct resource *res;
u32 codec_mask;
+ device_t sm_dev;
+
+ /* Enable azalia - PM_io 0x59[4], disable ac97 - PM_io 0x59[1..0] */
+ pm_iowrite(0x59, 0xB);
+
+ /* Find the SMBus */
+ sm_dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
- /* SM Setting */
+ /* Set routing pin - SMBus ExtFunc (0xf8/0xfc) */
+ pci_write_config32(sm_dev, 0xf8, 0x00);
+ pci_write_config8(sm_dev, 0xfc, 0xAA);
+ /* Set INTA - SMBus 0x63 [2..0] */
+ byte = pci_read_config8(sm_dev, 0x63);
+ byte &= ~0x7;
+ byte |= 0x0; /* INTA:0x0 - INTH:0x7 */
+ pci_write_config8(sm_dev, 0x63, byte);
- /* Set routing pin */
- pci_write_config32(dev, 0xf8, 0x0);
- pci_write_config8(dev, 0xfc, 0xAA);
- /* Set INTA */
- pci_write_config8(dev, 0x63, 0x0);
- /* Enable azalia, disable ac97 */
- pm_iowrite(0x59, 0xB);
+ /* Program the 2C to 0x437b1002 */
+ dword = 0x437b1002;
+ pci_write_config32(dev, 0x2c, dword);
+ /* Read in BAR */
+ /* Is this right? HDA allows for a 64-bit BAR
+ * but this is only setup for a 32-bit one
+ */
res = find_resource(dev, 0x10);
if (!res)
return;
--
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot