static inline void dump_smbus_registers(void) { u32 device; print_debug("\n"); for (device = 1; device < 0x80; device++) { int j; if (smbus_read_byte(device, 0) < 0) continue; printk(BIOS_DEBUG, "smbus: %02x", device); for (j = 0; j < 256; j++) { int status; unsigned char byte; status = smbus_read_byte(device, j); if (status < 0) { break; } if ((j & 0xf) == 0) { printk(BIOS_DEBUG, "\n%02x: ", j); } byte = status & 0xff; printk(BIOS_DEBUG, "%02x ", byte); } print_debug("\n"); } }
void dump_spd_registers(void) { unsigned device; device = SMBUS_MEM_DEVICE_START; printk(BIOS_DEBUG, "\n"); while(device <= SMBUS_MEM_DEVICE_END) { int status = 0; int i; printk(BIOS_DEBUG, "dimm %02x", device); for(i = 0; (i < 256) && (status == 0); i++) { unsigned char byte; if ((i % 20) == 0) { printk(BIOS_DEBUG, "\n%3d: ", i); } status = smbus_read_byte(device, i, &byte); if (status != 0) { printk(BIOS_DEBUG, "bad device\n"); continue; } printk(BIOS_DEBUG, "%02x ", byte); } device += SMBUS_MEM_DEVICE_INC; printk(BIOS_DEBUG, "\n"); } }
static void at24rf08c_read_string(u8 bank, u8 start, u8 len, char *result) { int i; device_t dev; dev = dev_find_slot_on_smbus(1, 0x54 | bank); if (dev == 0) { printk(BIOS_WARNING, "EEPROM not found\n"); memcpy(result, "*INVALID*", sizeof ("*INVALID*")); return; } for (i = 0; i < len; i++) { int t; int j; /* After a register write AT24RF08C (which we issued in init function) sometimes stops responding. Retry several times in case of failure. */ for (j = 0; j < 100; j++) { t = smbus_read_byte(dev, start + i); if (t >= 0) break; } if (t < 0x20 || t > 0x7f) { memcpy(result, "*INVALID*", sizeof ("*INVALID*")); return; } result[i] = t; } }
static inline int spd_read_byte(unsigned int device, unsigned int address) { if (device != DIMM0) return 0xFF; /* No DIMM1, don't even try. */ return smbus_read_byte(device, address); }
void dump_spd_registers(void) { int i; printk(BIOS_DEBUG, "\n"); for (i = 0; i < DIMM_SOCKETS; i++) { unsigned device; device = DIMM0 + i; if (device) { int j; printk(BIOS_DEBUG, "DIMM %d: %02x", i, device); for (j = 0; j < 256; j++) { int status; unsigned char byte; if ((j & 0xf) == 0) { printk(BIOS_DEBUG, "\n%02x: ", j); } status = smbus_read_byte(device, j); if (status < 0) { printk(BIOS_DEBUG, "bad device\n"); break; } byte = status & 0xff; printk(BIOS_DEBUG, "%02x ", byte); } printk(BIOS_DEBUG, "\n"); } } }
int spd_read_byte(unsigned int device, unsigned int address) { /* Only DIMM0 is available. */ if (device != DIMM0) return 0xFF; return smbus_read_byte(device, address); }
static void adm1027_enable_monitoring(device_t dev) { int result; result = smbus_read_byte(dev, ADM1027_REG_CONFIG1); if (!(result & CFG1_RDY)) { printk(BIOS_DEBUG, "ADM1027: monitoring not ready\n"); return; } result = (result | CFG1_STRT); result = smbus_write_byte(dev, ADM1027_REG_CONFIG1, result); result = smbus_read_byte(dev, ADM1027_REG_CONFIG1); if (!(result & CFG1_STRT)) { printk(BIOS_DEBUG, "ADM1027: monitoring would not enable\n"); } printk(BIOS_DEBUG, "ADM1027: monitoring enabled\n"); }
static void lm63_init(struct device *dev) { int result; if (dev->enabled && dev->path.type == DEVICE_PATH_I2C) { if (ops_smbus_bus(get_pbus_smbus(dev))) { if (dev->bus->dev->path.type == DEVICE_PATH_I2C) smbus_set_link(dev); // it is under mux result = smbus_read_byte(dev, 0x03); // result &= ~0x04; result |= 0x04; smbus_write_byte(dev, 0x03, result & 0xff); // config lm63 } } }
void smbios_mainboard_set_uuid(u8 *uuid) { static char result[16]; unsigned i; static int already_read; device_t dev; const int remap[16] = { /* UUID byteswap. */ 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 }; if (already_read) { memcpy (uuid, result, 16); return; } memset (result, 0, sizeof (result)); dev = dev_find_slot_on_smbus(1, 0x56); if (dev == 0) { printk(BIOS_WARNING, "eeprom not found\n"); already_read = 1; memset (uuid, 0, 16); return; } for (i = 0; i < 16; i++) { int t; int j; /* After a register write AT24RF08C (which we issued in init function) sometimes stops responding. Retry several times in case of failure. */ for (j = 0; j < 100; j++) { t = smbus_read_byte(dev, 0x12 + i); if (t >= 0) break; } if (t < 0) { memset (result, 0, sizeof (result)); break; } result[remap[i]] = t; } already_read = 1; memcpy (uuid, result, 16); }
static void spd_enable_refresh(void) { /* * Effects: Uses serial presence detect to set the * refresh rate in the DRAMC register. * see spd_set_dramc for the other values. * FIXME: Check for illegal/unsupported ram configurations and abort */ #if HAVE_STATIC_ARRAY_SUPPORT static const unsigned char refresh_rates[] = { 0x01, /* Normal 15.625 us -> 15.6 us */ 0x05, /* Reduced(.25X) 3.9 us -> 7.8 us */ 0x05, /* Reduced(.5X) 7.8 us -> 7.8 us */ 0x02, /* Extended(2x) 31.3 us -> 31.2 us */ 0x03, /* Extended(4x) 62.5 us -> 62.4 us */ 0x04, /* Extended(8x) 125 us -> 124.8 us */ }; #endif /* Find the first dimm and assume the rest are the same */ int status; int byte; unsigned device; unsigned refresh_rate; byte = -1; status = -1; device = SMBUS_MEM_DEVICE_START; while ((byte < 0) && (device <= SMBUS_MEM_DEVICE_END)) { byte = smbus_read_byte(device, 12); device += SMBUS_MEM_DEVICE_INC; } if (byte < 0) { /* We couldn't find anything we must have no memory */ sdram_no_memory(); } byte &= 0x7f; /* Default refresh rate be conservative */ refresh_rate = 5; /* see if the ram refresh is a supported one */ if (byte < 6) { #if HAVE_STATIC_ARRAY_SUPPORT refresh_rate = refresh_rates[byte]; #endif } byte = pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57); byte &= 0xf8; byte |= refresh_rate; pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57, byte); }
/** * The onboard 64MB PC133 memory does not have a SPD EEPROM so the * values have to be set manually, the SO-DIMM socket is located in * socket0 (0x50/DIMM0), and the onboard memory is located in socket1 * (0x51/DIMM1). */ static inline int spd_read_byte(unsigned device, unsigned address) { int i; if (device == DIMM0) { return smbus_read_byte(device, address); } else if (device == DIMM1) { for (i = 0; i < ARRAY_SIZE(spd_table); i++) { if (spd_table[i].address == address) return spd_table[i].data; } return 0xFF; /* Return 0xFF when address is not found. */ } else { return 0xFF; /* Return 0xFF on any failures. */ } }
static void init(struct device *dev) { unsigned int i; u32 chksum = 0; char block[20]; msr_t reset; device_t eeprom_dev = dev_find_slot_on_smbus(1, 0x52); if (eeprom_dev == 0) { printk(BIOS_WARNING, "eeprom not found\n"); return; } /* turn off all leds except led_ini */ outb(0x02, 0x5a); /* bit0 - led_run */ /* bit1 - led_ini */ /* bit2 - led_err */ /* bit3-bit7 - write has no effect */ outb(0x00, 0x49); /* bit0-bit6 - led_7-led_1 */ /* bit7 - write has no effect */ /* read the whole block and check if checksum is okay */ for (i = 0; i < 20; i++) { block[i] = smbus_read_byte(eeprom_dev, i); chksum += block[i]; } if (chksum != 0) { printk(BIOS_WARNING, "wrong checksum: 0x%0x\n", chksum); } hw_rev = block[5]; printk(BIOS_DEBUG, "hw revision: %u\n", hw_rev); /* Reset MFGPT7 (standby power domain) - this is done via * an undocumented register */ reset = rdmsr(0x5140002b); reset.lo |= 1 << 7; wrmsr(0x5140002b, reset); }
static void dump_spd_registers(void) { #if CONFIG_DEBUG_RAM_SETUP int i; print_debug("\n"); for(i = 0; i < DIMM_SOCKETS; i++) { unsigned device; device = DIMM_SPD_BASE + i; if (device) { int j; print_debug("dimm: "); print_debug_hex8(i); print_debug(".0: "); print_debug_hex8(device); for(j = 0; j < 256; j++) { int status; unsigned char byte; if ((j & 0xf) == 0) { print_debug("\n"); print_debug_hex8(j); print_debug(": "); } status = smbus_read_byte(device, j); if (status < 0) { print_debug("bad device\n"); break; } byte = status & 0xff; print_debug_hex8(byte); print_debug_char(' '); } print_debug("\n"); } } #endif }
uint8_t pcal9538a_get_output_type(PCAL9538A *pcal, uint8_t *result){ return smbus_read_byte(pcal->config.i2c, pcal->config.address, PCAL9538A_RA_OUT_TYPE, result); }
uint8_t pcal9538a_read_outputs(PCAL9538A *pcal, uint8_t *result){ return smbus_read_byte(pcal->config.i2c, pcal->config.address, PCAL9538A_RA_OUTPUT, result); }
uint8_t pcal9538a_get_input_inversion(PCAL9538A *pcal, uint8_t *result){ return smbus_read_byte(pcal->config.i2c, pcal->config.address, PCAL9538A_RA_INVERSION, result); }
static int spd_read_byte(u32 device, u32 address) { int result; result = smbus_read_byte(device, address); return result; }
int spd_read_byte(unsigned int device, unsigned int address) { return smbus_read_byte(device, address); }
static void nic_init(struct device *dev) { u32 dword, old, mac_h = 0, mac_l = 0; int eeprom_valid = 0; struct southbridge_nvidia_ck804_config *conf; static u32 nic_index = 0; u8 *base; struct resource *res; res = find_resource(dev, 0x10); base = res2mmio(res, 0, 0); #define NvRegPhyInterface 0xC0 #define PHY_RGMII 0x10000000 write32(base + NvRegPhyInterface, PHY_RGMII); old = dword = pci_read_config32(dev, 0x30); dword &= ~(0xf); dword |= 0xf; if (old != dword) pci_write_config32(dev, 0x30, dword); conf = dev->chip_info; if (conf->mac_eeprom_smbus != 0) { /* Read MAC address from EEPROM at first. */ struct device *dev_eeprom; dev_eeprom = dev_find_slot_on_smbus(conf->mac_eeprom_smbus, conf->mac_eeprom_addr); if (dev_eeprom) { /* If that is valid we will use that. */ unsigned char dat[6]; int i, status; for (i = 0; i < 6; i++) { status = smbus_read_byte(dev_eeprom, i); if (status < 0) break; dat[i] = status & 0xff; } if (status >= 0) { mac_l = 0; for (i = 3; i >= 0; i--) { mac_l <<= 8; mac_l += dat[i]; } if (mac_l != 0xffffffff) { mac_l += nic_index; mac_h = 0; for (i = 5; i >= 4; i--) { mac_h <<= 8; mac_h += dat[i]; } eeprom_valid = 1; } } } } /* If that is invalid we will read that from romstrap. */ if (!eeprom_valid) { u32 *mac_pos; mac_pos = (u32 *)0xffffffd0; /* See romstrap.inc and romstrap.ld. */ mac_l = read32(mac_pos) + nic_index; mac_h = read32(mac_pos + 1); } #if 1 /* Set that into NIC MMIO. */ #define NvRegMacAddrA 0xA8 #define NvRegMacAddrB 0xAC write32(base + NvRegMacAddrA, mac_l); write32(base + NvRegMacAddrB, mac_h); #else /* Set that into NIC. */ pci_write_config32(dev, 0xa8, mac_l); pci_write_config32(dev, 0xac, mac_h); #endif nic_index++; }
uint8_t pcal9538a_get_pull_up_down(PCAL9538A *pcal, uint8_t *result){ return smbus_read_byte(pcal->config.i2c, pcal->config.address, PCAL9538A_RA_PUD_DIR, result); }
uint8_t pcal9538a_get_pull_enabled(PCAL9538A *pcal, uint8_t *result){ return smbus_read_byte(pcal->config.i2c, pcal->config.address, PCAL9538A_RA_PUD_ENABLE, result); }
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) { static const uint16_t spd_addr[] = { // Node 0 DIMM0, DIMM1, DIMM2, 0, 0, 0, 0, 0, // Node 1 0, 0, 0, 0, 0, 0, 0, 0, }; unsigned bsp_apicid = 0; int needs_reset = 0; struct sys_info *sysinfo = &sysinfo_car; winbond_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); console_init(); enable_rom_decode(); print_info("now booting... fallback\n"); /* Is this a CPU only reset? Or is this a secondary CPU? */ if (!cpu_init_detectedx && boot_cpu()) { /* Nothing special needs to be done to find bus 0. */ /* Allow the HT devices to be found. */ enumerate_ht_chain(); } print_info("now booting... real_main\n"); if (bist == 0) bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo); /* Halt if there was a built in self test failure. */ report_bist_failure(bist); setup_default_resource_map(); setup_coherent_ht_domain(); wait_all_core0_started(); print_info("now booting... Core0 started\n"); #if CONFIG_LOGICAL_CPUS /* It is said that we should start core1 after all core0 launched. */ start_other_cores(); wait_all_other_cores_started(bsp_apicid); #endif init_timer(); ht_setup_chains_x(sysinfo); /* Init sblnk and sbbusn, nodes, sbdn. */ needs_reset = optimize_link_coherent_ht(); needs_reset |= optimize_link_incoherent_ht(sysinfo); needs_reset |= k8t890_early_setup_ht(); if (needs_reset) { print_debug("ht reset -\n"); soft_reset(); } /* the HT settings needs to be OK, because link freq change may cause HT disconnect */ vt8237_sb_enable_fid_vid(); enable_fid_change(); init_fidvid_bsp(bsp_apicid); /* Stop the APs so we can start them later in init. */ allow_all_aps_stop(bsp_apicid); /* It's the time to set ctrl now. */ fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr); enable_smbus(); /* this seems to be some GPIO on the SMBus--in any case, setting these * two bits reduces the pullup impedance of the bus lines and is required * in order to be able to read SPD info */ smbus_write_byte(0x48, 0x07, smbus_read_byte(0x48, 0x07) | 0x80); smbus_write_byte(0x4a, 0x07, smbus_read_byte(0x4a, 0x07) | 0x10); unsigned char mask; mask = 0; // mask |= 1 /* AGP voltage 1.7 V (not verified, just vendor BIOS value) */ // mask |= 2 /* V-Link voltage 2.6 V (not verified either) */ smbus_write_byte(0x4a, 0x00, (smbus_read_byte(0x4a, 0x00) & ~0x0f) | (0x0f ^ (mask << 2))); smbus_write_byte(0x4a, 0x01, (smbus_read_byte(0x4a, 0x01) & ~0x03) | (0x03 ^ mask)); mask = 25; /* RAM voltage in decivolts, valid range from 25 to 28 */ mask = 3 - (mask - 25); smbus_write_byte(0x4a, 0x02, 0x4f | (mask << 4)); smbus_write_byte(0x4a, 0x03, 0x04 | mask); sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo); post_cache_as_ram(); }
static void nic_init(struct device *dev) { u8 *base; u32 mac_h = 0, mac_l = 0; int eeprom_valid = 0; struct southbridge_nvidia_mcp55_config *conf; static u32 nic_index = 0; struct resource *res; res = find_resource(dev, 0x10); if (!res) return; base = res2mmio(res, 0, 0); phy_detect(base); #define NvRegPhyInterface 0xC0 #define PHY_RGMII 0x10000000 write32(base + NvRegPhyInterface, PHY_RGMII); conf = dev->chip_info; if (conf->mac_eeprom_smbus != 0) { // read MAC address from EEPROM at first struct device *dev_eeprom; dev_eeprom = dev_find_slot_on_smbus(conf->mac_eeprom_smbus, conf->mac_eeprom_addr); if(dev_eeprom) { // if that is valid we will use that unsigned char dat[6]; int status; int i; for(i=0;i<6;i++) { status = smbus_read_byte(dev_eeprom, i); if(status < 0) break; dat[i] = status & 0xff; } if(status >= 0) { mac_l = 0; for(i=3;i>=0;i--) { mac_l <<= 8; mac_l += dat[i]; } if(mac_l != 0xffffffff) { mac_l += nic_index; mac_h = 0; for(i=5;i>=4;i--) { mac_h <<= 8; mac_h += dat[i]; } eeprom_valid = 1; } } } } // if that is invalid we will read that from romstrap if(!eeprom_valid) { u32 *mac_pos; mac_pos = (u32 *)0xffffffd0; // refer to romstrap.inc and romstrap.ld mac_l = read32(mac_pos) + nic_index; // overflow? mac_h = read32(mac_pos + 1); } #if 1 // set that into NIC MMIO #define NvRegMacAddrA 0xA8 #define NvRegMacAddrB 0xAC write32(base + NvRegMacAddrA, mac_l); write32(base + NvRegMacAddrB, mac_h); #else // set that into NIC pci_write_config32(dev, 0xa8, mac_l); pci_write_config32(dev, 0xac, mac_h); #endif nic_index++; }
uint8_t pcal9538a_get_interrupt_mask(PCAL9538A *pcal, uint8_t *result){ return smbus_read_byte(pcal->config.i2c, pcal->config.address, PCAL9538A_RA_INT_MASK, result); }
static int spd_read_byte(u16 device, u16 address) { return smbus_read_byte(device, address); }
uint8_t pcal9538a_get_input_latch(PCAL9538A *pcal, uint8_t *result){ return smbus_read_byte(pcal->config.i2c, pcal->config.address, PCAL9538A_RA_LATCH, result); }
static inline int spd_read_byte(u32 device, u32 address) { return smbus_read_byte(device, address); }
uint8_t pcal9538a_get_output_dir(PCAL9538A *pcal, uint8_t *result){ return smbus_read_byte(pcal->config.i2c, pcal->config.address, PCAL9538A_RA_CONFIG, result); }
static inline int spd_read_byte(unsigned device, unsigned address) { return smbus_read_byte(device, address); }
static int w83795_set_bank(struct device *dev, uint8_t bank) { return smbus_write_byte(dev, W83795_REG_BANKSEL, bank); } static uint8_t w83795_read(struct device *dev, uint16_t reg) { int ret; ret = w83795_set_bank(dev, reg >> 8); if (ret < 0) { printk(BIOS_DEBUG, "read failed to set bank %x\n", reg >> 8); return -1; } ret = smbus_read_byte(dev, reg & 0xff); return ret; } static uint8_t w83795_write(struct device *dev, uint16_t reg, uint8_t value) { int err; err = w83795_set_bank(dev, reg >> 8); if (err < 0) { printk(BIOS_DEBUG, "write failed to set bank %x\n", reg >> 8); return -1; } err = smbus_write_byte(dev, reg & 0xff, value); return err;