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 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 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 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 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 */ 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 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 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 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 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 */ 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 363 static void reset_engine(PnvI2cCtlr *ctlr) 364 { 365 pnv_i2c_xscom_write(ctlr, I2C_RESET_I2C_REG, 0); 366 } 367 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 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 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 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 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