2 * QTest testcase for PowerNV 10 Host I2C Communications
4 * Copyright (c) 2023, IBM Corporation.
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.
9 #include "qemu/osdep.h"
11 #include "hw/gpio/pca9554_regs.h"
12 #include "hw/gpio/pca9552_regs.h"
13 #include "pnv-xscom.h"
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)) | \
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)))
27 #define PNV10_XSCOM_I2CM_BASE 0xa0000
28 #define PNV10_XSCOM_I2CM_SIZE 0x1000
30 #include "hw/i2c/pnv_i2c_regs.h"
45 static uint64_t pnv_i2c_xscom_addr(PnvI2cCtlr
*ctlr
, uint32_t reg
)
47 return pnv_xscom_addr(ctlr
->chip
, PNV10_XSCOM_I2CM_BASE
+
48 (PNV10_XSCOM_I2CM_SIZE
* ctlr
->engine
) + reg
);
51 static uint64_t pnv_i2c_xscom_read(PnvI2cCtlr
*ctlr
, uint32_t reg
)
53 return qtest_readq(ctlr
->qts
, pnv_i2c_xscom_addr(ctlr
, reg
));
56 static void pnv_i2c_xscom_write(PnvI2cCtlr
*ctlr
, uint32_t reg
, uint64_t val
)
58 qtest_writeq(ctlr
->qts
, pnv_i2c_xscom_addr(ctlr
, reg
), val
);
61 /* Write len bytes from buf to i2c device with given addr and port */
62 static void pnv_i2c_send(PnvI2cDev
*dev
, const uint8_t *buf
, uint16_t len
)
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
);
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
), ==,
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
);
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);
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
);
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
), ==,
103 /* Recieve len bytes into buf from i2c device with given addr and port */
104 static void pnv_i2c_recv(PnvI2cDev
*dev
, uint8_t *buf
, uint16_t len
)
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
);
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
), ==,
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
);
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);
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
);
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
), ==,
146 static void pnv_i2c_pca9554_default_cfg(PnvI2cDev
*dev
)
150 /* input register bits are not inverted */
151 buf
[0] = PCA9554_POLARITY
;
153 pnv_i2c_send(dev
, buf
, 2);
155 /* All pins are inputs */
156 buf
[0] = PCA9554_CONFIG
;
158 pnv_i2c_send(dev
, buf
, 2);
160 /* Output value for when pins are outputs */
161 buf
[0] = PCA9554_OUTPUT
;
163 pnv_i2c_send(dev
, buf
, 2);
166 static void pnv_i2c_pca9554_set_pin(PnvI2cDev
*dev
, int pin
, bool high
)
170 uint8_t mask
= 0x1 << pin
;
171 uint8_t new_value
= ((high
) ? 1 : 0) << pin
;
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);
178 /* write new OUTPUT value */
179 send_buf
[1] = (recv_buf
[0] & ~mask
) | new_value
;
180 pnv_i2c_send(dev
, send_buf
, 2);
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);
190 static uint8_t pnv_i2c_pca9554_read_pins(PnvI2cDev
*dev
)
195 send_buf
[0] = PCA9554_INPUT
;
196 pnv_i2c_send(dev
, send_buf
, 1);
197 pnv_i2c_recv(dev
, recv_buf
, 1);
198 inputs
= recv_buf
[0];
202 static void pnv_i2c_pca9554_flip_polarity(PnvI2cDev
*dev
)
207 send_buf
[0] = PCA9554_POLARITY
;
208 pnv_i2c_send(dev
, send_buf
, 1);
209 pnv_i2c_recv(dev
, recv_buf
, 1);
210 send_buf
[1] = recv_buf
[0] ^ 0xff;
211 pnv_i2c_send(dev
, send_buf
, 2);
214 static void pnv_i2c_pca9554_default_inputs(PnvI2cDev
*dev
)
216 uint8_t pin_values
= pnv_i2c_pca9554_read_pins(dev
);
217 g_assert_cmphex(pin_values
, ==, 0xff);
220 /* Check that setting pin values and polarity changes inputs as expected */
221 static void pnv_i2c_pca554_set_pins(PnvI2cDev
*dev
)
224 pnv_i2c_pca9554_set_pin(dev
, 0, 0);
225 pin_values
= pnv_i2c_pca9554_read_pins(dev
);
226 g_assert_cmphex(pin_values
, ==, 0xfe);
227 pnv_i2c_pca9554_flip_polarity(dev
);
228 pin_values
= pnv_i2c_pca9554_read_pins(dev
);
229 g_assert_cmphex(pin_values
, ==, 0x01);
230 pnv_i2c_pca9554_set_pin(dev
, 2, 0);
231 pin_values
= pnv_i2c_pca9554_read_pins(dev
);
232 g_assert_cmphex(pin_values
, ==, 0x05);
233 pnv_i2c_pca9554_flip_polarity(dev
);
234 pin_values
= pnv_i2c_pca9554_read_pins(dev
);
235 g_assert_cmphex(pin_values
, ==, 0xfa);
236 pnv_i2c_pca9554_default_cfg(dev
);
237 pin_values
= pnv_i2c_pca9554_read_pins(dev
);
238 g_assert_cmphex(pin_values
, ==, 0xff);
241 static void pnv_i2c_pca9552_default_cfg(PnvI2cDev
*dev
)
244 /* configure pwm/psc regs */
245 buf
[0] = PCA9552_PSC0
;
247 pnv_i2c_send(dev
, buf
, 2);
248 buf
[0] = PCA9552_PWM0
;
250 pnv_i2c_send(dev
, buf
, 2);
251 buf
[0] = PCA9552_PSC1
;
253 pnv_i2c_send(dev
, buf
, 2);
254 buf
[0] = PCA9552_PWM1
;
256 pnv_i2c_send(dev
, buf
, 2);
258 /* configure all pins as inputs */
259 buf
[0] = PCA9552_LS0
;
261 pnv_i2c_send(dev
, buf
, 2);
262 buf
[0] = PCA9552_LS1
;
264 pnv_i2c_send(dev
, buf
, 2);
265 buf
[0] = PCA9552_LS2
;
267 pnv_i2c_send(dev
, buf
, 2);
268 buf
[0] = PCA9552_LS3
;
270 pnv_i2c_send(dev
, buf
, 2);
273 static void pnv_i2c_pca9552_set_pin(PnvI2cDev
*dev
, int pin
, bool high
)
277 uint8_t reg
= PCA9552_LS0
+ (pin
/ 4);
278 uint8_t shift
= (pin
% 4) * 2;
279 uint8_t mask
= ~(0x3 << shift
);
280 uint8_t new_value
= ((high
) ? 1 : 0) << shift
;
282 /* read current LSx value */
284 pnv_i2c_send(dev
, send_buf
, 1);
285 pnv_i2c_recv(dev
, recv_buf
, 1);
287 /* write new value to LSx */
288 send_buf
[1] = (recv_buf
[0] & mask
) | new_value
;
289 pnv_i2c_send(dev
, send_buf
, 2);
292 static uint16_t pnv_i2c_pca9552_read_pins(PnvI2cDev
*dev
)
297 send_buf
[0] = PCA9552_INPUT0
;
298 pnv_i2c_send(dev
, send_buf
, 1);
299 pnv_i2c_recv(dev
, recv_buf
, 1);
300 inputs
= recv_buf
[0];
301 send_buf
[0] = PCA9552_INPUT1
;
302 pnv_i2c_send(dev
, send_buf
, 1);
303 pnv_i2c_recv(dev
, recv_buf
, 1);
304 inputs
|= recv_buf
[0] << 8;
308 static void pnv_i2c_pca9552_default_inputs(PnvI2cDev
*dev
)
310 uint16_t pin_values
= pnv_i2c_pca9552_read_pins(dev
);
311 g_assert_cmphex(pin_values
, ==, 0xffff);
315 * Set pins 0-4 one at a time and verify that pins 5-9 are
316 * set to the same value
318 static void pnv_i2c_pca552_set_pins(PnvI2cDev
*dev
)
323 pnv_i2c_pca9552_set_pin(dev
, 0, 0);
324 pin_values
= pnv_i2c_pca9552_read_pins(dev
);
326 /* pins 0 and 5 should be low */
327 g_assert_cmphex(pin_values
, ==, 0xffde);
330 pnv_i2c_pca9552_set_pin(dev
, 1, 0);
331 pin_values
= pnv_i2c_pca9552_read_pins(dev
);
333 /* pins 0, 1, 5 and 6 should be low */
334 g_assert_cmphex(pin_values
, ==, 0xff9c);
337 pnv_i2c_pca9552_set_pin(dev
, 2, 0);
338 pin_values
= pnv_i2c_pca9552_read_pins(dev
);
340 /* pins 0, 1, 2, 5, 6 and 7 should be low */
341 g_assert_cmphex(pin_values
, ==, 0xff18);
344 pnv_i2c_pca9552_set_pin(dev
, 3, 0);
345 pin_values
= pnv_i2c_pca9552_read_pins(dev
);
347 /* pins 0, 1, 2, 3, 5, 6, 7 and 8 should be low */
348 g_assert_cmphex(pin_values
, ==, 0xfe10);
351 pnv_i2c_pca9552_set_pin(dev
, 4, 0);
352 pin_values
= pnv_i2c_pca9552_read_pins(dev
);
354 /* pins 0, 1, 2, 3, 5, 6, 7, 8 and 9 should be low */
355 g_assert_cmphex(pin_values
, ==, 0xfc00);
357 /* reset all pins to the high state */
358 pnv_i2c_pca9552_default_cfg(dev
);
359 pin_values
= pnv_i2c_pca9552_read_pins(dev
);
361 /* verify all pins went back to the high state */
362 g_assert_cmphex(pin_values
, ==, 0xffff);
365 static void reset_engine(PnvI2cCtlr
*ctlr
)
367 pnv_i2c_xscom_write(ctlr
, I2C_RESET_I2C_REG
, 0);
370 static void check_i2cm_por_regs(QTestState
*qts
, const PnvChip
*chip
)
373 for (engine
= 0; engine
< chip
->num_i2c
; engine
++) {
377 ctlr
.engine
= engine
;
379 /* Check version in Extended Status Register */
380 uint64_t value
= pnv_i2c_xscom_read(&ctlr
, I2C_EXTD_STAT_REG
);
381 g_assert_cmphex(value
& I2C_EXTD_STAT_I2C_VERSION
, ==, 0x1700000000);
383 /* Check for command complete and bus idle in Status Register */
384 value
= pnv_i2c_xscom_read(&ctlr
, I2C_STAT_REG
);
385 g_assert_cmphex(value
& (I2C_STAT_ANY_ERR
| I2C_STAT_CMD_COMP
),
391 static void reset_all(QTestState
*qts
, const PnvChip
*chip
)
394 for (engine
= 0; engine
< chip
->num_i2c
; engine
++) {
398 ctlr
.engine
= engine
;
400 pnv_i2c_xscom_write(&ctlr
, I2C_MODE_REG
, 0x02be040000000000);
404 static void test_host_i2c(const void *data
)
406 const PnvChip
*chip
= data
;
408 const char *machine
= "powernv8";
413 if (chip
->chip_type
== PNV_CHIP_POWER9
) {
414 machine
= "powernv9";
415 } else if (chip
->chip_type
== PNV_CHIP_POWER10
) {
416 machine
= "powernv10-rainier";
419 qts
= qtest_initf("-M %s -smp %d,cores=1,threads=%d -nographic "
420 "-nodefaults -serial mon:stdio -S "
424 /* Check the I2C master status registers after POR */
425 check_i2cm_por_regs(qts
, chip
);
427 /* Now do a forced "immediate" reset on all engines */
428 reset_all(qts
, chip
);
430 /* Check that the status values are still good */
431 check_i2cm_por_regs(qts
, chip
);
433 /* P9 doesn't have any i2c devices attached at this time */
434 if (chip
->chip_type
!= PNV_CHIP_POWER10
) {
439 /* Initialize for a P10 pca9552 hotplug device */
443 pca9552
.ctlr
= &ctlr
;
447 /* Set all pca9552 pins as inputs */
448 pnv_i2c_pca9552_default_cfg(&pca9552
);
450 /* Check that all pins of the pca9552 are high */
451 pnv_i2c_pca9552_default_inputs(&pca9552
);
453 /* perform individual pin tests */
454 pnv_i2c_pca552_set_pins(&pca9552
);
456 /* Initialize for a P10 pca9554 CableCard Presence detection device */
457 pca9554
.ctlr
= &ctlr
;
461 /* Set all pca9554 pins as inputs */
462 pnv_i2c_pca9554_default_cfg(&pca9554
);
464 /* Check that all pins of the pca9554 are high */
465 pnv_i2c_pca9554_default_inputs(&pca9554
);
467 /* perform individual pin tests */
468 pnv_i2c_pca554_set_pins(&pca9554
);
473 static void add_test(const char *name
, void (*test
)(const void *data
))
477 for (i
= 0; i
< ARRAY_SIZE(pnv_chips
); i
++) {
478 char *tname
= g_strdup_printf("pnv-xscom/%s/%s", name
,
479 pnv_chips
[i
].cpu_model
);
480 qtest_add_data_func(tname
, &pnv_chips
[i
], test
);
485 int main(int argc
, char **argv
)
487 g_test_init(&argc
, &argv
, NULL
);
489 add_test("host-i2c", test_host_i2c
);