printk_foo -> printk(BIOS_FOO, ...)
[coreboot.git] / src / southbridge / amd / sb600 / sb600_hda.c
index b8044fadf138a5c8d8ca44aceae76b553e4c398c..3ba1fe910ec90c6998e1ca700ae56522b3c78841 100644 (file)
 #define   HDA_ICII_BUSY (1 << 0)
 #define   HDA_ICII_VALID  (1 << 1)
 
-static int set_bits(u8 * port, u32 mask, u32 val)
+static int set_bits(u32 port, u32 mask, u32 val)
 {
        u32 dword;
        int count;
 
+       /* Write (val & ~mask) to port */
        val &= mask;
-       dword = readl(port);
+       dword = read32(port);
        dword &= ~mask;
        dword |= val;
-       writel(dword, port);
+       write32(port, dword);
 
+       /* Wait for readback of register to
+        * match what was just written to it
+        */
        count = 50;
        do {
-               dword = readl(port);
+               /* Wait 1ms based on BKDG wait time */
+               mdelay(1);
+               dword = read32(port);
                dword &= mask;
-               udelay(100);
        } while ((dword != val) && --count);
 
+       /* Timeout occured */
        if (!count)
                return -1;
-
-       udelay(540);
        return 0;
 }
 
-static int codec_detect(u8 * base)
+static u32 codec_detect(u32 base)
 {
        u32 dword;
 
-       /* 1 */
-       set_bits(base + 0x08, 1, 1);
-
-       /* 2 */
-       dword = readl(base + 0x0e);
-       dword |= 7;
-       writel(dword, base + 0x0e);
+       /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
+       if (set_bits(base + 0x08, 1, 0) == -1)
+               goto no_codec;
 
-       /* 3 */
-       set_bits(base + 0x08, 1, 0);
+       /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
+       if (set_bits(base + 0x08, 1, 1) == -1)
+               goto no_codec;
 
-       /* 4 */
-       set_bits(base + 0x08, 1, 1);
+       /* Delay for 1 ms since the BKDG does */
+       mdelay(1);
 
-       /* 5 */
-       dword = readl(base + 0xe);
-       dword &= 7;
+       /* Read in Codec location (BAR + 0xe)[3..0]*/
+       dword = read32(base + 0xe);
+       dword &= 0x0F;
+       if (!dword)
+               goto no_codec;
 
-       /* 6 */
-       if (!dword) {
-               set_bits(base + 0x08, 1, 0);
-               printk_debug("No codec!\n");
-               return 0;
-       }
        return dword;
 
+no_codec:
+       /* Codec Not found */
+       /* Put HDA back in reset (BAR + 0x8) [0] */
+       set_bits(base + 0x08, 1, 0);
+       printk(BIOS_DEBUG, "No codec!\n");
+       return 0;
 }
 
 static u32 cim_verb_data[] = {
@@ -148,14 +151,14 @@ static u32 cim_verb_data[] = {
        0x01f71ec4,
        0x01f71f01,
 };
-static unsigned find_verb(u32 viddid, u32 ** verb)
+static u32 find_verb(u32 viddid, u32 ** verb)
 {
        device_t azalia_dev = dev_find_slot(0, PCI_DEVFN(0x14, 2));
        struct southbridge_amd_sb600_config *cfg =
            (struct southbridge_amd_sb600_config *)azalia_dev->chip_info;
-       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);
+       printk(BIOS_DEBUG, "Dev=%s\n", dev_path(azalia_dev));
+       printk(BIOS_DEBUG, "Default viddid=%x\n", cfg->hda_viddid);
+       printk(BIOS_DEBUG, "Reading viddid=%x\n", viddid);
        if (!cfg)
                return 0;
        if (viddid != cfg->hda_viddid)
@@ -169,7 +172,7 @@ static unsigned find_verb(u32 viddid, u32 ** verb)
  *  no response would imply that the codec is non-operative
  */
 
-static int wait_for_ready(u8 *base)
+static int wait_for_ready(u32 base)
 {
        /* Use a 50 usec timeout - the Linux kernel uses the
         * same duration */
@@ -177,7 +180,7 @@ static int wait_for_ready(u8 *base)
        int timeout = 50;
 
        while(timeout--) {
-               u32 dword=readl(base +  HDA_ICII_REG);
+               u32 dword=read32(base +  HDA_ICII_REG);
                if (!(dword & HDA_ICII_BUSY))
                        return 0;
                udelay(1);
@@ -192,14 +195,14 @@ static int wait_for_ready(u8 *base)
  *  is non-operative
  */
 
-static int wait_for_valid(u8 *base)
+static int wait_for_valid(u32 base)
 {
        /* Use a 50 usec timeout - the Linux kernel uses the
         * same duration */
 
        int timeout = 50;
        while(timeout--) {
-               u32 dword = readl(base + HDA_ICII_REG);
+               u32 dword = read32(base + HDA_ICII_REG);
                if ((dword & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
                        HDA_ICII_VALID)
                        return 0;
@@ -209,7 +212,7 @@ static int wait_for_valid(u8 *base)
        return 1;
 }
 
-static void codec_init(u8 * base, int addr)
+static void codec_init(u32 base, int addr)
 {
        u32 dword;
        u32 *verb;
@@ -221,37 +224,37 @@ static void codec_init(u8 * base, int addr)
                return;
 
        dword = (addr << 28) | 0x000f0000;
-       writel(dword, base + 0x60);
+       write32(base + 0x60, dword);
 
        if (wait_for_valid(base) == -1)
                return;
 
-       dword = readl(base + 0x64);
+       dword = read32(base + 0x64);
 
        /* 2 */
-       printk_debug("codec viddid: %08x\n", dword);
+       printk(BIOS_DEBUG, "codec viddid: %08x\n", dword);
        verb_size = find_verb(dword, &verb);
 
        if (!verb_size) {
-               printk_debug("No verb!\n");
+               printk(BIOS_DEBUG, "No verb!\n");
                return;
        }
 
-       printk_debug("verb_size: %d\n", verb_size);
+       printk(BIOS_DEBUG, "verb_size: %d\n", verb_size);
        /* 3 */
        for (i = 0; i < verb_size; i++) {
                if (wait_for_ready(base) == -1)
                        return;
 
-               writel(verb[i], base + 0x60);
+               write32(base + 0x60, verb[i]);
 
                if (wait_for_valid(base) == -1)
                        return;
        }
-       printk_debug("verb loaded!\n");
+       printk(BIOS_DEBUG, "verb loaded!\n");
 }
 
-static void codecs_init(u8 * base, u32 codec_mask)
+static void codecs_init(u32 base, u32 codec_mask)
 {
        int i;
        for (i = 2; i >= 0; i--) {
@@ -262,31 +265,48 @@ static void codecs_init(u8 * base, u32 codec_mask)
 
 static void hda_init(struct device *dev)
 {
-       u8 *base;
+       u8 byte;
+       u32 dword;
+       u32 base;
        struct resource *res;
        u32 codec_mask;
+       device_t sm_dev;
 
-       /* SM Setting */
-       device_t hda_dev;
-       hda_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
-       /* 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 */
+       /* Enable azalia - PM_io 0x59[4], disable ac97 - PM_io 0x59[1..0] */
        pm_iowrite(0x59, 0xB);
 
+       /* Find the SMBus */
+       /* FIXME: Need to find out why the call below crashes. */
+       /*sm_dev = dev_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_ATI_SB600_SM, 0);*/
+       sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
+
+       /* 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);
+
+       /* 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;
 
-       base = (u8 *) ((u32)res->base);
-       printk_debug("base = %08x\n", base);
+       base = ((u32)res->base);
+       printk(BIOS_DEBUG, "base = 0x%x\n", base);
        codec_mask = codec_detect(base);
 
        if (codec_mask) {
-               printk_debug("codec_mask = %02x\n", codec_mask);
+               printk(BIOS_DEBUG, "codec_mask = %02x\n", codec_mask);
                codecs_init(base, codec_mask);
        }
 }
@@ -305,7 +325,7 @@ static struct device_operations hda_audio_ops = {
        .ops_pci = &lops_pci,
 };
 
-static struct pci_driver hdaaudio_driver __pci_driver = {
+static const struct pci_driver hdaaudio_driver __pci_driver = {
        .ops = &hda_audio_ops,
        .vendor = PCI_VENDOR_ID_ATI,
        .device = PCI_DEVICE_ID_ATI_SB600_HDA,