Changeset 3640 for trunk/coreboot-v2

Show
Ignore:
Timestamp:
10/07/08 18:25:10 (3 months ago)
Author:
jcrouse
Message:

[PATCH] coreboot: Don't loop forever waiting for HDA codecs

We shouldn't assume the presence of a working HDA codec, so put in
a reasonable timeout of 50usecs (timeout value borrowed from the kernel).
This makes SimNow? work, since apparently though the codec is
present in Simnow, it is non functional.

Signed-off-by: Jordan Crouse <jordan.crouse@…>
Acked-by: Ronald G. Minnich <rminnich@…>

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/coreboot-v2/src/southbridge/amd/sb600/sb600_hda.c

    r3589 r3640  
    2626#include <delay.h> 
    2727#include "sb600.h" 
     28 
     29#define HDA_ICII_REG 0x68 
     30#define   HDA_ICII_BUSY (1 << 0) 
     31#define   HDA_ICII_VALID  (1 << 1) 
    2832 
    2933static int set_bits(u8 * port, u32 mask, u32 val) 
     
    161165} 
    162166 
     167/** 
     168 *  Wait 50usec for for the codec to indicate it is ready 
     169 *  no response would imply that the codec is non-operative 
     170 */ 
     171 
     172static int wait_for_ready(u8 *base) 
     173{ 
     174        /* Use a 50 usec timeout - the Linux kernel uses the 
     175         * same duration */ 
     176 
     177        int timeout = 50; 
     178 
     179        while(timeout--) { 
     180                u32 dword=readl(base +  HDA_ICII_REG); 
     181                if (!(dword & HDA_ICII_BUSY)) 
     182                        return 0; 
     183                udelay(1); 
     184        } 
     185 
     186        return -1; 
     187} 
     188 
     189/** 
     190 *  Wait 50usec for for the codec to indicate that it accepted 
     191 *  the previous command.  No response would imply that the code 
     192 *  is non-operative 
     193 */ 
     194 
     195static int wait_for_valid(u8 *base) 
     196{ 
     197        /* Use a 50 usec timeout - the Linux kernel uses the 
     198         * same duration */ 
     199 
     200        int timeout = 50; 
     201        while(timeout--) { 
     202                u32 dword = readl(base + HDA_ICII_REG); 
     203                if ((dword & (HDA_ICII_VALID | HDA_ICII_BUSY)) == 
     204                        HDA_ICII_VALID) 
     205                        return 0; 
     206                udelay(1); 
     207        } 
     208 
     209        return 1; 
     210} 
     211 
    163212static void codec_init(u8 * base, int addr) 
    164213{ 
     
    169218 
    170219        /* 1 */ 
    171         do { 
    172                 dword = readl(base + 0x68); 
    173         } while (dword & 1); 
     220        if (wait_for_ready(base) == -1) 
     221                return; 
    174222 
    175223        dword = (addr << 28) | 0x000f0000; 
    176224        writel(dword, base + 0x60); 
    177225 
    178         do { 
    179                 dword = readl(base + 0x68); 
    180         } while ((dword & 3) != 2); 
     226        if (wait_for_valid(base) == -1) 
     227                return; 
    181228 
    182229        dword = readl(base + 0x64); 
     
    194241        /* 3 */ 
    195242        for (i = 0; i < verb_size; i++) { 
    196                 do { 
    197                         dword = readl(base + 0x68); 
    198                 } while (dword & 1); 
     243                if (wait_for_ready(base) == -1) 
     244                        return; 
    199245 
    200246                writel(verb[i], base + 0x60); 
    201247 
    202                 do { 
    203                         dword = readl(base + 0x68); 
    204                 } while ((dword & 3) != 2); 
     248                if (wait_for_valid(base) == -1) 
     249                        return; 
    205250        } 
    206251        printk_debug("verb loaded!\n");