xref: /openbmc/qemu/hw/i2c/smbus_eeprom.c (revision 93198b6cad8af03996373584284a1673ad6000cb)
1 /*
2  * QEMU SMBus EEPROM device
3  *
4  * Copyright (c) 2007 Arastra, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
25 #include "qemu/osdep.h"
26 #include "qemu/units.h"
27 #include "qapi/error.h"
28 #include "hw/hw.h"
29 #include "hw/i2c/i2c.h"
30 #include "hw/i2c/smbus_slave.h"
31 #include "hw/i2c/smbus_eeprom.h"
32 
33 //#define DEBUG
34 
35 typedef struct SMBusEEPROMDevice {
36     SMBusDevice smbusdev;
37     void *data;
38     uint8_t offset;
39 } SMBusEEPROMDevice;
40 
41 static void eeprom_quick_cmd(SMBusDevice *dev, uint8_t read)
42 {
43 #ifdef DEBUG
44     printf("eeprom_quick_cmd: addr=0x%02x read=%d\n", dev->i2c.address, read);
45 #endif
46 }
47 
48 static void eeprom_send_byte(SMBusDevice *dev, uint8_t val)
49 {
50     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
51 #ifdef DEBUG
52     printf("eeprom_send_byte: addr=0x%02x val=0x%02x\n",
53            dev->i2c.address, val);
54 #endif
55     eeprom->offset = val;
56 }
57 
58 static uint8_t eeprom_receive_byte(SMBusDevice *dev)
59 {
60     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
61     uint8_t *data = eeprom->data;
62     uint8_t val = data[eeprom->offset++];
63 #ifdef DEBUG
64     printf("eeprom_receive_byte: addr=0x%02x val=0x%02x\n",
65            dev->i2c.address, val);
66 #endif
67     return val;
68 }
69 
70 static void eeprom_write_data(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len)
71 {
72     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
73     int n;
74 #ifdef DEBUG
75     printf("eeprom_write_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n",
76            dev->i2c.address, cmd, buf[0]);
77 #endif
78     /* A page write operation is not a valid SMBus command.
79        It is a block write without a length byte.  Fortunately we
80        get the full block anyway.  */
81     /* TODO: Should this set the current location?  */
82     if (cmd + len > 256)
83         n = 256 - cmd;
84     else
85         n = len;
86     memcpy(eeprom->data + cmd, buf, n);
87     len -= n;
88     if (len)
89         memcpy(eeprom->data, buf + n, len);
90 }
91 
92 static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n)
93 {
94     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
95     /* If this is the first byte then set the current position.  */
96     if (n == 0)
97         eeprom->offset = cmd;
98     /* As with writes, we implement block reads without the
99        SMBus length byte.  */
100     return eeprom_receive_byte(dev);
101 }
102 
103 static void smbus_eeprom_realize(DeviceState *dev, Error **errp)
104 {
105     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *)dev;
106 
107     eeprom->offset = 0;
108 }
109 
110 static Property smbus_eeprom_properties[] = {
111     DEFINE_PROP_PTR("data", SMBusEEPROMDevice, data),
112     DEFINE_PROP_END_OF_LIST(),
113 };
114 
115 static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
116 {
117     DeviceClass *dc = DEVICE_CLASS(klass);
118     SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass);
119 
120     dc->realize = smbus_eeprom_realize;
121     sc->quick_cmd = eeprom_quick_cmd;
122     sc->send_byte = eeprom_send_byte;
123     sc->receive_byte = eeprom_receive_byte;
124     sc->write_data = eeprom_write_data;
125     sc->read_data = eeprom_read_data;
126     dc->props = smbus_eeprom_properties;
127     /* Reason: pointer property "data" */
128     dc->user_creatable = false;
129 }
130 
131 static const TypeInfo smbus_eeprom_info = {
132     .name          = "smbus-eeprom",
133     .parent        = TYPE_SMBUS_DEVICE,
134     .instance_size = sizeof(SMBusEEPROMDevice),
135     .class_init    = smbus_eeprom_class_initfn,
136 };
137 
138 static void smbus_eeprom_register_types(void)
139 {
140     type_register_static(&smbus_eeprom_info);
141 }
142 
143 type_init(smbus_eeprom_register_types)
144 
145 void smbus_eeprom_init_one(I2CBus *smbus, uint8_t address, uint8_t *eeprom_buf)
146 {
147     DeviceState *dev;
148 
149     dev = qdev_create((BusState *) smbus, "smbus-eeprom");
150     qdev_prop_set_uint8(dev, "address", address);
151     qdev_prop_set_ptr(dev, "data", eeprom_buf);
152     qdev_init_nofail(dev);
153 }
154 
155 void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom,
156                        const uint8_t *eeprom_spd, int eeprom_spd_size)
157 {
158     int i;
159     uint8_t *eeprom_buf = g_malloc0(8 * 256); /* XXX: make this persistent */
160     if (eeprom_spd_size > 0) {
161         memcpy(eeprom_buf, eeprom_spd, eeprom_spd_size);
162     }
163 
164     for (i = 0; i < nb_eeprom; i++) {
165         smbus_eeprom_init_one(smbus, 0x50 + i, eeprom_buf + (i * 256));
166     }
167 }
168 
169 /* Generate SDRAM SPD EEPROM data describing a module of type and size */
170 uint8_t *spd_data_generate(enum sdram_type type, ram_addr_t ram_size,
171                            Error **errp)
172 {
173     uint8_t *spd;
174     uint8_t nbanks;
175     uint16_t density;
176     uint32_t size;
177     int min_log2, max_log2, sz_log2;
178     int i;
179 
180     switch (type) {
181     case SDR:
182         min_log2 = 2;
183         max_log2 = 9;
184         break;
185     case DDR:
186         min_log2 = 5;
187         max_log2 = 12;
188         break;
189     case DDR2:
190         min_log2 = 7;
191         max_log2 = 14;
192         break;
193     default:
194         g_assert_not_reached();
195     }
196     size = ram_size >> 20; /* work in terms of megabytes */
197     if (size < 4) {
198         error_setg(errp, "SDRAM size is too small");
199         return NULL;
200     }
201     sz_log2 = 31 - clz32(size);
202     size = 1U << sz_log2;
203     if (ram_size > size * MiB) {
204         error_setg(errp, "SDRAM size 0x"RAM_ADDR_FMT" is not a power of 2, "
205                    "truncating to %u MB", ram_size, size);
206     }
207     if (sz_log2 < min_log2) {
208         error_setg(errp,
209                    "Memory size is too small for SDRAM type, adjusting type");
210         if (size >= 32) {
211             type = DDR;
212             min_log2 = 5;
213             max_log2 = 12;
214         } else {
215             type = SDR;
216             min_log2 = 2;
217             max_log2 = 9;
218         }
219     }
220 
221     nbanks = 1;
222     while (sz_log2 > max_log2 && nbanks < 8) {
223         sz_log2--;
224         nbanks++;
225     }
226 
227     if (size > (1ULL << sz_log2) * nbanks) {
228         error_setg(errp, "Memory size is too big for SDRAM, truncating");
229     }
230 
231     /* split to 2 banks if possible to avoid a bug in MIPS Malta firmware */
232     if (nbanks == 1 && sz_log2 > min_log2) {
233         sz_log2--;
234         nbanks++;
235     }
236 
237     density = 1ULL << (sz_log2 - 2);
238     switch (type) {
239     case DDR2:
240         density = (density & 0xe0) | (density >> 8 & 0x1f);
241         break;
242     case DDR:
243         density = (density & 0xf8) | (density >> 8 & 0x07);
244         break;
245     case SDR:
246     default:
247         density &= 0xff;
248         break;
249     }
250 
251     spd = g_malloc0(256);
252     spd[0] = 128;   /* data bytes in EEPROM */
253     spd[1] = 8;     /* log2 size of EEPROM */
254     spd[2] = type;
255     spd[3] = 13;    /* row address bits */
256     spd[4] = 10;    /* column address bits */
257     spd[5] = (type == DDR2 ? nbanks - 1 : nbanks);
258     spd[6] = 64;    /* module data width */
259                     /* reserved / data width high */
260     spd[8] = 4;     /* interface voltage level */
261     spd[9] = 0x25;  /* highest CAS latency */
262     spd[10] = 1;    /* access time */
263                     /* DIMM configuration 0 = non-ECC */
264     spd[12] = 0x82; /* refresh requirements */
265     spd[13] = 8;    /* primary SDRAM width */
266                     /* ECC SDRAM width */
267     spd[15] = (type == DDR2 ? 0 : 1); /* reserved / delay for random col rd */
268     spd[16] = 12;   /* burst lengths supported */
269     spd[17] = 4;    /* banks per SDRAM device */
270     spd[18] = 12;   /* ~CAS latencies supported */
271     spd[19] = (type == DDR2 ? 0 : 1); /* reserved / ~CS latencies supported */
272     spd[20] = 2;    /* DIMM type / ~WE latencies */
273                     /* module features */
274                     /* memory chip features */
275     spd[23] = 0x12; /* clock cycle time @ medium CAS latency */
276                     /* data access time */
277                     /* clock cycle time @ short CAS latency */
278                     /* data access time */
279     spd[27] = 20;   /* min. row precharge time */
280     spd[28] = 15;   /* min. row active row delay */
281     spd[29] = 20;   /* min. ~RAS to ~CAS delay */
282     spd[30] = 45;   /* min. active to precharge time */
283     spd[31] = density;
284     spd[32] = 20;   /* addr/cmd setup time */
285     spd[33] = 8;    /* addr/cmd hold time */
286     spd[34] = 20;   /* data input setup time */
287     spd[35] = 8;    /* data input hold time */
288 
289     /* checksum */
290     for (i = 0; i < 63; i++) {
291         spd[63] += spd[i];
292     }
293     return spd;
294 }
295