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/misc/pca9554_regs.h" 12 #include "hw/misc/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 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 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 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 */ 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 */ 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 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 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 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 uint8_t inputs; 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]; 199 return inputs; 200 } 201 202 static void pnv_i2c_pca9554_flip_polarity(PnvI2cDev *dev) 203 { 204 uint8_t recv_buf[1]; 205 uint8_t send_buf[2]; 206 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); 212 } 213 214 static void pnv_i2c_pca9554_default_inputs(PnvI2cDev *dev) 215 { 216 uint8_t pin_values = pnv_i2c_pca9554_read_pins(dev); 217 g_assert_cmphex(pin_values, ==, 0xff); 218 } 219 220 /* Check that setting pin values and polarity changes inputs as expected */ 221 static void pnv_i2c_pca554_set_pins(PnvI2cDev *dev) 222 { 223 uint8_t pin_values; 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); 239 } 240 241 static void pnv_i2c_pca9552_default_cfg(PnvI2cDev *dev) 242 { 243 uint8_t buf[2]; 244 /* configure pwm/psc regs */ 245 buf[0] = PCA9552_PSC0; 246 buf[1] = 0xff; 247 pnv_i2c_send(dev, buf, 2); 248 buf[0] = PCA9552_PWM0; 249 buf[1] = 0x80; 250 pnv_i2c_send(dev, buf, 2); 251 buf[0] = PCA9552_PSC1; 252 buf[1] = 0xff; 253 pnv_i2c_send(dev, buf, 2); 254 buf[0] = PCA9552_PWM1; 255 buf[1] = 0x80; 256 pnv_i2c_send(dev, buf, 2); 257 258 /* configure all pins as inputs */ 259 buf[0] = PCA9552_LS0; 260 buf[1] = 0x55; 261 pnv_i2c_send(dev, buf, 2); 262 buf[0] = PCA9552_LS1; 263 buf[1] = 0x55; 264 pnv_i2c_send(dev, buf, 2); 265 buf[0] = PCA9552_LS2; 266 buf[1] = 0x55; 267 pnv_i2c_send(dev, buf, 2); 268 buf[0] = PCA9552_LS3; 269 buf[1] = 0x55; 270 pnv_i2c_send(dev, buf, 2); 271 } 272 273 static void pnv_i2c_pca9552_set_pin(PnvI2cDev *dev, int pin, bool high) 274 { 275 uint8_t send_buf[2]; 276 uint8_t recv_buf[2]; 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; 281 282 /* read current LSx value */ 283 send_buf[0] = reg; 284 pnv_i2c_send(dev, send_buf, 1); 285 pnv_i2c_recv(dev, recv_buf, 1); 286 287 /* write new value to LSx */ 288 send_buf[1] = (recv_buf[0] & mask) | new_value; 289 pnv_i2c_send(dev, send_buf, 2); 290 } 291 292 static uint16_t pnv_i2c_pca9552_read_pins(PnvI2cDev *dev) 293 { 294 uint8_t send_buf[2]; 295 uint8_t recv_buf[2]; 296 uint16_t inputs; 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; 305 return inputs; 306 } 307 308 static void pnv_i2c_pca9552_default_inputs(PnvI2cDev *dev) 309 { 310 uint16_t pin_values = pnv_i2c_pca9552_read_pins(dev); 311 g_assert_cmphex(pin_values, ==, 0xffff); 312 } 313 314 /* 315 * Set pins 0-4 one at a time and verify that pins 5-9 are 316 * set to the same value 317 */ 318 static void pnv_i2c_pca552_set_pins(PnvI2cDev *dev) 319 { 320 uint16_t pin_values; 321 322 /* set pin 0 low */ 323 pnv_i2c_pca9552_set_pin(dev, 0, 0); 324 pin_values = pnv_i2c_pca9552_read_pins(dev); 325 326 /* pins 0 and 5 should be low */ 327 g_assert_cmphex(pin_values, ==, 0xffde); 328 329 /* set pin 1 low */ 330 pnv_i2c_pca9552_set_pin(dev, 1, 0); 331 pin_values = pnv_i2c_pca9552_read_pins(dev); 332 333 /* pins 0, 1, 5 and 6 should be low */ 334 g_assert_cmphex(pin_values, ==, 0xff9c); 335 336 /* set pin 2 low */ 337 pnv_i2c_pca9552_set_pin(dev, 2, 0); 338 pin_values = pnv_i2c_pca9552_read_pins(dev); 339 340 /* pins 0, 1, 2, 5, 6 and 7 should be low */ 341 g_assert_cmphex(pin_values, ==, 0xff18); 342 343 /* set pin 3 low */ 344 pnv_i2c_pca9552_set_pin(dev, 3, 0); 345 pin_values = pnv_i2c_pca9552_read_pins(dev); 346 347 /* pins 0, 1, 2, 3, 5, 6, 7 and 8 should be low */ 348 g_assert_cmphex(pin_values, ==, 0xfe10); 349 350 /* set pin 4 low */ 351 pnv_i2c_pca9552_set_pin(dev, 4, 0); 352 pin_values = pnv_i2c_pca9552_read_pins(dev); 353 354 /* pins 0, 1, 2, 3, 5, 6, 7, 8 and 9 should be low */ 355 g_assert_cmphex(pin_values, ==, 0xfc00); 356 357 /* reset all pins to the high state */ 358 pnv_i2c_pca9552_default_cfg(dev); 359 pin_values = pnv_i2c_pca9552_read_pins(dev); 360 361 /* verify all pins went back to the high state */ 362 g_assert_cmphex(pin_values, ==, 0xffff); 363 } 364 365 static void reset_engine(PnvI2cCtlr *ctlr) 366 { 367 pnv_i2c_xscom_write(ctlr, I2C_RESET_I2C_REG, 0); 368 } 369 370 static void check_i2cm_por_regs(QTestState *qts, const PnvChip *chip) 371 { 372 int engine; 373 for (engine = 0; engine < chip->num_i2c; engine++) { 374 PnvI2cCtlr ctlr; 375 ctlr.qts = qts; 376 ctlr.chip = chip; 377 ctlr.engine = engine; 378 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); 382 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), 386 ==, 387 I2C_STAT_CMD_COMP); 388 } 389 } 390 391 static void reset_all(QTestState *qts, const PnvChip *chip) 392 { 393 int engine; 394 for (engine = 0; engine < chip->num_i2c; engine++) { 395 PnvI2cCtlr ctlr; 396 ctlr.qts = qts; 397 ctlr.chip = chip; 398 ctlr.engine = engine; 399 reset_engine(&ctlr); 400 pnv_i2c_xscom_write(&ctlr, I2C_MODE_REG, 0x02be040000000000); 401 } 402 } 403 404 static void test_host_i2c(const void *data) 405 { 406 const PnvChip *chip = data; 407 QTestState *qts; 408 const char *machine = "powernv8"; 409 PnvI2cCtlr ctlr; 410 PnvI2cDev pca9552; 411 PnvI2cDev pca9554; 412 413 if (chip->chip_type == PNV_CHIP_POWER9) { 414 machine = "powernv9"; 415 } else if (chip->chip_type == PNV_CHIP_POWER10) { 416 machine = "powernv10-rainier"; 417 } 418 419 qts = qtest_initf("-M %s -smp %d,cores=1,threads=%d -nographic " 420 "-nodefaults -serial mon:stdio -S " 421 "-d guest_errors", 422 machine, SMT, SMT); 423 424 /* Check the I2C master status registers after POR */ 425 check_i2cm_por_regs(qts, chip); 426 427 /* Now do a forced "immediate" reset on all engines */ 428 reset_all(qts, chip); 429 430 /* Check that the status values are still good */ 431 check_i2cm_por_regs(qts, chip); 432 433 /* P9 doesn't have any i2c devices attached at this time */ 434 if (chip->chip_type != PNV_CHIP_POWER10) { 435 qtest_quit(qts); 436 return; 437 } 438 439 /* Initialize for a P10 pca9552 hotplug device */ 440 ctlr.qts = qts; 441 ctlr.chip = chip; 442 ctlr.engine = 2; 443 pca9552.ctlr = &ctlr; 444 pca9552.port = 1; 445 pca9552.addr = 0x63; 446 447 /* Set all pca9552 pins as inputs */ 448 pnv_i2c_pca9552_default_cfg(&pca9552); 449 450 /* Check that all pins of the pca9552 are high */ 451 pnv_i2c_pca9552_default_inputs(&pca9552); 452 453 /* perform individual pin tests */ 454 pnv_i2c_pca552_set_pins(&pca9552); 455 456 /* Initialize for a P10 pca9554 CableCard Presence detection device */ 457 pca9554.ctlr = &ctlr; 458 pca9554.port = 1; 459 pca9554.addr = 0x25; 460 461 /* Set all pca9554 pins as inputs */ 462 pnv_i2c_pca9554_default_cfg(&pca9554); 463 464 /* Check that all pins of the pca9554 are high */ 465 pnv_i2c_pca9554_default_inputs(&pca9554); 466 467 /* perform individual pin tests */ 468 pnv_i2c_pca554_set_pins(&pca9554); 469 470 qtest_quit(qts); 471 } 472 473 static void add_test(const char *name, void (*test)(const void *data)) 474 { 475 int i; 476 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); 481 g_free(tname); 482 } 483 } 484 485 int main(int argc, char **argv) 486 { 487 g_test_init(&argc, &argv, NULL); 488 489 add_test("host-i2c", test_host_i2c); 490 return g_test_run(); 491 } 492