13fffc223Sths /* 23fffc223Sths * QEMU SMBus EEPROM device 33fffc223Sths * 43fffc223Sths * Copyright (c) 2007 Arastra, Inc. 53fffc223Sths * 63fffc223Sths * Permission is hereby granted, free of charge, to any person obtaining a copy 73fffc223Sths * of this software and associated documentation files (the "Software"), to deal 83fffc223Sths * in the Software without restriction, including without limitation the rights 93fffc223Sths * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 103fffc223Sths * copies of the Software, and to permit persons to whom the Software is 113fffc223Sths * furnished to do so, subject to the following conditions: 123fffc223Sths * 133fffc223Sths * The above copyright notice and this permission notice shall be included in 143fffc223Sths * all copies or substantial portions of the Software. 153fffc223Sths * 163fffc223Sths * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 173fffc223Sths * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 183fffc223Sths * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 193fffc223Sths * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 203fffc223Sths * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 213fffc223Sths * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 223fffc223Sths * THE SOFTWARE. 233fffc223Sths */ 243fffc223Sths 250430891cSPeter Maydell #include "qemu/osdep.h" 26b296b664SBALATON Zoltan #include "qemu/units.h" 27b296b664SBALATON Zoltan #include "qapi/error.h" 2883c9f4caSPaolo Bonzini #include "hw/hw.h" 290d09e41aSPaolo Bonzini #include "hw/i2c/i2c.h" 30*93198b6cSCorey Minyard #include "hw/i2c/smbus_slave.h" 31*93198b6cSCorey Minyard #include "hw/i2c/smbus_eeprom.h" 323fffc223Sths 333fffc223Sths //#define DEBUG 343fffc223Sths 353fffc223Sths typedef struct SMBusEEPROMDevice { 361ea96673SPaul Brook SMBusDevice smbusdev; 37bf2782d7SGerd Hoffmann void *data; 383fffc223Sths uint8_t offset; 393fffc223Sths } SMBusEEPROMDevice; 403fffc223Sths 413fffc223Sths static void eeprom_quick_cmd(SMBusDevice *dev, uint8_t read) 423fffc223Sths { 433fffc223Sths #ifdef DEBUG 44ab7d9131Sbalrog printf("eeprom_quick_cmd: addr=0x%02x read=%d\n", dev->i2c.address, read); 453fffc223Sths #endif 463fffc223Sths } 473fffc223Sths 483fffc223Sths static void eeprom_send_byte(SMBusDevice *dev, uint8_t val) 493fffc223Sths { 503fffc223Sths SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev; 513fffc223Sths #ifdef DEBUG 52ab7d9131Sbalrog printf("eeprom_send_byte: addr=0x%02x val=0x%02x\n", 53ab7d9131Sbalrog dev->i2c.address, val); 543fffc223Sths #endif 553fffc223Sths eeprom->offset = val; 563fffc223Sths } 573fffc223Sths 583fffc223Sths static uint8_t eeprom_receive_byte(SMBusDevice *dev) 593fffc223Sths { 603fffc223Sths SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev; 61bf2782d7SGerd Hoffmann uint8_t *data = eeprom->data; 62bf2782d7SGerd Hoffmann uint8_t val = data[eeprom->offset++]; 633fffc223Sths #ifdef DEBUG 64ab7d9131Sbalrog printf("eeprom_receive_byte: addr=0x%02x val=0x%02x\n", 65ab7d9131Sbalrog dev->i2c.address, val); 663fffc223Sths #endif 673fffc223Sths return val; 683fffc223Sths } 693fffc223Sths 700ff596d0Spbrook static void eeprom_write_data(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len) 713fffc223Sths { 723fffc223Sths SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev; 730ff596d0Spbrook int n; 743fffc223Sths #ifdef DEBUG 75ab7d9131Sbalrog printf("eeprom_write_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n", 76ab7d9131Sbalrog dev->i2c.address, cmd, buf[0]); 773fffc223Sths #endif 78b36dc67bSStefan Weil /* A page write operation is not a valid SMBus command. 790ff596d0Spbrook It is a block write without a length byte. Fortunately we 800ff596d0Spbrook get the full block anyway. */ 810ff596d0Spbrook /* TODO: Should this set the current location? */ 820ff596d0Spbrook if (cmd + len > 256) 830ff596d0Spbrook n = 256 - cmd; 840ff596d0Spbrook else 850ff596d0Spbrook n = len; 860ff596d0Spbrook memcpy(eeprom->data + cmd, buf, n); 870ff596d0Spbrook len -= n; 880ff596d0Spbrook if (len) 890ff596d0Spbrook memcpy(eeprom->data, buf + n, len); 903fffc223Sths } 913fffc223Sths 920ff596d0Spbrook static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n) 933fffc223Sths { 943fffc223Sths SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev; 950ff596d0Spbrook /* If this is the first byte then set the current position. */ 960ff596d0Spbrook if (n == 0) 970ff596d0Spbrook eeprom->offset = cmd; 980ff596d0Spbrook /* As with writes, we implement block reads without the 990ff596d0Spbrook SMBus length byte. */ 1000ff596d0Spbrook return eeprom_receive_byte(dev); 1013fffc223Sths } 1023fffc223Sths 10319473e51SPhilippe Mathieu-Daudé static void smbus_eeprom_realize(DeviceState *dev, Error **errp) 1043fffc223Sths { 1051ea96673SPaul Brook SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *)dev; 1060ff596d0Spbrook 1073fffc223Sths eeprom->offset = 0; 1083fffc223Sths } 1091ea96673SPaul Brook 11039bffca2SAnthony Liguori static Property smbus_eeprom_properties[] = { 11139bffca2SAnthony Liguori DEFINE_PROP_PTR("data", SMBusEEPROMDevice, data), 11239bffca2SAnthony Liguori DEFINE_PROP_END_OF_LIST(), 11339bffca2SAnthony Liguori }; 11439bffca2SAnthony Liguori 115b5ea9327SAnthony Liguori static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data) 116b5ea9327SAnthony Liguori { 11739bffca2SAnthony Liguori DeviceClass *dc = DEVICE_CLASS(klass); 118b5ea9327SAnthony Liguori SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass); 119b5ea9327SAnthony Liguori 12019473e51SPhilippe Mathieu-Daudé dc->realize = smbus_eeprom_realize; 121b5ea9327SAnthony Liguori sc->quick_cmd = eeprom_quick_cmd; 122b5ea9327SAnthony Liguori sc->send_byte = eeprom_send_byte; 123b5ea9327SAnthony Liguori sc->receive_byte = eeprom_receive_byte; 124b5ea9327SAnthony Liguori sc->write_data = eeprom_write_data; 125b5ea9327SAnthony Liguori sc->read_data = eeprom_read_data; 12639bffca2SAnthony Liguori dc->props = smbus_eeprom_properties; 1271b111dc1SMarkus Armbruster /* Reason: pointer property "data" */ 128e90f2a8cSEduardo Habkost dc->user_creatable = false; 129b5ea9327SAnthony Liguori } 130b5ea9327SAnthony Liguori 1318c43a6f0SAndreas Färber static const TypeInfo smbus_eeprom_info = { 132b5ea9327SAnthony Liguori .name = "smbus-eeprom", 13339bffca2SAnthony Liguori .parent = TYPE_SMBUS_DEVICE, 13439bffca2SAnthony Liguori .instance_size = sizeof(SMBusEEPROMDevice), 135b5ea9327SAnthony Liguori .class_init = smbus_eeprom_class_initfn, 1361ea96673SPaul Brook }; 1371ea96673SPaul Brook 13883f7d43aSAndreas Färber static void smbus_eeprom_register_types(void) 1391ea96673SPaul Brook { 14039bffca2SAnthony Liguori type_register_static(&smbus_eeprom_info); 1411ea96673SPaul Brook } 1421ea96673SPaul Brook 14383f7d43aSAndreas Färber type_init(smbus_eeprom_register_types) 144a88df0b9SIsaku Yamahata 145e2224214SCédric Le Goater void smbus_eeprom_init_one(I2CBus *smbus, uint8_t address, uint8_t *eeprom_buf) 146e2224214SCédric Le Goater { 147e2224214SCédric Le Goater DeviceState *dev; 148e2224214SCédric Le Goater 149e2224214SCédric Le Goater dev = qdev_create((BusState *) smbus, "smbus-eeprom"); 150e2224214SCédric Le Goater qdev_prop_set_uint8(dev, "address", address); 151e2224214SCédric Le Goater qdev_prop_set_ptr(dev, "data", eeprom_buf); 152e2224214SCédric Le Goater qdev_init_nofail(dev); 153e2224214SCédric Le Goater } 154e2224214SCédric Le Goater 155a5c82852SAndreas Färber void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom, 156a88df0b9SIsaku Yamahata const uint8_t *eeprom_spd, int eeprom_spd_size) 157a88df0b9SIsaku Yamahata { 158a88df0b9SIsaku Yamahata int i; 1597267c094SAnthony Liguori uint8_t *eeprom_buf = g_malloc0(8 * 256); /* XXX: make this persistent */ 160a88df0b9SIsaku Yamahata if (eeprom_spd_size > 0) { 161a88df0b9SIsaku Yamahata memcpy(eeprom_buf, eeprom_spd, eeprom_spd_size); 162a88df0b9SIsaku Yamahata } 163a88df0b9SIsaku Yamahata 164a88df0b9SIsaku Yamahata for (i = 0; i < nb_eeprom; i++) { 165e2224214SCédric Le Goater smbus_eeprom_init_one(smbus, 0x50 + i, eeprom_buf + (i * 256)); 166a88df0b9SIsaku Yamahata } 167a88df0b9SIsaku Yamahata } 168b296b664SBALATON Zoltan 169b296b664SBALATON Zoltan /* Generate SDRAM SPD EEPROM data describing a module of type and size */ 170b296b664SBALATON Zoltan uint8_t *spd_data_generate(enum sdram_type type, ram_addr_t ram_size, 171b296b664SBALATON Zoltan Error **errp) 172b296b664SBALATON Zoltan { 173b296b664SBALATON Zoltan uint8_t *spd; 174b296b664SBALATON Zoltan uint8_t nbanks; 175b296b664SBALATON Zoltan uint16_t density; 176b296b664SBALATON Zoltan uint32_t size; 177b296b664SBALATON Zoltan int min_log2, max_log2, sz_log2; 178b296b664SBALATON Zoltan int i; 179b296b664SBALATON Zoltan 180b296b664SBALATON Zoltan switch (type) { 181b296b664SBALATON Zoltan case SDR: 182b296b664SBALATON Zoltan min_log2 = 2; 183b296b664SBALATON Zoltan max_log2 = 9; 184b296b664SBALATON Zoltan break; 185b296b664SBALATON Zoltan case DDR: 186b296b664SBALATON Zoltan min_log2 = 5; 187b296b664SBALATON Zoltan max_log2 = 12; 188b296b664SBALATON Zoltan break; 189b296b664SBALATON Zoltan case DDR2: 190b296b664SBALATON Zoltan min_log2 = 7; 191b296b664SBALATON Zoltan max_log2 = 14; 192b296b664SBALATON Zoltan break; 193b296b664SBALATON Zoltan default: 194b296b664SBALATON Zoltan g_assert_not_reached(); 195b296b664SBALATON Zoltan } 196b296b664SBALATON Zoltan size = ram_size >> 20; /* work in terms of megabytes */ 197b296b664SBALATON Zoltan if (size < 4) { 198b296b664SBALATON Zoltan error_setg(errp, "SDRAM size is too small"); 199b296b664SBALATON Zoltan return NULL; 200b296b664SBALATON Zoltan } 201b296b664SBALATON Zoltan sz_log2 = 31 - clz32(size); 202b296b664SBALATON Zoltan size = 1U << sz_log2; 203b296b664SBALATON Zoltan if (ram_size > size * MiB) { 204b296b664SBALATON Zoltan error_setg(errp, "SDRAM size 0x"RAM_ADDR_FMT" is not a power of 2, " 205b296b664SBALATON Zoltan "truncating to %u MB", ram_size, size); 206b296b664SBALATON Zoltan } 207b296b664SBALATON Zoltan if (sz_log2 < min_log2) { 208b296b664SBALATON Zoltan error_setg(errp, 209b296b664SBALATON Zoltan "Memory size is too small for SDRAM type, adjusting type"); 210b296b664SBALATON Zoltan if (size >= 32) { 211b296b664SBALATON Zoltan type = DDR; 212b296b664SBALATON Zoltan min_log2 = 5; 213b296b664SBALATON Zoltan max_log2 = 12; 214b296b664SBALATON Zoltan } else { 215b296b664SBALATON Zoltan type = SDR; 216b296b664SBALATON Zoltan min_log2 = 2; 217b296b664SBALATON Zoltan max_log2 = 9; 218b296b664SBALATON Zoltan } 219b296b664SBALATON Zoltan } 220b296b664SBALATON Zoltan 221b296b664SBALATON Zoltan nbanks = 1; 222b296b664SBALATON Zoltan while (sz_log2 > max_log2 && nbanks < 8) { 223b296b664SBALATON Zoltan sz_log2--; 224b296b664SBALATON Zoltan nbanks++; 225b296b664SBALATON Zoltan } 226b296b664SBALATON Zoltan 227b296b664SBALATON Zoltan if (size > (1ULL << sz_log2) * nbanks) { 228b296b664SBALATON Zoltan error_setg(errp, "Memory size is too big for SDRAM, truncating"); 229b296b664SBALATON Zoltan } 230b296b664SBALATON Zoltan 231b296b664SBALATON Zoltan /* split to 2 banks if possible to avoid a bug in MIPS Malta firmware */ 232b296b664SBALATON Zoltan if (nbanks == 1 && sz_log2 > min_log2) { 233b296b664SBALATON Zoltan sz_log2--; 234b296b664SBALATON Zoltan nbanks++; 235b296b664SBALATON Zoltan } 236b296b664SBALATON Zoltan 237b296b664SBALATON Zoltan density = 1ULL << (sz_log2 - 2); 238b296b664SBALATON Zoltan switch (type) { 239b296b664SBALATON Zoltan case DDR2: 240b296b664SBALATON Zoltan density = (density & 0xe0) | (density >> 8 & 0x1f); 241b296b664SBALATON Zoltan break; 242b296b664SBALATON Zoltan case DDR: 243b296b664SBALATON Zoltan density = (density & 0xf8) | (density >> 8 & 0x07); 244b296b664SBALATON Zoltan break; 245b296b664SBALATON Zoltan case SDR: 246b296b664SBALATON Zoltan default: 247b296b664SBALATON Zoltan density &= 0xff; 248b296b664SBALATON Zoltan break; 249b296b664SBALATON Zoltan } 250b296b664SBALATON Zoltan 251b296b664SBALATON Zoltan spd = g_malloc0(256); 252b296b664SBALATON Zoltan spd[0] = 128; /* data bytes in EEPROM */ 253b296b664SBALATON Zoltan spd[1] = 8; /* log2 size of EEPROM */ 254b296b664SBALATON Zoltan spd[2] = type; 255b296b664SBALATON Zoltan spd[3] = 13; /* row address bits */ 256b296b664SBALATON Zoltan spd[4] = 10; /* column address bits */ 257b296b664SBALATON Zoltan spd[5] = (type == DDR2 ? nbanks - 1 : nbanks); 258b296b664SBALATON Zoltan spd[6] = 64; /* module data width */ 259b296b664SBALATON Zoltan /* reserved / data width high */ 260b296b664SBALATON Zoltan spd[8] = 4; /* interface voltage level */ 261b296b664SBALATON Zoltan spd[9] = 0x25; /* highest CAS latency */ 262b296b664SBALATON Zoltan spd[10] = 1; /* access time */ 263b296b664SBALATON Zoltan /* DIMM configuration 0 = non-ECC */ 264b296b664SBALATON Zoltan spd[12] = 0x82; /* refresh requirements */ 265b296b664SBALATON Zoltan spd[13] = 8; /* primary SDRAM width */ 266b296b664SBALATON Zoltan /* ECC SDRAM width */ 267b296b664SBALATON Zoltan spd[15] = (type == DDR2 ? 0 : 1); /* reserved / delay for random col rd */ 268b296b664SBALATON Zoltan spd[16] = 12; /* burst lengths supported */ 269b296b664SBALATON Zoltan spd[17] = 4; /* banks per SDRAM device */ 270b296b664SBALATON Zoltan spd[18] = 12; /* ~CAS latencies supported */ 271b296b664SBALATON Zoltan spd[19] = (type == DDR2 ? 0 : 1); /* reserved / ~CS latencies supported */ 272b296b664SBALATON Zoltan spd[20] = 2; /* DIMM type / ~WE latencies */ 273b296b664SBALATON Zoltan /* module features */ 274b296b664SBALATON Zoltan /* memory chip features */ 275b296b664SBALATON Zoltan spd[23] = 0x12; /* clock cycle time @ medium CAS latency */ 276b296b664SBALATON Zoltan /* data access time */ 277b296b664SBALATON Zoltan /* clock cycle time @ short CAS latency */ 278b296b664SBALATON Zoltan /* data access time */ 279b296b664SBALATON Zoltan spd[27] = 20; /* min. row precharge time */ 280b296b664SBALATON Zoltan spd[28] = 15; /* min. row active row delay */ 281b296b664SBALATON Zoltan spd[29] = 20; /* min. ~RAS to ~CAS delay */ 282b296b664SBALATON Zoltan spd[30] = 45; /* min. active to precharge time */ 283b296b664SBALATON Zoltan spd[31] = density; 284b296b664SBALATON Zoltan spd[32] = 20; /* addr/cmd setup time */ 285b296b664SBALATON Zoltan spd[33] = 8; /* addr/cmd hold time */ 286b296b664SBALATON Zoltan spd[34] = 20; /* data input setup time */ 287b296b664SBALATON Zoltan spd[35] = 8; /* data input hold time */ 288b296b664SBALATON Zoltan 289b296b664SBALATON Zoltan /* checksum */ 290b296b664SBALATON Zoltan for (i = 0; i < 63; i++) { 291b296b664SBALATON Zoltan spd[63] += spd[i]; 292b296b664SBALATON Zoltan } 293b296b664SBALATON Zoltan return spd; 294b296b664SBALATON Zoltan } 295