[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [PATCH v1 08/15] hw/i2c/aspeed: introduce a new dma_dram_offset attr
From: |
Jamin Lin |
Subject: |
RE: [PATCH v1 08/15] hw/i2c/aspeed: introduce a new dma_dram_offset attribute in AspeedI2Cbus |
Date: |
Fri, 26 Jul 2024 02:03:28 +0000 |
Hi Cedric,
> Subject: Re: [PATCH v1 08/15] hw/i2c/aspeed: introduce a new
> dma_dram_offset attribute in AspeedI2Cbus
>
> On 7/18/24 08:49, Jamin Lin wrote:
> > The "Current DMA Operating Address Status(0x50)" register of I2C new
> > mode has been removed in AST2700.
> > This register is used for debugging and it is a read only register.
> >
> > To support AST2700 DMA mode, introduce a new dma_dram_offset class
> > attribute in AspeedI2Cbus to save the current DMA operating address.
> >
> > ASPEED AST2700 SOC is a 64 bits quad core CPUs (Cortex-a35) And the
> > base address of dram is "0x4 00000000" which is 64bits address.
> >
> > Set the dma_dram_offset data type to uint64_t for
> > 64 bits dram address DMA support.
> >
> > Both "DMA Mode Buffer Address Register(I2CD24 old mode)" and "DMA
> > Operating Address Status (I2CC50 new mode)" are used for showing the
> > low part dram offset bits [31:0], so change to read/write both
> > register bits [31:0] in bus register read/write functions.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> > hw/i2c/aspeed_i2c.c | 50
> +++++++++++++++++++++++--------------
> > include/hw/i2c/aspeed_i2c.h | 9 +------
> > 2 files changed, 32 insertions(+), 27 deletions(-)
> >
> > diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index
> > abcb1d5330..c0d3ac3867 100644
> > --- a/hw/i2c/aspeed_i2c.c
> > +++ b/hw/i2c/aspeed_i2c.c
> > @@ -114,7 +114,10 @@ static uint64_t
> aspeed_i2c_bus_old_read(AspeedI2CBus *bus, hwaddr offset,
> > if (!aic->has_dma) {
> > qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA
> support\n", __func__);
> > value = -1;
> > + break;
> > }
> > +
> > + value = extract64(bus->dma_dram_offset, 0, 32);
> > break;
> > case A_I2CD_DMA_LEN:
> > if (!aic->has_dma) {
> > @@ -150,9 +153,7 @@ static uint64_t
> aspeed_i2c_bus_new_read(AspeedI2CBus *bus, hwaddr offset,
> > case A_I2CM_DMA_TX_ADDR:
> > case A_I2CM_DMA_RX_ADDR:
> > case A_I2CM_DMA_LEN_STS:
> > - case A_I2CC_DMA_ADDR:
> > case A_I2CC_DMA_LEN:
> > -
> > case A_I2CS_DEV_ADDR:
> > case A_I2CS_DMA_RX_ADDR:
> > case A_I2CS_DMA_LEN:
> > @@ -161,6 +162,9 @@ static uint64_t
> aspeed_i2c_bus_new_read(AspeedI2CBus *bus, hwaddr offset,
> > case A_I2CS_DMA_LEN_STS:
> > /* Value is already set, don't do anything. */
> > break;
> > + case A_I2CC_DMA_ADDR:
> > + value = extract64(bus->dma_dram_offset, 0, 32);
> > + break;
> > case A_I2CS_INTR_STS:
> > break;
> > case A_I2CM_CMD:
> > @@ -210,18 +214,18 @@ static int aspeed_i2c_dma_read(AspeedI2CBus
> *bus, uint8_t *data)
> > {
> > MemTxResult result;
> > AspeedI2CState *s = bus->controller;
> > - uint32_t reg_dma_addr = aspeed_i2c_bus_dma_addr_offset(bus);
> > uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
> >
> > - result = address_space_read(&s->dram_as, bus->regs[reg_dma_addr],
> > + result = address_space_read(&s->dram_as, bus->dma_dram_offset,
> > MEMTXATTRS_UNSPECIFIED, data,
> 1);
> > if (result != MEMTX_OK) {
> > - qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM read failed
> @%08x\n",
> > - __func__, bus->regs[reg_dma_addr]);
> > + qemu_log_mask(LOG_GUEST_ERROR,
> > + "%s: DRAM read failed @%" PRIx64 "\n",
> > + __func__, bus->dma_dram_offset);
> > return -1;
> > }
> >
> > - bus->regs[reg_dma_addr]++;
> > + bus->dma_dram_offset++;
> > bus->regs[reg_dma_len]--;
> > return 0;
> > }
> > @@ -291,7 +295,6 @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
> > uint32_t reg_pool_ctrl = aspeed_i2c_bus_pool_ctrl_offset(bus);
> > uint32_t reg_byte_buf = aspeed_i2c_bus_byte_buf_offset(bus);
> > uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
> > - uint32_t reg_dma_addr = aspeed_i2c_bus_dma_addr_offset(bus);
> > int pool_rx_count = SHARED_ARRAY_FIELD_EX32(bus->regs,
> reg_pool_ctrl,
> > RX_SIZE) + 1;
> >
> > @@ -323,14 +326,17 @@ static void aspeed_i2c_bus_recv(AspeedI2CBus
> *bus)
> > data = i2c_recv(bus->bus);
> > trace_aspeed_i2c_bus_recv("DMA",
> bus->regs[reg_dma_len],
> > bus->regs[reg_dma_len],
> data);
> > - result = address_space_write(&s->dram_as,
> bus->regs[reg_dma_addr],
> > +
> > + result = address_space_write(&s->dram_as,
> > + bus->dma_dram_offset,
> >
> MEMTXATTRS_UNSPECIFIED, &data, 1);
> > if (result != MEMTX_OK) {
> > - qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write
> failed @%08x\n",
> > - __func__, bus->regs[reg_dma_addr]);
> > + qemu_log_mask(LOG_GUEST_ERROR,
> > + "%s: DRAM write failed @%" PRIx64
> "\n",
> > + __func__, bus->dma_dram_offset);
> > return;
> > }
> > - bus->regs[reg_dma_addr]++;
> > +
> > + bus->dma_dram_offset++;
> > bus->regs[reg_dma_len]--;
> > /* In new mode, keep track of how many bytes we RXed */
> > if (aspeed_i2c_is_new_mode(bus->controller)) { @@
> > -636,14 +642,18 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus
> *bus, hwaddr offset,
> > case A_I2CM_DMA_TX_ADDR:
> > bus->regs[R_I2CM_DMA_TX_ADDR] = FIELD_EX32(value,
> I2CM_DMA_TX_ADDR,
> > ADDR);
> > - bus->regs[R_I2CC_DMA_ADDR] = FIELD_EX32(value,
> I2CM_DMA_TX_ADDR, ADDR);
> > + bus->dma_dram_offset =
> > + deposit64(bus->dma_dram_offset, 0, 32,
> > + FIELD_EX32(value, I2CM_DMA_TX_ADDR,
> ADDR));
> > bus->regs[R_I2CC_DMA_LEN] = ARRAY_FIELD_EX32(bus->regs,
> I2CM_DMA_LEN,
> >
> TX_BUF_LEN) + 1;
> > break;
> > case A_I2CM_DMA_RX_ADDR:
> > bus->regs[R_I2CM_DMA_RX_ADDR] = FIELD_EX32(value,
> I2CM_DMA_RX_ADDR,
> > ADDR);
> > - bus->regs[R_I2CC_DMA_ADDR] = FIELD_EX32(value,
> I2CM_DMA_RX_ADDR, ADDR);
> > + bus->dma_dram_offset =
> > + deposit64(bus->dma_dram_offset, 0, 32,
> > + FIELD_EX32(value, I2CM_DMA_RX_ADDR,
> ADDR));
> > bus->regs[R_I2CC_DMA_LEN] = ARRAY_FIELD_EX32(bus->regs,
> I2CM_DMA_LEN,
> >
> RX_BUF_LEN) + 1;
> > break;
> > @@ -811,7 +821,8 @@ static void aspeed_i2c_bus_old_write(AspeedI2CBus
> *bus, hwaddr offset,
> > break;
> > }
> >
> > - bus->regs[R_I2CD_DMA_ADDR] = value & 0x3ffffffc;
> > + bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0,
> 32,
> > + value & 0x3ffffffc);
> > break;
> >
> > case A_I2CD_DMA_LEN:
> > @@ -1188,8 +1199,9 @@ static int
> aspeed_i2c_bus_new_slave_event(AspeedI2CBus *bus,
> > return -1;
> > }
> > ARRAY_FIELD_DP32(bus->regs, I2CS_DMA_LEN_STS, RX_LEN,
> 0);
> > - bus->regs[R_I2CC_DMA_ADDR] =
> > - ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_RX_ADDR, ADDR);
> > + bus->dma_dram_offset =
> > + deposit64(bus->dma_dram_offset, 0, 32,
> > + ARRAY_FIELD_EX32(bus->regs,
> I2CS_DMA_RX_ADDR,
> > + ADDR));
> > bus->regs[R_I2CC_DMA_LEN] =
> > ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_LEN,
> RX_BUF_LEN) + 1;
> > i2c_ack(bus->bus);
> > @@ -1255,10 +1267,10 @@ static int aspeed_i2c_bus_slave_event(I2CSlave
> *slave, enum i2c_event event)
> > static void aspeed_i2c_bus_new_slave_send_async(AspeedI2CBus *bus,
> uint8_t data)
> > {
> > assert(address_space_write(&bus->controller->dram_as,
> > - bus->regs[R_I2CC_DMA_ADDR],
> > + bus->dma_dram_offset,
> > MEMTXATTRS_UNSPECIFIED, &data,
> 1) ==
> > MEMTX_OK);
> >
> > - bus->regs[R_I2CC_DMA_ADDR]++;
> > + bus->dma_dram_offset++;
> > bus->regs[R_I2CC_DMA_LEN]--;
> > ARRAY_FIELD_DP32(bus->regs, I2CS_DMA_LEN_STS, RX_LEN,
> > ARRAY_FIELD_EX32(bus->regs,
> I2CS_DMA_LEN_STS,
> > RX_LEN) + 1); diff --git a/include/hw/i2c/aspeed_i2c.h
> > b/include/hw/i2c/aspeed_i2c.h index b42c4dc584..bdaea3207d 100644
> > --- a/include/hw/i2c/aspeed_i2c.h
> > +++ b/include/hw/i2c/aspeed_i2c.h
> > @@ -248,6 +248,7 @@ struct AspeedI2CBus {
> >
> > uint32_t regs[ASPEED_I2C_NEW_NUM_REG];
> > uint8_t pool[ASPEED_I2C_BUS_POOL_SIZE];
> > + uint64_t dma_dram_offset;
>
>
> aspeed_i2c_bus_vmstate needs an update. No need to increment again the
> vmstate version if all patches are merged in the same release cycle.
>
Thanks for review.
Will update
Jamin
> Thanks,
>
> C.
>
> > };
> >
> > struct AspeedI2CState {
> > @@ -369,14 +370,6 @@ static inline uint32_t
> aspeed_i2c_bus_dma_len_offset(AspeedI2CBus *bus)
> > return R_I2CD_DMA_LEN;
> > }
> >
> > -static inline uint32_t aspeed_i2c_bus_dma_addr_offset(AspeedI2CBus
> > *bus) -{
> > - if (aspeed_i2c_is_new_mode(bus->controller)) {
> > - return R_I2CC_DMA_ADDR;
> > - }
> > - return R_I2CD_DMA_ADDR;
> > -}
> > -
> > static inline bool aspeed_i2c_bus_is_master(AspeedI2CBus *bus)
> > {
> > return SHARED_ARRAY_FIELD_EX32(bus->regs,
> > aspeed_i2c_bus_ctrl_offset(bus),
************* Email Confidentiality Notice ********************
免責聲明:
本信件(或其附件)可能包含機密資訊,並受法律保護。如 台端非指定之收件者,請以電子郵件通知本電子郵件之發送者,
並請立即刪除本電子郵件及其附件和銷毀所有複印件。謝謝您的合作!
DISCLAIMER:
This message (and any attachments) may contain legally privileged and/or other
confidential information. If you have received it in error, please notify the
sender by reply e-mail and immediately delete the e-mail and any attachments
without copying or disclosing the contents. Thank you.
- Re: [PATCH v1 04/15] hw/i2c/aspeed: support discontinuous register memory region of I2C bus, (continued)
[PATCH v1 05/15] hw/i2c/aspeed: rename the I2C class pool attribute to share_pool, Jamin Lin, 2024/07/18
[PATCH v1 07/15] hw/i2c/aspeed: support discontinuous poll buffer memory region of I2C bus, Jamin Lin, 2024/07/18
[PATCH v1 06/15] hw/i2c/aspeed: introduce a new bus pool buffer attribute in AspeedI2Cbus, Jamin Lin, 2024/07/18
[PATCH v1 08/15] hw/i2c/aspeed: introduce a new dma_dram_offset attribute in AspeedI2Cbus, Jamin Lin, 2024/07/18
[PATCH v1 10/15] hw/i2c/aspeed: support Tx/Rx buffer 64 bits address, Jamin Lin, 2024/07/18
[PATCH v1 09/15] hw/i2c/aspeed: Add AST2700 support, Jamin Lin, 2024/07/18
[PATCH v1 11/15] hw/i2c/aspeed: support high part dram offset for DMA 64 bits, Jamin Lin, 2024/07/18
[PATCH v1 12/15] aspeed/soc: introduce a new API to get the INTC orgate information, Jamin Lin, 2024/07/18