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" 3093198b6cSCorey Minyard #include "hw/i2c/smbus_slave.h" 3193198b6cSCorey Minyard #include "hw/i2c/smbus_eeprom.h" 323fffc223Sths 333fffc223Sths //#define DEBUG 343fffc223Sths 35b398a924SCorey Minyard #define TYPE_SMBUS_EEPROM "smbus-eeprom" 36b398a924SCorey Minyard 37b398a924SCorey Minyard #define SMBUS_EEPROM(obj) \ 38b398a924SCorey Minyard OBJECT_CHECK(SMBusEEPROMDevice, (obj), TYPE_SMBUS_EEPROM) 39b398a924SCorey Minyard 40*0cf487e5SCorey Minyard #define SMBUS_EEPROM_SIZE 256 41*0cf487e5SCorey Minyard 423fffc223Sths typedef struct SMBusEEPROMDevice { 431ea96673SPaul Brook SMBusDevice smbusdev; 44bf2782d7SGerd Hoffmann void *data; 453fffc223Sths uint8_t offset; 463fffc223Sths } SMBusEEPROMDevice; 473fffc223Sths 483fffc223Sths static uint8_t eeprom_receive_byte(SMBusDevice *dev) 493fffc223Sths { 50b398a924SCorey Minyard SMBusEEPROMDevice *eeprom = SMBUS_EEPROM(dev); 51bf2782d7SGerd Hoffmann uint8_t *data = eeprom->data; 52bf2782d7SGerd Hoffmann uint8_t val = data[eeprom->offset++]; 538b38e532SCorey Minyard 543fffc223Sths #ifdef DEBUG 55ab7d9131Sbalrog printf("eeprom_receive_byte: addr=0x%02x val=0x%02x\n", 56ab7d9131Sbalrog dev->i2c.address, val); 573fffc223Sths #endif 583fffc223Sths return val; 593fffc223Sths } 603fffc223Sths 619cf27d74SCorey Minyard static int eeprom_write_data(SMBusDevice *dev, uint8_t *buf, uint8_t len) 623fffc223Sths { 63b398a924SCorey Minyard SMBusEEPROMDevice *eeprom = SMBUS_EEPROM(dev); 649cf27d74SCorey Minyard uint8_t *data = eeprom->data; 659cf27d74SCorey Minyard 663fffc223Sths #ifdef DEBUG 67ab7d9131Sbalrog printf("eeprom_write_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n", 689cf27d74SCorey Minyard dev->i2c.address, buf[0], buf[1]); 693fffc223Sths #endif 709cf27d74SCorey Minyard /* len is guaranteed to be > 0 */ 719cf27d74SCorey Minyard eeprom->offset = buf[0]; 729cf27d74SCorey Minyard buf++; 739cf27d74SCorey Minyard len--; 749cf27d74SCorey Minyard 759cf27d74SCorey Minyard for (; len > 0; len--) { 769cf27d74SCorey Minyard data[eeprom->offset] = *buf++; 77*0cf487e5SCorey Minyard eeprom->offset = (eeprom->offset + 1) % SMBUS_EEPROM_SIZE; 783fffc223Sths } 793fffc223Sths 809cf27d74SCorey Minyard return 0; 819cf27d74SCorey Minyard } 829cf27d74SCorey Minyard 8319473e51SPhilippe Mathieu-Daudé static void smbus_eeprom_realize(DeviceState *dev, Error **errp) 843fffc223Sths { 85b398a924SCorey Minyard SMBusEEPROMDevice *eeprom = SMBUS_EEPROM(dev); 860ff596d0Spbrook 873fffc223Sths eeprom->offset = 0; 883fffc223Sths } 891ea96673SPaul Brook 9039bffca2SAnthony Liguori static Property smbus_eeprom_properties[] = { 9139bffca2SAnthony Liguori DEFINE_PROP_PTR("data", SMBusEEPROMDevice, data), 9239bffca2SAnthony Liguori DEFINE_PROP_END_OF_LIST(), 9339bffca2SAnthony Liguori }; 9439bffca2SAnthony Liguori 95b5ea9327SAnthony Liguori static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data) 96b5ea9327SAnthony Liguori { 9739bffca2SAnthony Liguori DeviceClass *dc = DEVICE_CLASS(klass); 98b5ea9327SAnthony Liguori SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass); 99b5ea9327SAnthony Liguori 10019473e51SPhilippe Mathieu-Daudé dc->realize = smbus_eeprom_realize; 101b5ea9327SAnthony Liguori sc->receive_byte = eeprom_receive_byte; 102b5ea9327SAnthony Liguori sc->write_data = eeprom_write_data; 10339bffca2SAnthony Liguori dc->props = smbus_eeprom_properties; 1041b111dc1SMarkus Armbruster /* Reason: pointer property "data" */ 105e90f2a8cSEduardo Habkost dc->user_creatable = false; 106b5ea9327SAnthony Liguori } 107b5ea9327SAnthony Liguori 1088c43a6f0SAndreas Färber static const TypeInfo smbus_eeprom_info = { 109b398a924SCorey Minyard .name = TYPE_SMBUS_EEPROM, 11039bffca2SAnthony Liguori .parent = TYPE_SMBUS_DEVICE, 11139bffca2SAnthony Liguori .instance_size = sizeof(SMBusEEPROMDevice), 112b5ea9327SAnthony Liguori .class_init = smbus_eeprom_class_initfn, 1131ea96673SPaul Brook }; 1141ea96673SPaul Brook 11583f7d43aSAndreas Färber static void smbus_eeprom_register_types(void) 1161ea96673SPaul Brook { 11739bffca2SAnthony Liguori type_register_static(&smbus_eeprom_info); 1181ea96673SPaul Brook } 1191ea96673SPaul Brook 12083f7d43aSAndreas Färber type_init(smbus_eeprom_register_types) 121a88df0b9SIsaku Yamahata 122e2224214SCédric Le Goater void smbus_eeprom_init_one(I2CBus *smbus, uint8_t address, uint8_t *eeprom_buf) 123e2224214SCédric Le Goater { 124e2224214SCédric Le Goater DeviceState *dev; 125e2224214SCédric Le Goater 126b398a924SCorey Minyard dev = qdev_create((BusState *) smbus, TYPE_SMBUS_EEPROM); 127e2224214SCédric Le Goater qdev_prop_set_uint8(dev, "address", address); 128e2224214SCédric Le Goater qdev_prop_set_ptr(dev, "data", eeprom_buf); 129e2224214SCédric Le Goater qdev_init_nofail(dev); 130e2224214SCédric Le Goater } 131e2224214SCédric Le Goater 132a5c82852SAndreas Färber void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom, 133a88df0b9SIsaku Yamahata const uint8_t *eeprom_spd, int eeprom_spd_size) 134a88df0b9SIsaku Yamahata { 135a88df0b9SIsaku Yamahata int i; 136*0cf487e5SCorey Minyard /* XXX: make this persistent */ 137*0cf487e5SCorey Minyard uint8_t *eeprom_buf = g_malloc0(8 * SMBUS_EEPROM_SIZE); 138a88df0b9SIsaku Yamahata if (eeprom_spd_size > 0) { 139a88df0b9SIsaku Yamahata memcpy(eeprom_buf, eeprom_spd, eeprom_spd_size); 140a88df0b9SIsaku Yamahata } 141a88df0b9SIsaku Yamahata 142a88df0b9SIsaku Yamahata for (i = 0; i < nb_eeprom; i++) { 143*0cf487e5SCorey Minyard smbus_eeprom_init_one(smbus, 0x50 + i, 144*0cf487e5SCorey Minyard eeprom_buf + (i * SMBUS_EEPROM_SIZE)); 145a88df0b9SIsaku Yamahata } 146a88df0b9SIsaku Yamahata } 147b296b664SBALATON Zoltan 148b296b664SBALATON Zoltan /* Generate SDRAM SPD EEPROM data describing a module of type and size */ 149b296b664SBALATON Zoltan uint8_t *spd_data_generate(enum sdram_type type, ram_addr_t ram_size, 150b296b664SBALATON Zoltan Error **errp) 151b296b664SBALATON Zoltan { 152b296b664SBALATON Zoltan uint8_t *spd; 153b296b664SBALATON Zoltan uint8_t nbanks; 154b296b664SBALATON Zoltan uint16_t density; 155b296b664SBALATON Zoltan uint32_t size; 156b296b664SBALATON Zoltan int min_log2, max_log2, sz_log2; 157b296b664SBALATON Zoltan int i; 158b296b664SBALATON Zoltan 159b296b664SBALATON Zoltan switch (type) { 160b296b664SBALATON Zoltan case SDR: 161b296b664SBALATON Zoltan min_log2 = 2; 162b296b664SBALATON Zoltan max_log2 = 9; 163b296b664SBALATON Zoltan break; 164b296b664SBALATON Zoltan case DDR: 165b296b664SBALATON Zoltan min_log2 = 5; 166b296b664SBALATON Zoltan max_log2 = 12; 167b296b664SBALATON Zoltan break; 168b296b664SBALATON Zoltan case DDR2: 169b296b664SBALATON Zoltan min_log2 = 7; 170b296b664SBALATON Zoltan max_log2 = 14; 171b296b664SBALATON Zoltan break; 172b296b664SBALATON Zoltan default: 173b296b664SBALATON Zoltan g_assert_not_reached(); 174b296b664SBALATON Zoltan } 175b296b664SBALATON Zoltan size = ram_size >> 20; /* work in terms of megabytes */ 176b296b664SBALATON Zoltan if (size < 4) { 177b296b664SBALATON Zoltan error_setg(errp, "SDRAM size is too small"); 178b296b664SBALATON Zoltan return NULL; 179b296b664SBALATON Zoltan } 180b296b664SBALATON Zoltan sz_log2 = 31 - clz32(size); 181b296b664SBALATON Zoltan size = 1U << sz_log2; 182b296b664SBALATON Zoltan if (ram_size > size * MiB) { 183b296b664SBALATON Zoltan error_setg(errp, "SDRAM size 0x"RAM_ADDR_FMT" is not a power of 2, " 184b296b664SBALATON Zoltan "truncating to %u MB", ram_size, size); 185b296b664SBALATON Zoltan } 186b296b664SBALATON Zoltan if (sz_log2 < min_log2) { 187b296b664SBALATON Zoltan error_setg(errp, 188b296b664SBALATON Zoltan "Memory size is too small for SDRAM type, adjusting type"); 189b296b664SBALATON Zoltan if (size >= 32) { 190b296b664SBALATON Zoltan type = DDR; 191b296b664SBALATON Zoltan min_log2 = 5; 192b296b664SBALATON Zoltan max_log2 = 12; 193b296b664SBALATON Zoltan } else { 194b296b664SBALATON Zoltan type = SDR; 195b296b664SBALATON Zoltan min_log2 = 2; 196b296b664SBALATON Zoltan max_log2 = 9; 197b296b664SBALATON Zoltan } 198b296b664SBALATON Zoltan } 199b296b664SBALATON Zoltan 200b296b664SBALATON Zoltan nbanks = 1; 201b296b664SBALATON Zoltan while (sz_log2 > max_log2 && nbanks < 8) { 202b296b664SBALATON Zoltan sz_log2--; 203b296b664SBALATON Zoltan nbanks++; 204b296b664SBALATON Zoltan } 205b296b664SBALATON Zoltan 206b296b664SBALATON Zoltan if (size > (1ULL << sz_log2) * nbanks) { 207b296b664SBALATON Zoltan error_setg(errp, "Memory size is too big for SDRAM, truncating"); 208b296b664SBALATON Zoltan } 209b296b664SBALATON Zoltan 210b296b664SBALATON Zoltan /* split to 2 banks if possible to avoid a bug in MIPS Malta firmware */ 211b296b664SBALATON Zoltan if (nbanks == 1 && sz_log2 > min_log2) { 212b296b664SBALATON Zoltan sz_log2--; 213b296b664SBALATON Zoltan nbanks++; 214b296b664SBALATON Zoltan } 215b296b664SBALATON Zoltan 216b296b664SBALATON Zoltan density = 1ULL << (sz_log2 - 2); 217b296b664SBALATON Zoltan switch (type) { 218b296b664SBALATON Zoltan case DDR2: 219b296b664SBALATON Zoltan density = (density & 0xe0) | (density >> 8 & 0x1f); 220b296b664SBALATON Zoltan break; 221b296b664SBALATON Zoltan case DDR: 222b296b664SBALATON Zoltan density = (density & 0xf8) | (density >> 8 & 0x07); 223b296b664SBALATON Zoltan break; 224b296b664SBALATON Zoltan case SDR: 225b296b664SBALATON Zoltan default: 226b296b664SBALATON Zoltan density &= 0xff; 227b296b664SBALATON Zoltan break; 228b296b664SBALATON Zoltan } 229b296b664SBALATON Zoltan 230b296b664SBALATON Zoltan spd = g_malloc0(256); 231b296b664SBALATON Zoltan spd[0] = 128; /* data bytes in EEPROM */ 232b296b664SBALATON Zoltan spd[1] = 8; /* log2 size of EEPROM */ 233b296b664SBALATON Zoltan spd[2] = type; 234b296b664SBALATON Zoltan spd[3] = 13; /* row address bits */ 235b296b664SBALATON Zoltan spd[4] = 10; /* column address bits */ 236b296b664SBALATON Zoltan spd[5] = (type == DDR2 ? nbanks - 1 : nbanks); 237b296b664SBALATON Zoltan spd[6] = 64; /* module data width */ 238b296b664SBALATON Zoltan /* reserved / data width high */ 239b296b664SBALATON Zoltan spd[8] = 4; /* interface voltage level */ 240b296b664SBALATON Zoltan spd[9] = 0x25; /* highest CAS latency */ 241b296b664SBALATON Zoltan spd[10] = 1; /* access time */ 242b296b664SBALATON Zoltan /* DIMM configuration 0 = non-ECC */ 243b296b664SBALATON Zoltan spd[12] = 0x82; /* refresh requirements */ 244b296b664SBALATON Zoltan spd[13] = 8; /* primary SDRAM width */ 245b296b664SBALATON Zoltan /* ECC SDRAM width */ 246b296b664SBALATON Zoltan spd[15] = (type == DDR2 ? 0 : 1); /* reserved / delay for random col rd */ 247b296b664SBALATON Zoltan spd[16] = 12; /* burst lengths supported */ 248b296b664SBALATON Zoltan spd[17] = 4; /* banks per SDRAM device */ 249b296b664SBALATON Zoltan spd[18] = 12; /* ~CAS latencies supported */ 250b296b664SBALATON Zoltan spd[19] = (type == DDR2 ? 0 : 1); /* reserved / ~CS latencies supported */ 251b296b664SBALATON Zoltan spd[20] = 2; /* DIMM type / ~WE latencies */ 252b296b664SBALATON Zoltan /* module features */ 253b296b664SBALATON Zoltan /* memory chip features */ 254b296b664SBALATON Zoltan spd[23] = 0x12; /* clock cycle time @ medium CAS latency */ 255b296b664SBALATON Zoltan /* data access time */ 256b296b664SBALATON Zoltan /* clock cycle time @ short CAS latency */ 257b296b664SBALATON Zoltan /* data access time */ 258b296b664SBALATON Zoltan spd[27] = 20; /* min. row precharge time */ 259b296b664SBALATON Zoltan spd[28] = 15; /* min. row active row delay */ 260b296b664SBALATON Zoltan spd[29] = 20; /* min. ~RAS to ~CAS delay */ 261b296b664SBALATON Zoltan spd[30] = 45; /* min. active to precharge time */ 262b296b664SBALATON Zoltan spd[31] = density; 263b296b664SBALATON Zoltan spd[32] = 20; /* addr/cmd setup time */ 264b296b664SBALATON Zoltan spd[33] = 8; /* addr/cmd hold time */ 265b296b664SBALATON Zoltan spd[34] = 20; /* data input setup time */ 266b296b664SBALATON Zoltan spd[35] = 8; /* data input hold time */ 267b296b664SBALATON Zoltan 268b296b664SBALATON Zoltan /* checksum */ 269b296b664SBALATON Zoltan for (i = 0; i < 63; i++) { 270b296b664SBALATON Zoltan spd[63] += spd[i]; 271b296b664SBALATON Zoltan } 272b296b664SBALATON Zoltan return spd; 273b296b664SBALATON Zoltan } 274