1 /*
2 * QTest testcase for PowerNV 10 Host I2C Communications
3 *
4 * Copyright (c) 2023, IBM Corporation.
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2 or
7 * later. See the COPYING file in the top-level directory.
8 */
9 #include "qemu/osdep.h"
10 #include "libqtest.h"
11 #include "hw/gpio/pca9554_regs.h"
12 #include "hw/gpio/pca9552_regs.h"
13 #include "pnv-xscom.h"
14
15 #define PPC_BIT(bit) (0x8000000000000000ULL >> (bit))
16 #define PPC_BIT32(bit) (0x80000000 >> (bit))
17 #define PPC_BIT8(bit) (0x80 >> (bit))
18 #define PPC_BITMASK(bs, be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs))
19 #define PPC_BITMASK32(bs, be) ((PPC_BIT32(bs) - PPC_BIT32(be)) | \
20 PPC_BIT32(bs))
21
22 #define MASK_TO_LSH(m) (__builtin_ffsll(m) - 1)
23 #define GETFIELD(m, v) (((v) & (m)) >> MASK_TO_LSH(m))
24 #define SETFIELD(m, v, val) \
25 (((v) & ~(m)) | ((((typeof(v))(val)) << MASK_TO_LSH(m)) & (m)))
26
27 #define PNV10_XSCOM_I2CM_BASE 0xa0000
28 #define PNV10_XSCOM_I2CM_SIZE 0x1000
29
30 #include "hw/i2c/pnv_i2c_regs.h"
31
32 typedef struct {
33 QTestState *qts;
34 const PnvChip *chip;
35 int engine;
36 } PnvI2cCtlr;
37
38 typedef struct {
39 PnvI2cCtlr *ctlr;
40 int port;
41 uint8_t addr;
42 } PnvI2cDev;
43
44
pnv_i2c_xscom_addr(PnvI2cCtlr * ctlr,uint32_t reg)45 static uint64_t pnv_i2c_xscom_addr(PnvI2cCtlr *ctlr, uint32_t reg)
46 {
47 return pnv_xscom_addr(ctlr->chip, PNV10_XSCOM_I2CM_BASE +
48 (PNV10_XSCOM_I2CM_SIZE * ctlr->engine) + reg);
49 }
50
pnv_i2c_xscom_read(PnvI2cCtlr * ctlr,uint32_t reg)51 static uint64_t pnv_i2c_xscom_read(PnvI2cCtlr *ctlr, uint32_t reg)
52 {
53 return qtest_readq(ctlr->qts, pnv_i2c_xscom_addr(ctlr, reg));
54 }
55
pnv_i2c_xscom_write(PnvI2cCtlr * ctlr,uint32_t reg,uint64_t val)56 static void pnv_i2c_xscom_write(PnvI2cCtlr *ctlr, uint32_t reg, uint64_t val)
57 {
58 qtest_writeq(ctlr->qts, pnv_i2c_xscom_addr(ctlr, reg), val);
59 }
60
61 /* Write len bytes from buf to i2c device with given addr and port */
pnv_i2c_send(PnvI2cDev * dev,const uint8_t * buf,uint16_t len)62 static void pnv_i2c_send(PnvI2cDev *dev, const uint8_t *buf, uint16_t len)
63 {
64 int byte_num;
65 uint64_t reg64;
66
67 /* select requested port */
68 reg64 = SETFIELD(I2C_MODE_BIT_RATE_DIV, 0ull, 0x2be);
69 reg64 = SETFIELD(I2C_MODE_PORT_NUM, reg64, dev->port);
70 pnv_i2c_xscom_write(dev->ctlr, I2C_MODE_REG, reg64);
71
72 /* check status for cmd complete and bus idle */
73 reg64 = pnv_i2c_xscom_read(dev->ctlr, I2C_EXTD_STAT_REG);
74 g_assert_cmphex(reg64 & I2C_EXTD_STAT_I2C_BUSY, ==, 0);
75 reg64 = pnv_i2c_xscom_read(dev->ctlr, I2C_STAT_REG);
76 g_assert_cmphex(reg64 & (I2C_STAT_ANY_ERR | I2C_STAT_CMD_COMP), ==,
77 I2C_STAT_CMD_COMP);
78
79 /* Send start, with stop, with address and len bytes of data */
80 reg64 = I2C_CMD_WITH_START | I2C_CMD_WITH_ADDR | I2C_CMD_WITH_STOP;
81 reg64 = SETFIELD(I2C_CMD_DEV_ADDR, reg64, dev->addr);
82 reg64 = SETFIELD(I2C_CMD_LEN_BYTES, reg64, len);
83 pnv_i2c_xscom_write(dev->ctlr, I2C_CMD_REG, reg64);
84
85 /* check status for errors */
86 reg64 = pnv_i2c_xscom_read(dev->ctlr, I2C_STAT_REG);
87 g_assert_cmphex(reg64 & I2C_STAT_ANY_ERR, ==, 0);
88
89 /* write data bytes to fifo register */
90 for (byte_num = 0; byte_num < len; byte_num++) {
91 reg64 = SETFIELD(I2C_FIFO, 0ull, buf[byte_num]);
92 pnv_i2c_xscom_write(dev->ctlr, I2C_FIFO_REG, reg64);
93 }
94
95 /* check status for cmd complete and bus idle */
96 reg64 = pnv_i2c_xscom_read(dev->ctlr, I2C_EXTD_STAT_REG);
97 g_assert_cmphex(reg64 & I2C_EXTD_STAT_I2C_BUSY, ==, 0);
98 reg64 = pnv_i2c_xscom_read(dev->ctlr, I2C_STAT_REG);
99 g_assert_cmphex(reg64 & (I2C_STAT_ANY_ERR | I2C_STAT_CMD_COMP), ==,
100 I2C_STAT_CMD_COMP);
101 }
102
103 /* Recieve len bytes into buf from i2c device with given addr and port */
pnv_i2c_recv(PnvI2cDev * dev,uint8_t * buf,uint16_t len)104 static void pnv_i2c_recv(PnvI2cDev *dev, uint8_t *buf, uint16_t len)
105 {
106 int byte_num;
107 uint64_t reg64;
108
109 /* select requested port */
110 reg64 = SETFIELD(I2C_MODE_BIT_RATE_DIV, 0ull, 0x2be);
111 reg64 = SETFIELD(I2C_MODE_PORT_NUM, reg64, dev->port);
112 pnv_i2c_xscom_write(dev->ctlr, I2C_MODE_REG, reg64);
113
114 /* check status for cmd complete and bus idle */
115 reg64 = pnv_i2c_xscom_read(dev->ctlr, I2C_EXTD_STAT_REG);
116 g_assert_cmphex(reg64 & I2C_EXTD_STAT_I2C_BUSY, ==, 0);
117 reg64 = pnv_i2c_xscom_read(dev->ctlr, I2C_STAT_REG);
118 g_assert_cmphex(reg64 & (I2C_STAT_ANY_ERR | I2C_STAT_CMD_COMP), ==,
119 I2C_STAT_CMD_COMP);
120
121 /* Send start, with stop, with address and len bytes of data */
122 reg64 = I2C_CMD_WITH_START | I2C_CMD_WITH_ADDR |
123 I2C_CMD_WITH_STOP | I2C_CMD_READ_NOT_WRITE;
124 reg64 = SETFIELD(I2C_CMD_DEV_ADDR, reg64, dev->addr);
125 reg64 = SETFIELD(I2C_CMD_LEN_BYTES, reg64, len);
126 pnv_i2c_xscom_write(dev->ctlr, I2C_CMD_REG, reg64);
127
128 /* check status for errors */
129 reg64 = pnv_i2c_xscom_read(dev->ctlr, I2C_STAT_REG);
130 g_assert_cmphex(reg64 & I2C_STAT_ANY_ERR, ==, 0);
131
132 /* Read data bytes from fifo register */
133 for (byte_num = 0; byte_num < len; byte_num++) {
134 reg64 = pnv_i2c_xscom_read(dev->ctlr, I2C_FIFO_REG);
135 buf[byte_num] = GETFIELD(I2C_FIFO, reg64);
136 }
137
138 /* check status for cmd complete and bus idle */
139 reg64 = pnv_i2c_xscom_read(dev->ctlr, I2C_EXTD_STAT_REG);
140 g_assert_cmphex(reg64 & I2C_EXTD_STAT_I2C_BUSY, ==, 0);
141 reg64 = pnv_i2c_xscom_read(dev->ctlr, I2C_STAT_REG);
142 g_assert_cmphex(reg64 & (I2C_STAT_ANY_ERR | I2C_STAT_CMD_COMP), ==,
143 I2C_STAT_CMD_COMP);
144 }
145
pnv_i2c_pca9554_default_cfg(PnvI2cDev * dev)146 static void pnv_i2c_pca9554_default_cfg(PnvI2cDev *dev)
147 {
148 uint8_t buf[2];
149
150 /* input register bits are not inverted */
151 buf[0] = PCA9554_POLARITY;
152 buf[1] = 0;
153 pnv_i2c_send(dev, buf, 2);
154
155 /* All pins are inputs */
156 buf[0] = PCA9554_CONFIG;
157 buf[1] = 0xff;
158 pnv_i2c_send(dev, buf, 2);
159
160 /* Output value for when pins are outputs */
161 buf[0] = PCA9554_OUTPUT;
162 buf[1] = 0xff;
163 pnv_i2c_send(dev, buf, 2);
164 }
165
pnv_i2c_pca9554_set_pin(PnvI2cDev * dev,int pin,bool high)166 static void pnv_i2c_pca9554_set_pin(PnvI2cDev *dev, int pin, bool high)
167 {
168 uint8_t send_buf[2];
169 uint8_t recv_buf[2];
170 uint8_t mask = 0x1 << pin;
171 uint8_t new_value = ((high) ? 1 : 0) << pin;
172
173 /* read current OUTPUT value */
174 send_buf[0] = PCA9554_OUTPUT;
175 pnv_i2c_send(dev, send_buf, 1);
176 pnv_i2c_recv(dev, recv_buf, 1);
177
178 /* write new OUTPUT value */
179 send_buf[1] = (recv_buf[0] & ~mask) | new_value;
180 pnv_i2c_send(dev, send_buf, 2);
181
182 /* Update config bit for output */
183 send_buf[0] = PCA9554_CONFIG;
184 pnv_i2c_send(dev, send_buf, 1);
185 pnv_i2c_recv(dev, recv_buf, 1);
186 send_buf[1] = recv_buf[0] & ~mask;
187 pnv_i2c_send(dev, send_buf, 2);
188 }
189
pnv_i2c_pca9554_read_pins(PnvI2cDev * dev)190 static uint8_t pnv_i2c_pca9554_read_pins(PnvI2cDev *dev)
191 {
192 uint8_t send_buf[1];
193 uint8_t recv_buf[1];
194 send_buf[0] = PCA9554_INPUT;
195 pnv_i2c_send(dev, send_buf, 1);
196 pnv_i2c_recv(dev, recv_buf, 1);
197 return recv_buf[0];
198 }
199
pnv_i2c_pca9554_flip_polarity(PnvI2cDev * dev)200 static void pnv_i2c_pca9554_flip_polarity(PnvI2cDev *dev)
201 {
202 uint8_t recv_buf[1];
203 uint8_t send_buf[2];
204
205 send_buf[0] = PCA9554_POLARITY;
206 pnv_i2c_send(dev, send_buf, 1);
207 pnv_i2c_recv(dev, recv_buf, 1);
208 send_buf[1] = recv_buf[0] ^ 0xff;
209 pnv_i2c_send(dev, send_buf, 2);
210 }
211
pnv_i2c_pca9554_default_inputs(PnvI2cDev * dev)212 static void pnv_i2c_pca9554_default_inputs(PnvI2cDev *dev)
213 {
214 uint8_t pin_values = pnv_i2c_pca9554_read_pins(dev);
215 g_assert_cmphex(pin_values, ==, 0xff);
216 }
217
218 /* Check that setting pin values and polarity changes inputs as expected */
pnv_i2c_pca554_set_pins(PnvI2cDev * dev)219 static void pnv_i2c_pca554_set_pins(PnvI2cDev *dev)
220 {
221 uint8_t pin_values;
222 pnv_i2c_pca9554_set_pin(dev, 0, 0);
223 pin_values = pnv_i2c_pca9554_read_pins(dev);
224 g_assert_cmphex(pin_values, ==, 0xfe);
225 pnv_i2c_pca9554_flip_polarity(dev);
226 pin_values = pnv_i2c_pca9554_read_pins(dev);
227 g_assert_cmphex(pin_values, ==, 0x01);
228 pnv_i2c_pca9554_set_pin(dev, 2, 0);
229 pin_values = pnv_i2c_pca9554_read_pins(dev);
230 g_assert_cmphex(pin_values, ==, 0x05);
231 pnv_i2c_pca9554_flip_polarity(dev);
232 pin_values = pnv_i2c_pca9554_read_pins(dev);
233 g_assert_cmphex(pin_values, ==, 0xfa);
234 pnv_i2c_pca9554_default_cfg(dev);
235 pin_values = pnv_i2c_pca9554_read_pins(dev);
236 g_assert_cmphex(pin_values, ==, 0xff);
237 }
238
pnv_i2c_pca9552_default_cfg(PnvI2cDev * dev)239 static void pnv_i2c_pca9552_default_cfg(PnvI2cDev *dev)
240 {
241 uint8_t buf[2];
242 /* configure pwm/psc regs */
243 buf[0] = PCA9552_PSC0;
244 buf[1] = 0xff;
245 pnv_i2c_send(dev, buf, 2);
246 buf[0] = PCA9552_PWM0;
247 buf[1] = 0x80;
248 pnv_i2c_send(dev, buf, 2);
249 buf[0] = PCA9552_PSC1;
250 buf[1] = 0xff;
251 pnv_i2c_send(dev, buf, 2);
252 buf[0] = PCA9552_PWM1;
253 buf[1] = 0x80;
254 pnv_i2c_send(dev, buf, 2);
255
256 /* configure all pins as inputs */
257 buf[0] = PCA9552_LS0;
258 buf[1] = 0x55;
259 pnv_i2c_send(dev, buf, 2);
260 buf[0] = PCA9552_LS1;
261 buf[1] = 0x55;
262 pnv_i2c_send(dev, buf, 2);
263 buf[0] = PCA9552_LS2;
264 buf[1] = 0x55;
265 pnv_i2c_send(dev, buf, 2);
266 buf[0] = PCA9552_LS3;
267 buf[1] = 0x55;
268 pnv_i2c_send(dev, buf, 2);
269 }
270
pnv_i2c_pca9552_set_pin(PnvI2cDev * dev,int pin,bool high)271 static void pnv_i2c_pca9552_set_pin(PnvI2cDev *dev, int pin, bool high)
272 {
273 uint8_t send_buf[2];
274 uint8_t recv_buf[2];
275 uint8_t reg = PCA9552_LS0 + (pin / 4);
276 uint8_t shift = (pin % 4) * 2;
277 uint8_t mask = ~(0x3 << shift);
278 uint8_t new_value = ((high) ? 1 : 0) << shift;
279
280 /* read current LSx value */
281 send_buf[0] = reg;
282 pnv_i2c_send(dev, send_buf, 1);
283 pnv_i2c_recv(dev, recv_buf, 1);
284
285 /* write new value to LSx */
286 send_buf[1] = (recv_buf[0] & mask) | new_value;
287 pnv_i2c_send(dev, send_buf, 2);
288 }
289
pnv_i2c_pca9552_read_pins(PnvI2cDev * dev)290 static uint16_t pnv_i2c_pca9552_read_pins(PnvI2cDev *dev)
291 {
292 uint8_t send_buf[2];
293 uint8_t recv_buf[2];
294 uint16_t inputs;
295 send_buf[0] = PCA9552_INPUT0;
296 pnv_i2c_send(dev, send_buf, 1);
297 pnv_i2c_recv(dev, recv_buf, 1);
298 inputs = recv_buf[0];
299 send_buf[0] = PCA9552_INPUT1;
300 pnv_i2c_send(dev, send_buf, 1);
301 pnv_i2c_recv(dev, recv_buf, 1);
302 inputs |= recv_buf[0] << 8;
303 return inputs;
304 }
305
pnv_i2c_pca9552_default_inputs(PnvI2cDev * dev)306 static void pnv_i2c_pca9552_default_inputs(PnvI2cDev *dev)
307 {
308 uint16_t pin_values = pnv_i2c_pca9552_read_pins(dev);
309 g_assert_cmphex(pin_values, ==, 0xffff);
310 }
311
312 /*
313 * Set pins 0-4 one at a time and verify that pins 5-9 are
314 * set to the same value
315 */
pnv_i2c_pca552_set_pins(PnvI2cDev * dev)316 static void pnv_i2c_pca552_set_pins(PnvI2cDev *dev)
317 {
318 uint16_t pin_values;
319
320 /* set pin 0 low */
321 pnv_i2c_pca9552_set_pin(dev, 0, 0);
322 pin_values = pnv_i2c_pca9552_read_pins(dev);
323
324 /* pins 0 and 5 should be low */
325 g_assert_cmphex(pin_values, ==, 0xffde);
326
327 /* set pin 1 low */
328 pnv_i2c_pca9552_set_pin(dev, 1, 0);
329 pin_values = pnv_i2c_pca9552_read_pins(dev);
330
331 /* pins 0, 1, 5 and 6 should be low */
332 g_assert_cmphex(pin_values, ==, 0xff9c);
333
334 /* set pin 2 low */
335 pnv_i2c_pca9552_set_pin(dev, 2, 0);
336 pin_values = pnv_i2c_pca9552_read_pins(dev);
337
338 /* pins 0, 1, 2, 5, 6 and 7 should be low */
339 g_assert_cmphex(pin_values, ==, 0xff18);
340
341 /* set pin 3 low */
342 pnv_i2c_pca9552_set_pin(dev, 3, 0);
343 pin_values = pnv_i2c_pca9552_read_pins(dev);
344
345 /* pins 0, 1, 2, 3, 5, 6, 7 and 8 should be low */
346 g_assert_cmphex(pin_values, ==, 0xfe10);
347
348 /* set pin 4 low */
349 pnv_i2c_pca9552_set_pin(dev, 4, 0);
350 pin_values = pnv_i2c_pca9552_read_pins(dev);
351
352 /* pins 0, 1, 2, 3, 5, 6, 7, 8 and 9 should be low */
353 g_assert_cmphex(pin_values, ==, 0xfc00);
354
355 /* reset all pins to the high state */
356 pnv_i2c_pca9552_default_cfg(dev);
357 pin_values = pnv_i2c_pca9552_read_pins(dev);
358
359 /* verify all pins went back to the high state */
360 g_assert_cmphex(pin_values, ==, 0xffff);
361 }
362
reset_engine(PnvI2cCtlr * ctlr)363 static void reset_engine(PnvI2cCtlr *ctlr)
364 {
365 pnv_i2c_xscom_write(ctlr, I2C_RESET_I2C_REG, 0);
366 }
367
check_i2cm_por_regs(QTestState * qts,const PnvChip * chip)368 static void check_i2cm_por_regs(QTestState *qts, const PnvChip *chip)
369 {
370 int engine;
371 for (engine = 0; engine < chip->num_i2c; engine++) {
372 PnvI2cCtlr ctlr;
373 ctlr.qts = qts;
374 ctlr.chip = chip;
375 ctlr.engine = engine;
376
377 /* Check version in Extended Status Register */
378 uint64_t value = pnv_i2c_xscom_read(&ctlr, I2C_EXTD_STAT_REG);
379 g_assert_cmphex(value & I2C_EXTD_STAT_I2C_VERSION, ==, 0x1700000000);
380
381 /* Check for command complete and bus idle in Status Register */
382 value = pnv_i2c_xscom_read(&ctlr, I2C_STAT_REG);
383 g_assert_cmphex(value & (I2C_STAT_ANY_ERR | I2C_STAT_CMD_COMP),
384 ==,
385 I2C_STAT_CMD_COMP);
386 }
387 }
388
reset_all(QTestState * qts,const PnvChip * chip)389 static void reset_all(QTestState *qts, const PnvChip *chip)
390 {
391 int engine;
392 for (engine = 0; engine < chip->num_i2c; engine++) {
393 PnvI2cCtlr ctlr;
394 ctlr.qts = qts;
395 ctlr.chip = chip;
396 ctlr.engine = engine;
397 reset_engine(&ctlr);
398 pnv_i2c_xscom_write(&ctlr, I2C_MODE_REG, 0x02be040000000000);
399 }
400 }
401
test_host_i2c(const void * data)402 static void test_host_i2c(const void *data)
403 {
404 const PnvChip *chip = data;
405 QTestState *qts;
406 const char *machine = "powernv8";
407 PnvI2cCtlr ctlr;
408 PnvI2cDev pca9552;
409 PnvI2cDev pca9554;
410
411 if (chip->chip_type == PNV_CHIP_POWER9) {
412 machine = "powernv9";
413 } else if (chip->chip_type == PNV_CHIP_POWER10) {
414 machine = "powernv10-rainier";
415 }
416
417 qts = qtest_initf("-M %s -smp %d,cores=1,threads=%d -nographic "
418 "-nodefaults -serial mon:stdio -S "
419 "-d guest_errors",
420 machine, SMT, SMT);
421
422 /* Check the I2C master status registers after POR */
423 check_i2cm_por_regs(qts, chip);
424
425 /* Now do a forced "immediate" reset on all engines */
426 reset_all(qts, chip);
427
428 /* Check that the status values are still good */
429 check_i2cm_por_regs(qts, chip);
430
431 /* P9 doesn't have any i2c devices attached at this time */
432 if (chip->chip_type != PNV_CHIP_POWER10) {
433 qtest_quit(qts);
434 return;
435 }
436
437 /* Initialize for a P10 pca9552 hotplug device */
438 ctlr.qts = qts;
439 ctlr.chip = chip;
440 ctlr.engine = 2;
441 pca9552.ctlr = &ctlr;
442 pca9552.port = 1;
443 pca9552.addr = 0x63;
444
445 /* Set all pca9552 pins as inputs */
446 pnv_i2c_pca9552_default_cfg(&pca9552);
447
448 /* Check that all pins of the pca9552 are high */
449 pnv_i2c_pca9552_default_inputs(&pca9552);
450
451 /* perform individual pin tests */
452 pnv_i2c_pca552_set_pins(&pca9552);
453
454 /* Initialize for a P10 pca9554 CableCard Presence detection device */
455 pca9554.ctlr = &ctlr;
456 pca9554.port = 1;
457 pca9554.addr = 0x25;
458
459 /* Set all pca9554 pins as inputs */
460 pnv_i2c_pca9554_default_cfg(&pca9554);
461
462 /* Check that all pins of the pca9554 are high */
463 pnv_i2c_pca9554_default_inputs(&pca9554);
464
465 /* perform individual pin tests */
466 pnv_i2c_pca554_set_pins(&pca9554);
467
468 qtest_quit(qts);
469 }
470
add_test(const char * name,void (* test)(const void * data))471 static void add_test(const char *name, void (*test)(const void *data))
472 {
473 int i;
474
475 for (i = 0; i < ARRAY_SIZE(pnv_chips); i++) {
476 char *tname = g_strdup_printf("pnv-xscom/%s/%s", name,
477 pnv_chips[i].cpu_model);
478 qtest_add_data_func(tname, &pnv_chips[i], test);
479 g_free(tname);
480 }
481 }
482
main(int argc,char ** argv)483 int main(int argc, char **argv)
484 {
485 g_test_init(&argc, &argv, NULL);
486
487 add_test("host-i2c", test_host_i2c);
488 return g_test_run();
489 }
490