aspeed_i3c.c (97fb7498129500fba37f90a3b9f088c884509028) | aspeed_i3c.c (3816beda39596621ffabe6b9ea482aacdc63c1bc) |
---|---|
1/* 2 * ASPEED I3C Controller 3 * 4 * Copyright (C) 2021 ASPEED Technology Inc. 5 * Copyright (C) 2023 Google LLC 6 * 7 * This code is licensed under the GPL version 2 or later. See 8 * the COPYING file in the top-level directory. 9 */ 10 11#include "qemu/osdep.h" 12#include "qemu/log.h" 13#include "qemu/error-report.h" 14#include "hw/i3c/aspeed_i3c.h" 15#include "hw/registerfields.h" 16#include "hw/qdev-properties.h" 17#include "qapi/error.h" 18#include "migration/vmstate.h" 19#include "trace.h" | 1/* 2 * ASPEED I3C Controller 3 * 4 * Copyright (C) 2021 ASPEED Technology Inc. 5 * Copyright (C) 2023 Google LLC 6 * 7 * This code is licensed under the GPL version 2 or later. See 8 * the COPYING file in the top-level directory. 9 */ 10 11#include "qemu/osdep.h" 12#include "qemu/log.h" 13#include "qemu/error-report.h" 14#include "hw/i3c/aspeed_i3c.h" 15#include "hw/registerfields.h" 16#include "hw/qdev-properties.h" 17#include "qapi/error.h" 18#include "migration/vmstate.h" 19#include "trace.h" |
20#include "hw/i3c/i3c.h" 21#include "hw/irq.h" |
|
20 21/* I3C Controller Registers */ 22REG32(I3C1_REG0, 0x10) 23REG32(I3C1_REG1, 0x14) 24 FIELD(I3C1_REG1, I2C_MODE, 0, 1) 25 FIELD(I3C1_REG1, SLV_TEST_MODE, 1, 1) 26 FIELD(I3C1_REG1, ACT_MODE, 2, 2) 27 FIELD(I3C1_REG1, PENDING_INT, 4, 4) --- 379 unchanged lines hidden (view full) --- 407 [R_SCL_I3C_PP_TIMING] = 0xff00ff00, 408 [R_SCL_I2C_FMP_TIMING] = 0xff000000, 409 [R_SCL_EXT_TERMN_LCNT_TIMING] = 0x0000fff0, 410 [R_BUS_IDLE_TIMING] = 0xfff00000, 411 [R_EXTENDED_CAPABILITY] = 0xffffffff, 412 [R_SLAVE_CONFIG] = 0xffffffff, 413}; 414 | 22 23/* I3C Controller Registers */ 24REG32(I3C1_REG0, 0x10) 25REG32(I3C1_REG1, 0x14) 26 FIELD(I3C1_REG1, I2C_MODE, 0, 1) 27 FIELD(I3C1_REG1, SLV_TEST_MODE, 1, 1) 28 FIELD(I3C1_REG1, ACT_MODE, 2, 2) 29 FIELD(I3C1_REG1, PENDING_INT, 4, 4) --- 379 unchanged lines hidden (view full) --- 409 [R_SCL_I3C_PP_TIMING] = 0xff00ff00, 410 [R_SCL_I2C_FMP_TIMING] = 0xff000000, 411 [R_SCL_EXT_TERMN_LCNT_TIMING] = 0x0000fff0, 412 [R_BUS_IDLE_TIMING] = 0xfff00000, 413 [R_EXTENDED_CAPABILITY] = 0xffffffff, 414 [R_SLAVE_CONFIG] = 0xffffffff, 415}; 416 |
417static void aspeed_i3c_device_update_irq(AspeedI3CDevice *s) 418{ 419 bool level = !!(s->regs[R_INTR_SIGNAL_EN] & s->regs[R_INTR_STATUS]); 420 qemu_set_irq(s->irq, level); 421} 422 423static uint32_t aspeed_i3c_device_intr_status_r(AspeedI3CDevice *s) 424{ 425 /* Only return the status whose corresponding EN bits are set. */ 426 return s->regs[R_INTR_STATUS] & s->regs[R_INTR_STATUS_EN]; 427} 428 429static void aspeed_i3c_device_intr_status_w(AspeedI3CDevice *s, uint32_t val) 430{ 431 /* INTR_STATUS[13:5] is w1c, other bits are RO. */ 432 val &= 0x3fe0; 433 s->regs[R_INTR_STATUS] &= ~val; 434 435 aspeed_i3c_device_update_irq(s); 436} 437 438static void aspeed_i3c_device_intr_status_en_w(AspeedI3CDevice *s, uint32_t val) 439{ 440 s->regs[R_INTR_STATUS_EN] = val; 441 aspeed_i3c_device_update_irq(s); 442} 443 444static void aspeed_i3c_device_intr_signal_en_w(AspeedI3CDevice *s, uint32_t val) 445{ 446 s->regs[R_INTR_SIGNAL_EN] = val; 447 aspeed_i3c_device_update_irq(s); 448} 449 450static void aspeed_i3c_device_intr_force_w(AspeedI3CDevice *s, uint32_t val) 451{ 452 /* INTR_FORCE is WO, just set the corresponding INTR_STATUS bits. */ 453 s->regs[R_INTR_STATUS] = val; 454 aspeed_i3c_device_update_irq(s); 455} 456 |
|
415static uint64_t aspeed_i3c_device_read(void *opaque, hwaddr offset, 416 unsigned size) 417{ 418 AspeedI3CDevice *s = ASPEED_I3C_DEVICE(opaque); 419 uint32_t addr = offset >> 2; 420 uint64_t value; 421 422 switch (addr) { 423 /* RAZ */ 424 case R_COMMAND_QUEUE_PORT: 425 case R_RESET_CTRL: 426 case R_INTR_FORCE: 427 value = 0; 428 break; | 457static uint64_t aspeed_i3c_device_read(void *opaque, hwaddr offset, 458 unsigned size) 459{ 460 AspeedI3CDevice *s = ASPEED_I3C_DEVICE(opaque); 461 uint32_t addr = offset >> 2; 462 uint64_t value; 463 464 switch (addr) { 465 /* RAZ */ 466 case R_COMMAND_QUEUE_PORT: 467 case R_RESET_CTRL: 468 case R_INTR_FORCE: 469 value = 0; 470 break; |
471 case R_INTR_STATUS: 472 value = aspeed_i3c_device_intr_status_r(s); 473 break; |
|
429 default: 430 value = s->regs[addr]; 431 break; 432 } 433 434 trace_aspeed_i3c_device_read(s->id, offset, value); 435 436 return value; --- 28 unchanged lines hidden (view full) --- 465 "%s: write to readonly register[0x%02" HWADDR_PRIx 466 "] = 0x%08" PRIx64 "\n", 467 __func__, offset, value); 468 break; 469 case R_RX_TX_DATA_PORT: 470 break; 471 case R_RESET_CTRL: 472 break; | 474 default: 475 value = s->regs[addr]; 476 break; 477 } 478 479 trace_aspeed_i3c_device_read(s->id, offset, value); 480 481 return value; --- 28 unchanged lines hidden (view full) --- 510 "%s: write to readonly register[0x%02" HWADDR_PRIx 511 "] = 0x%08" PRIx64 "\n", 512 __func__, offset, value); 513 break; 514 case R_RX_TX_DATA_PORT: 515 break; 516 case R_RESET_CTRL: 517 break; |
518 case R_INTR_STATUS: 519 aspeed_i3c_device_intr_status_w(s, val32); 520 break; 521 case R_INTR_STATUS_EN: 522 aspeed_i3c_device_intr_status_en_w(s, val32); 523 break; 524 case R_INTR_SIGNAL_EN: 525 aspeed_i3c_device_intr_signal_en_w(s, val32); 526 break; 527 case R_INTR_FORCE: 528 aspeed_i3c_device_intr_force_w(s, val32); 529 break; |
|
473 default: 474 s->regs[addr] = val32; 475 break; 476 } 477} 478 479static const VMStateDescription aspeed_i3c_device_vmstate = { 480 .name = TYPE_ASPEED_I3C, --- 217 unchanged lines hidden --- | 530 default: 531 s->regs[addr] = val32; 532 break; 533 } 534} 535 536static const VMStateDescription aspeed_i3c_device_vmstate = { 537 .name = TYPE_ASPEED_I3C, --- 217 unchanged lines hidden --- |