diff --git a/bsp_sedi/drivers/dma/sedi_dma_ann_1p0.c b/bsp_sedi/drivers/dma/sedi_dma_ann_1p0.c index 504eb1f..379b293 100644 --- a/bsp_sedi/drivers/dma/sedi_dma_ann_1p0.c +++ b/bsp_sedi/drivers/dma/sedi_dma_ann_1p0.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Intel Corporation + * Copyright (c) 2023-2024 Intel Corporation * * SPDX-License-Identifier: BSD-3-Clause */ @@ -113,20 +113,26 @@ int sedi_dma_get_capabilities(IN sedi_dma_t dma_device, static inline void dma_vnn_req(sedi_dma_t dma_device, int channel_id) { + unsigned int key = sedi_core_irq_lock(); + if (dma_context[dma_device].vnn_status == 0) { PM_VNN_DRIVER_REQ(VNN_ID_DMA0 + dma_device); } dma_context[dma_device].vnn_status |= BIT(channel_id); + sedi_core_irq_unlock(key); } static inline void dma_vnn_dereq(sedi_dma_t dma_device, int channel_id) { + unsigned int key = sedi_core_irq_lock(); + if (dma_context[dma_device].vnn_status & (BIT(channel_id))) { dma_context[dma_device].vnn_status &= (~BIT(channel_id)); + if (dma_context[dma_device].vnn_status == 0) { + PM_VNN_DRIVER_DEREQ(VNN_ID_DMA0 + dma_device); + } } - if (dma_context[dma_device].vnn_status == 0) { - PM_VNN_DRIVER_DEREQ(VNN_ID_DMA0 + dma_device); - } + sedi_core_irq_unlock(key); } static void dma_set_default_channel_config(OUT channel_config_t *config) diff --git a/bsp_sedi/drivers/hpet/sedi_hpet.c b/bsp_sedi/drivers/hpet/sedi_hpet.c index faae6e8..218ab71 100644 --- a/bsp_sedi/drivers/hpet/sedi_hpet.c +++ b/bsp_sedi/drivers/hpet/sedi_hpet.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Intel Corporation + * Copyright (c) 2023 - 2024 Intel Corporation * * SPDX-License-Identifier: BSD-3-Clause */ @@ -62,8 +62,7 @@ static const sedi_hpet_capabilities_t hpet_cap = { 0 }; static inline void wait_for_idle(uint32_t bits) { - while (SEDI_REG_GET(HPET, HPET_CTRL_STS) & bits) - ; + SEDI_POLL_WAIT(SEDI_REG_GET(HPET, HPET_CTRL_STS) & bits, 10); } uint32_t sedi_hpet_get_min_delay(void) @@ -166,6 +165,11 @@ uint64_t sedi_hpet_get_main_counter(void) return ((uint64_t)highBits << 32) | lowBits; } +uint64_t sedi_hpet_get_us(void) +{ + return HPET_CYCLE_TO_US(sedi_hpet_get_main_counter()); +} + void sedi_hpet_enable_interrupt(IN sedi_hpet_t timer_id) { switch (timer_id) { @@ -216,6 +220,9 @@ int32_t sedi_hpet_init(uint32_t clk_divisor, uint32_t min_delay) * Initial state of HPET is unknown, so put it back in a reset-like * state (i.e. set main counter to 0 and disable interrupts) */ + sedi_hpet_update_comparator(HPET_0, (uint64_t)-1); + sedi_hpet_update_comparator(HPET_1, (uint64_t)-1); + sedi_hpet_update_comparator(HPET_2, (uint64_t)-1); SEDI_REG_RBFV_SET(HPET, GCFG_LOW, EN, 0); SEDI_REG_SET(HPET, GIS_LOW, SEDI_REG_GET(HPET, GIS_LOW)); SEDI_REG_SET(HPET, MCV, (uint64_t)0x0); @@ -307,6 +314,7 @@ int32_t sedi_hpet_kill_timer(IN sedi_hpet_t timer_id) /* Disable interrupt */ sedi_hpet_disable_interrupt(timer_id); + sedi_hpet_set_int_status(BIT(timer_id)); /* Set comparator all bits as 1 */ sedi_hpet_update_comparator(timer_id, (uint64_t)-1); diff --git a/bsp_sedi/drivers/i2c/sedi_i2c_dw_apb_200a.c b/bsp_sedi/drivers/i2c/sedi_i2c_dw_apb_200a.c index b50ca2b..ef26b3d 100644 --- a/bsp_sedi/drivers/i2c/sedi_i2c_dw_apb_200a.c +++ b/bsp_sedi/drivers/i2c/sedi_i2c_dw_apb_200a.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Intel Corporation + * Copyright (c) 2023 - 2024 Intel Corporation * * SPDX-License-Identifier: BSD-3-Clause */ @@ -26,10 +26,6 @@ enum { I2C_SPEED_STANDARD = 0, I2C_SPEED_FAST, I2C_SPEED_FAST_PLUS, I2C_SPEED_HI SEDI_RBFVM(I2C, TX_ABRT_SOURCE, ABRT_TXDATA_NOACK, ABRT_TXDATA_NOACK_GENERATED) | \ SEDI_RBFVM(I2C, TX_ABRT_SOURCE, ABRT_GCALL_NOACK, ABRT_GCALL_NOACK_GENERATED)) -#define BSETS_DMA_ENABLE \ - (SEDI_RBFVM(I2C, DMA_CR, RDMAE, ENABLED) | \ - SEDI_RBFVM(I2C, DMA_CR, TDMAE, ENABLED)) - #define BSETS_INTR_ERROR \ (SEDI_RBFVM(I2C, INTR_STAT, R_RX_UNDER, ACTIVE) | \ SEDI_RBFVM(I2C, INTR_STAT, R_RX_OVER, ACTIVE) | \ @@ -64,7 +60,6 @@ enum { I2C_SPEED_STANDARD = 0, I2C_SPEED_FAST, I2C_SPEED_FAST_PLUS, I2C_SPEED_HI typedef enum { I2C_DMA_DIRECTION_TX = 0, I2C_DMA_DIRECTION_RX = 1, - I2C_DMA_DIRECTION_RX_CMD = 2 } i2c_dma_diretion_t; struct i2c_context { @@ -110,19 +105,14 @@ static uint32_t regval_speed[I2C_SPEED_MAX] = { * For example, standard mode is 100KHz, 10000ns per period, 5000ns for * SCL low & high level. */ -#define I2C_SS_SCL_HIGH 4000 -#define I2C_SS_SCL_LOW 4700 -#define I2C_FS_SCL_HIGH 600 -#define I2C_FS_SCL_LOW 1300 +#define I2C_SS_SCL_HIGH 4500 +#define I2C_SS_SCL_LOW 5100 +#define I2C_FS_SCL_HIGH 690 +#define I2C_FS_SCL_LOW 1650 #define I2C_FSP_SCL_HIGH 300 -#define I2C_FSP_SCL_LOW 600 -#ifndef I2C_SCL_400PF -#define I2C_HS_SCL_HIGH 70 -#define I2C_HS_SCL_LOW 590 -#else -#define I2C_HS_SCL_HIGH 160 -#define I2C_HS_SCL_LOW 320 -#endif +#define I2C_FSP_SCL_LOW 500 +#define I2C_HS_SCL_HIGH 300 +#define I2C_HS_SCL_LOW 500 #define I2C_CONTEXT_INIT(x) \ { \ @@ -133,7 +123,10 @@ static uint32_t regval_speed[I2C_SPEED_MAX] = { struct i2c_context contexts[SEDI_I2C_NUM] = { I2C_CONTEXT_INIT(0), I2C_CONTEXT_INIT(1), I2C_CONTEXT_INIT(2) }; +#define SEDI_I2C_POLL_WAIT(_cond) SEDI_POLL_WAIT_MUTE((_cond), 100) + static void i2c_isr_complete(sedi_i2c_t i2c_device, bool is_error); + static void init_i2c_prescale(sedi_i2c_bus_info_t *bus_info) { if (bus_info->std_clk.hcnt == 0) { @@ -167,8 +160,8 @@ static void dw_i2c_enable(uint32_t base) i2c->intr_mask = 0; i2c->enable = SEDI_RBFVM(I2C, ENABLE, ENABLE, ENABLED); - while (SEDI_PREG_RBFV_IS_SET(I2C, ENABLE_STATUS, IC_EN, DISABLED, &i2c->enable_status)) - ; + SEDI_I2C_POLL_WAIT(SEDI_PREG_RBFV_IS_SET(I2C, ENABLE_STATUS, IC_EN, DISABLED, + &i2c->enable_status)); } static int dw_i2c_disable(uint32_t base) @@ -185,16 +178,15 @@ static int dw_i2c_disable(uint32_t base) if (SEDI_PREG_RBFV_IS_SET(I2C, STATUS, MST_ACTIVITY, ACTIVE, &i2c->status)) { SEDI_PREG_RBFV_SET(I2C, ENABLE, ABORT, ENABLED, &i2c->enable); - while (SEDI_PREG_RBFV_IS_SET(I2C, ENABLE, ABORT, ENABLED, &i2c->enable)) - ; + SEDI_I2C_POLL_WAIT(SEDI_PREG_RBFV_IS_SET(I2C, ENABLE, ABORT, ENABLED, + &i2c->enable)); } - while (SEDI_PREG_RBFV_IS_SET(I2C, STATUS, MST_ACTIVITY, ACTIVE, &i2c->status)) - ; + SEDI_I2C_POLL_WAIT(SEDI_PREG_RBFV_IS_SET(I2C, STATUS, MST_ACTIVITY, ACTIVE, &i2c->status)); i2c->enable = 0; - while (SEDI_PREG_RBFV_IS_SET(I2C, ENABLE_STATUS, IC_EN, ENABLED, &i2c->enable_status)) - ; + SEDI_I2C_POLL_WAIT(SEDI_PREG_RBFV_IS_SET(I2C, ENABLE_STATUS, IC_EN, ENABLED, + &i2c->enable_status)); return 0; } @@ -268,6 +260,7 @@ static int dw_i2c_config_rxfifo(uint32_t base, uint32_t watermark) static int dw_i2c_poll_write(uint32_t base, const uint8_t *buffer, uint32_t length, bool pending) { + int ret; sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)base; uint32_t cmd = SEDI_RBFVM(I2C, DATA_CMD, CMD, WRITE); @@ -278,24 +271,28 @@ static int dw_i2c_poll_write(uint32_t base, const uint8_t *buffer, uint32_t leng } i2c->data_cmd = buffer[i] | cmd; - /* Check abort and error */ - do { - if (i2c->raw_intr_stat & BSETS_INTR_ERROR) { - return -1; - } - } while (SEDI_PREG_RBFV_IS_SET(I2C, STATUS, TFNF, FULL, &i2c->status)); + ret = SEDI_I2C_POLL_WAIT(SEDI_PREG_RBFV_IS_SET(I2C, STATUS, TFNF, FULL, + &i2c->status) && !(i2c->raw_intr_stat & BSETS_INTR_ERROR)); + if (ret) { + return ret; + } + /* Check abort and error */ + if (i2c->raw_intr_stat & BSETS_INTR_ERROR) { + return SEDI_DRIVER_ERROR_TRANSFER; + } } /* Wait for end */ - while (SEDI_PREG_RBFV_IS_SET(I2C, STATUS, ACTIVITY, ACTIVE, &i2c->status)) { - } + ret = SEDI_I2C_POLL_WAIT(SEDI_PREG_RBFV_IS_SET(I2C, STATUS, ACTIVITY, ACTIVE, + &i2c->status)); - return 0; + return ret; } static int dw_i2c_poll_read(uint32_t base, uint8_t *buffer, uint32_t length, bool pending) { + int ret; sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)base; uint32_t cmd = SEDI_RBFVM(I2C, DATA_CMD, CMD, READ); @@ -305,22 +302,26 @@ static int dw_i2c_poll_read(uint32_t base, uint8_t *buffer, uint32_t length, boo } i2c->data_cmd = cmd; - do { - /* Check abort and error*/ - if (i2c->raw_intr_stat & BSETS_INTR_ERROR) { - return -1; - } - } while (SEDI_PREG_RBFV_IS_SET(I2C, STATUS, RFNE, EMPTY, &i2c->status)); + ret = SEDI_I2C_POLL_WAIT(SEDI_PREG_RBFV_IS_SET(I2C, STATUS, RFNE, EMPTY, + &i2c->status) && !(i2c->raw_intr_stat & BSETS_INTR_ERROR)); + if (ret) { + return ret; + } + /* Check abort and error*/ + if (i2c->raw_intr_stat & BSETS_INTR_ERROR) { + return SEDI_DRIVER_ERROR_TRANSFER; + } + buffer[i] = (uint8_t)(i2c->data_cmd & 0xFF); } /* Wait for end */ - while (SEDI_PREG_RBFV_IS_SET(I2C, STATUS, ACTIVITY, ACTIVE, &i2c->status)) { - } + ret = SEDI_I2C_POLL_WAIT(SEDI_PREG_RBFV_IS_SET(I2C, STATUS, ACTIVITY, ACTIVE, + &i2c->status)); - return 0; + return ret; } static inline void dw_i2c_irq_config(uint32_t base, uint32_t config) @@ -349,14 +350,21 @@ static uint32_t dw_i2c_clear_interrupt(uint32_t base) return stat; } -static void dw_i2c_dma_enable(uint32_t base, int fifo_depth) +static void dw_i2c_dma_enable(uint32_t base, int fifo_depth, int tx_only) { sedi_i2c_regs_t *i2c = (void *)base; + uint32_t dma_cr = SEDI_RBFVM(I2C, DMA_CR, TDMAE, ENABLED); + SEDI_PREG_RBF_SET(I2C, TX_TL, TX_TL, fifo_depth, &i2c->tx_tl); i2c->dma_tdlr = SEDI_RBFM_VALUE(I2C, DMA_TDLR, DMATDL, fifo_depth); - i2c->dma_rdlr = SEDI_RBFM_VALUE(I2C, DMA_RDLR, DMARDL, fifo_depth - 1); - i2c->dma_cr = BSETS_DMA_ENABLE; + if (!tx_only) { + SEDI_PREG_RBF_SET(I2C, RX_TL, RX_TL, fifo_depth - 1, &i2c->rx_tl); + i2c->dma_rdlr = SEDI_RBFM_VALUE(I2C, DMA_RDLR, DMARDL, fifo_depth - 1); + dma_cr |= SEDI_RBFVM(I2C, DMA_CR, RDMAE, ENABLED); + } + + i2c->dma_cr = dma_cr; } /* force enter IDLE mode */ @@ -375,10 +383,8 @@ static void dw_i2c_abort(struct i2c_context *context) SEDI_PREG_RBFV_SET(I2C, ENABLE, ABORT, ENABLED, &i2c->enable); /* Waiting for abort operation finished, HW can clear */ - while (SEDI_PREG_RBFV_IS_SET(I2C, RAW_INTR_STAT, TX_ABRT, INACTIVE, &i2c->raw_intr_stat)) { - ; - } - + SEDI_I2C_POLL_WAIT(SEDI_PREG_RBFV_IS_SET(I2C, RAW_INTR_STAT, TX_ABRT, INACTIVE, + &i2c->raw_intr_stat)); while (SEDI_PREG_RBFV_GET(I2C, RXFLR, RXFLR, &i2c->rxflr) != 0) { value = i2c->data_cmd; } @@ -546,8 +552,8 @@ static void i2c_send(sedi_i2c_t i2c_device) static const sedi_driver_version_t driver_version = { SEDI_I2C_API_VERSION, SEDI_I2C_DRV_VERSION }; static sedi_i2c_capabilities_t driver_capabilities[SEDI_I2C_NUM] = { 0 }; -/* Used for I2C DMA Rx */ -static uint8_t dma_cmd __attribute__((aligned(32))) = 1; +/* Used for I2C DMA Rx, peripheral to peripheral not support, from has 5.8 */ +static uint8_t dma_cmd[I2C_MAX_BLOCK_TS] __attribute__((aligned(32))); sedi_driver_version_t sedi_i2c_get_version(void) { @@ -601,7 +607,13 @@ int32_t sedi_i2c_init(IN sedi_i2c_t i2c_device, /* i2c default configuration */ context->speed = I2C_SPEED_STANDARD; context->clk_info = &(context->bus_info.std_clk); - dw_i2c_config_speed(context->base, context->speed, context->clk_info); + + /* read command for rx dma */ + dma_cmd[0] = (SEDI_RBFVM(I2C, DATA_CMD, CMD, READ) | + SEDI_RBFVM(I2C, DATA_CMD, RESTART, ENABLE)) >> 8; + for (int i = 1; i < I2C_MAX_BLOCK_TS; i++) + dma_cmd[i] = SEDI_RBFVM(I2C, DATA_CMD, CMD, READ) >> 8; + sedi_core_clean_dcache_by_addr((uint32_t *)(dma_cmd), sizeof(dma_cmd)); return SEDI_DRIVER_OK; } @@ -649,15 +661,14 @@ int32_t sedi_i2c_set_power(IN sedi_i2c_t i2c_device, IN sedi_power_state_t state return ret; } -static void callback_tx_dma_transfer(const sedi_dma_t dma, const int chan, const int event, - void *param) +static void callback_dma_transfer(const sedi_dma_t dma, const int chan, + const int event, void *param) { struct i2c_context *context = &contexts[(int)param]; sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)(context->base); uint32_t i2c_event = SEDI_I2C_EVENT_TRANSFER_INCOMPLETE | SEDI_I2C_EVENT_DMA_ERROR; - PARAM_UNUSED(dma); - PARAM_UNUSED(chan); + sedi_dma_set_power(dma, chan, SEDI_POWER_LOW); /* DMA error, go to end */ if (event != SEDI_DMA_EVENT_TRANSFER_DONE) { @@ -666,76 +677,28 @@ static void callback_tx_dma_transfer(const sedi_dma_t dma, const int chan, const return; } - SEDI_PREG_RBFV_SET(I2C, DMA_CR, TDMAE, DISABLED, &i2c->dma_cr); - context->buf_index = context->buf_size; - context->tx_dma_chan = SEDI_I2C_DMA_CHANNEL_UNUSED; - - if (context->pending) { - /* If no STOP, all data sent by DMA, enable TX_EMPTY interrupt - * to get stop condition. - */ - SEDI_PREG_RBF_SET(I2C, TX_TL, TX_TL, 0, &i2c->tx_tl); - SEDI_PREG_RBFV_SET(I2C, INTR_MASK, M_TX_EMPTY, DISABLED, &i2c->intr_mask); + /* DMA tx_only or rx_cmd */ + if (context->tx_dma_chan == chan) { + /* disable tx dma */ + context->tx_dma_chan = SEDI_I2C_DMA_CHANNEL_UNUSED; + SEDI_PREG_RBFV_SET(I2C, DMA_CR, TDMAE, DISABLED, &i2c->dma_cr); + + /* sent last data by interrupt, with stop if not pending */ + uint32_t data = (context->rx_dma_chan != SEDI_I2C_DMA_CHANNEL_UNUSED) + ? SEDI_RBFVM(I2C, DATA_CMD, CMD, READ) + : context->buf[context->buf_size - 1]; + SEDI_I2C_POLL_WAIT(SEDI_PREG_RBFV_GET(I2C, TXFLR, TXFLR, &i2c->txflr) + == I2C_FIFO_DEPTH); + i2c->data_cmd = data | (context->pending + ? 0 : (SEDI_RBFVM(I2C, DATA_CMD, STOP, ENABLE))); + context->buf_index = context->buf_size; } else { - /* WA for I2C DMA transfer, wait until FIFO not full*/ - /* If need STOP, last data sent by interrupt */ - while (SEDI_PREG_RBFV_GET(I2C, TXFLR, TXFLR, &i2c->txflr) == I2C_FIFO_DEPTH) { - } - i2c->data_cmd = context->buf[context->buf_size - 1] | - SEDI_RBFVM(I2C, DATA_CMD, STOP, ENABLE); - } -} - -static void callback_rx_dma_transfer(const sedi_dma_t dma, const int chan, const int event, - void *param) -{ - struct i2c_context *context = &contexts[(int)param]; - sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)(context->base); - uint32_t i2c_event = SEDI_I2C_EVENT_TRANSFER_INCOMPLETE | SEDI_I2C_EVENT_DMA_ERROR; - - PARAM_UNUSED(dma); - PARAM_UNUSED(chan); + /* disable rx dma */ + context->rx_dma_chan = SEDI_I2C_DMA_CHANNEL_UNUSED; + SEDI_PREG_RBFV_SET(I2C, DMA_CR, RDMAE, DISABLED, &i2c->dma_cr); - /* DMA error, go to end */ - if (event != SEDI_DMA_EVENT_TRANSFER_DONE) { - context->status.event = i2c_event; - i2c_isr_complete((sedi_i2c_t)param, true); - return; - } - - /* Disable the Rx dma request */ - SEDI_PREG_RBFV_SET(I2C, DMA_CR, RDMAE, DISABLED, &i2c->dma_cr); - context->buf_index = context->buf_size; - context->rx_dma_chan = SEDI_I2C_DMA_CHANNEL_UNUSED; -} - -static void callback_rx_cmd_dma_transfer(const sedi_dma_t dma, const int chan, const int event, - void *param) -{ - struct i2c_context *context = &contexts[(int)param]; - sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)(context->base); - uint32_t i2c_event = SEDI_I2C_EVENT_TRANSFER_INCOMPLETE | SEDI_I2C_EVENT_DMA_ERROR; - - PARAM_UNUSED(dma); - PARAM_UNUSED(chan); - - /* DMA error, go to end */ - if (event != SEDI_DMA_EVENT_TRANSFER_DONE) { - context->status.event = i2c_event; - i2c_isr_complete((sedi_i2c_t)param, true); - return; - } - - context->tx_dma_chan = SEDI_I2C_DMA_CHANNEL_UNUSED; - - /* Send the last command, which is different from previous one*/ - while (SEDI_PREG_RBFV_GET(I2C, TXFLR, TXFLR, &i2c->txflr) == I2C_FIFO_DEPTH) { - } - if (context->pending) { - i2c->data_cmd = SEDI_RBFVM(I2C, DATA_CMD, CMD, READ); - } else { - i2c->data_cmd = SEDI_RBFVM(I2C, DATA_CMD, CMD, READ) | SEDI_RBFVM(I2C, DATA_CMD, - STOP, ENABLE); + /* dma rx data complete */ + i2c_isr_complete((sedi_i2c_t)param, false); } } @@ -744,26 +707,15 @@ static int config_and_enable_dma_channel(sedi_i2c_t i2c_dev, int dma, int handsh i2c_dma_diretion_t dir) { int ret; - int dma_dir; - int dma_per_dir; - - if (dir == I2C_DMA_DIRECTION_TX) { - dma_dir = DMA_MEMORY_TO_PERIPHERAL; - dma_per_dir = DMA_HS_PER_TX; - ret = sedi_dma_init(dma, chan, callback_tx_dma_transfer, (void *)i2c_dev); - DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR); - } else if (dir == I2C_DMA_DIRECTION_RX) { + int dma_dir = DMA_MEMORY_TO_PERIPHERAL; + + if (dir == I2C_DMA_DIRECTION_RX) { dma_dir = DMA_PERIPHERAL_TO_MEMORY; - dma_per_dir = DMA_HS_PER_RX; - ret = sedi_dma_init(dma, chan, callback_rx_dma_transfer, (void *)i2c_dev); - DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR); - } else { - dma_dir = DMA_PERIPHERAL_TO_PERIPHERAL; - dma_per_dir = DMA_HS_PER_TX; - ret = sedi_dma_init(dma, chan, callback_rx_cmd_dma_transfer, (void *)i2c_dev); - DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR); } + ret = sedi_dma_init(dma, chan, callback_dma_transfer, (void *)i2c_dev); + DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR); + ret = sedi_dma_set_power(dma, chan, SEDI_POWER_FULL); DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR); @@ -785,9 +737,6 @@ static int config_and_enable_dma_channel(sedi_i2c_t i2c_dev, int dma, int handsh ret = sedi_dma_control(dma, chan, SEDI_CONFIG_DMA_DIRECTION, dma_dir); DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR); - ret = sedi_dma_control(dma, chan, SEDI_CONFIG_DMA_HS_DEVICE_ID_PER_DIR, dma_per_dir); - DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR); - ret = sedi_dma_start_transfer(dma, chan, src, dst, len); DBG_CHECK(0 == ret, SEDI_DRIVER_ERROR); @@ -802,6 +751,7 @@ int32_t sedi_i2c_master_write_dma(IN sedi_i2c_t i2c_device, IN uint32_t addr, IN DBG_CHECK(NULL != data, SEDI_DRIVER_ERROR_PARAMETER); struct i2c_context *context = &contexts[i2c_device]; + sedi_i2c_regs_t *i2c = (sedi_i2c_regs_t *)(context->base); /* dma max block ts 4095, need slicing if exceed, tbd */ if (num <= SEDI_I2C_DMA_LENGTH_LIMIT || num > I2C_MAX_BLOCK_TS) { @@ -812,9 +762,9 @@ int32_t sedi_i2c_master_write_dma(IN sedi_i2c_t i2c_device, IN uint32_t addr, IN return SEDI_DRIVER_ERROR_BUSY; } + dw_i2c_disable(context->base); dw_i2c_clear_interrupt(context->base); dw_i2c_config_addr(context->base, addr); - dw_i2c_enable(context->base); context->status.busy = 1U; context->status.direction = 0U; @@ -826,14 +776,14 @@ int32_t sedi_i2c_master_write_dma(IN sedi_i2c_t i2c_device, IN uint32_t addr, IN context->tx_dma_dev = dma_dev; context->tx_dma_chan = dma_chan; - dw_i2c_irq_config(context->base, - BSETS_INTR_ERROR | SEDI_RBFVM(I2C, INTR_MASK, M_STOP_DET, DISABLED)); - - dw_i2c_dma_enable(context->base, 1); + i2c->intr_mask = BSETS_INTR_ERROR | SEDI_RBFVM(I2C, INTR_MASK, M_STOP_DET, DISABLED); config_and_enable_dma_channel(i2c_device, context->tx_dma_dev, context->tx_dma_handshake, context->tx_dma_chan, (uint32_t)data, dw_i2c_dr_address(context->base), - pending ? num : num - 1, I2C_DMA_DIRECTION_TX); + num - 1, I2C_DMA_DIRECTION_TX); + + dw_i2c_dma_enable(context->base, 1, 1); + i2c->enable = SEDI_RBFVM(I2C, ENABLE, ENABLE, ENABLED); return SEDI_DRIVER_OK; } @@ -858,9 +808,9 @@ int32_t sedi_i2c_master_read_dma(IN sedi_i2c_t i2c_device, IN uint32_t addr, OUT return SEDI_DRIVER_ERROR_BUSY; } + dw_i2c_disable(context->base); dw_i2c_clear_interrupt(context->base); dw_i2c_config_addr(context->base, addr); - dw_i2c_enable(context->base); context->status.busy = 1U; context->status.direction = 1U; @@ -874,25 +824,20 @@ int32_t sedi_i2c_master_read_dma(IN sedi_i2c_t i2c_device, IN uint32_t addr, OUT context->tx_dma_dev = cmd_dma_dev; context->tx_dma_chan = cmd_dma_chan; - dw_i2c_irq_config(context->base, - BSETS_INTR_ERROR | SEDI_RBFVM(I2C, INTR_MASK, M_STOP_DET, DISABLED)); - - /* First write the command into register and clean cache */ - i2c->data_cmd = SEDI_RBFVM(I2C, DATA_CMD, CMD, READ) | - SEDI_RBFVM(I2C, DATA_CMD, RESTART, ENABLE); - sedi_core_clean_dcache_by_addr((uint32_t *)(&dma_cmd), sizeof(dma_cmd)); + i2c->intr_mask = BSETS_INTR_ERROR; - dw_i2c_dma_enable(context->base, 1); + /* RX: start read data transfer first */ + config_and_enable_dma_channel(i2c_device, context->rx_dma_dev, context->rx_dma_handshake, + context->rx_dma_chan, dw_i2c_dr_address(context->base), (uint32_t)data, + num, I2C_DMA_DIRECTION_RX); - /* Command is written for next read per request */ + /* TX: write command for next read per request */ config_and_enable_dma_channel(i2c_device, context->tx_dma_dev, context->tx_dma_handshake, - context->tx_dma_chan, (uint32_t)&dma_cmd, dw_i2c_dr_address(context->base) + 1, - num - 2, I2C_DMA_DIRECTION_RX_CMD); + context->tx_dma_chan, (uint32_t)dma_cmd, dw_i2c_dr_address(context->base) + 1, + num - 1, I2C_DMA_DIRECTION_TX); - /* data transfer */ - config_and_enable_dma_channel(i2c_device, context->rx_dma_dev, context->rx_dma_handshake, - context->rx_dma_chan, dw_i2c_dr_address(context->base), (uint32_t)data, num, - I2C_DMA_DIRECTION_RX); + dw_i2c_dma_enable(context->base, 1, 0); + i2c->enable = SEDI_RBFVM(I2C, ENABLE, ENABLE, ENABLED); return SEDI_DRIVER_OK; } @@ -1282,6 +1227,7 @@ void sedi_i2c_isr_handler(IN sedi_i2c_t i2c_device) i2c_isr_complete(i2c_device, false); return; } + /* For send with no STOP, while TX FIFO empty, ended */ if ((context->pending) && (context->buf_index == context->buf_size) && (SEDI_PREG_RBFV_IS_SET(I2C, INTR_STAT, R_TX_EMPTY, ACTIVE, &stat))) { diff --git a/bsp_sedi/drivers/ipc/sedi_ipc.c b/bsp_sedi/drivers/ipc/sedi_ipc.c index eeafd0e..9d9b014 100644 --- a/bsp_sedi/drivers/ipc/sedi_ipc.c +++ b/bsp_sedi/drivers/ipc/sedi_ipc.c @@ -23,16 +23,6 @@ #define IPC_REG_SB_LOCAL2CSE_MSG 0x40 #define IPC_REG_SB_CSE2LOCAL_DRBL_MIRROR 0x4 -#define IPC_REG_SB_LOCAL2CNVI_CSR 0x698 -#define IPC_REG_SB_LOCAL2CNVI_DRBL 0x690 -#define IPC_REG_SB_LOCAL2CNVI_MSG 0x7600 -#define IPC_REG_SB_CNVI2LOCAL_DRBL_MIRROR 0x694 - -#define IPC_REG_SB_LOCAL2BT_CSR 0x698 -#define IPC_REG_SB_LOCAL2BT_DRBL 0x690 -#define IPC_REG_SB_LOCAL2BT_MSG 0x7600 -#define IPC_REG_SB_BT2LOCAL_DRBL_MIRROR 0x694 - #ifdef SEDI_SB_SUPPORT #define SEDI_SIDEBAND_PMC SEDI_SIDEBAND_0 #define SEDI_SIDEBAND_CSE SEDI_SIDEBAND_0 diff --git a/bsp_sedi/drivers/rtc/sedi_rtc.c b/bsp_sedi/drivers/rtc/sedi_rtc.c index 56318c2..35a8bc4 100644 --- a/bsp_sedi/drivers/rtc/sedi_rtc.c +++ b/bsp_sedi/drivers/rtc/sedi_rtc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Intel Corporation + * Copyright (c) 2023 - 2024 Intel Corporation * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,14 +9,6 @@ /* driver version */ #define SEDI_RTC_DRIVER_VERSION SEDI_DRIVER_VERSION_MAJOR_MINOR(0, 1) -#ifndef SEDI_RTC_TICKS_PER_SECOND -#define SEDI_RTC_TICKS_PER_SECOND 32768 -#endif - -#ifndef USECS_PER_SEC -#define USECS_PER_SEC 1000000 -#endif - /* driver version */ static const sedi_driver_version_t driver_version = { SEDI_RTC_API_VERSION, SEDI_RTC_DRIVER_VERSION }; @@ -28,7 +20,7 @@ static const sedi_rtc_capabilities_t driver_capabilities = { .support_alarm = 0, static inline uint64_t sedi_rtc_to_us(uint64_t rtc_ticks) { - return (rtc_ticks * USECS_PER_SEC) / SEDI_RTC_TICKS_PER_SECOND; + return SEDI_RTC_TICKS2US(rtc_ticks); } sedi_driver_version_t sedi_rtc_get_version(void) diff --git a/bsp_sedi/drivers/spi/sedi_spi_dw_apb.c b/bsp_sedi/drivers/spi/sedi_spi_dw_apb.c index d6278f9..0f5ed13 100644 --- a/bsp_sedi/drivers/spi/sedi_spi_dw_apb.c +++ b/bsp_sedi/drivers/spi/sedi_spi_dw_apb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Intel Corporation + * Copyright (c) 2023 - 2024 Intel Corporation * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,8 +25,6 @@ #define SPI_FRAME_SIZE_1_BYTE (1) #define SPI_FRAME_SIZE_2_BYTES (2) #define SPI_RECEIVE_MODE_MAX_SIZE (65536) -#define SPI_DMA_MAX_SIZE (4096) -#define SPI_DMA_MAX_SIZE_SHIFT (12) #define SSI_IC_FREQ (sedi_pm_get_lbw_clock()) #define SPI_BITWIDTH_4BITS (SEDI_RBFV(SPI, CTRLR0, DFS, FRAME_04BITS) + 1) @@ -52,6 +50,8 @@ SEDI_RBF_DEFINE(SPI, SPI_CTRLR0, WAIT_CYCLES, 11, 5, RW, (uint32_t)0x0); SEDI_RBF_DEFINE(SPI, TXFTLR, TFT, 0, 16, RW, (uint32_t)0x0); #endif +#define SEDI_SPI_POLL_WAIT(_cond) SEDI_POLL_WAIT((_cond), 100) + struct spi_context { /* hardware config */ sedi_spi_regs_t *base; @@ -173,8 +173,7 @@ static inline void lld_spi_enable(sedi_spi_regs_t *spi, bool enable) SEDI_PREG_RBF_SET(SPI, SSIENR, SSI_EN, val, &spi->ssienr); - while (SEDI_PREG_RBFV_GET(SPI, SSIENR, SSI_EN, &spi->ssienr) != val) - ; + SEDI_SPI_POLL_WAIT(SEDI_PREG_RBFV_GET(SPI, SSIENR, SSI_EN, &spi->ssienr) != val); } static inline void lld_spi_dma_enable(sedi_spi_regs_t *spi, bool enable) @@ -807,7 +806,7 @@ static void callback_dma_transfer(const sedi_dma_t dma, const int chan, sedi_spi_t spi_device = (sedi_spi_t)param; struct spi_context *context = &spi_contexts[spi_device]; - uint32_t len = SPI_DMA_MAX_SIZE; + uint32_t len = SEDI_DMA_PERIPH_MAX_SIZE; /* release the dma resource */ sedi_dma_set_power(dma, chan, SEDI_POWER_OFF); @@ -835,9 +834,7 @@ static void callback_dma_transfer(const sedi_dma_t dma, const int chan, context->tx_data_len); } /* Waiting for TX FIFO empty */ - while (lld_spi_is_busy(context->base)) { - ; - } + SEDI_SPI_POLL_WAIT(lld_spi_is_busy(context->base)); } else if (chan == context->rx_channel) { context->dma_rx_finished = true; context->data_rx_idx = context->rx_data_len; @@ -870,7 +867,7 @@ static void callback_dma_transfer(const sedi_dma_t dma, const int chan, } /* According to different transfer mode, do different fill or receive */ if (context->transfer_mode == SEDI_RBFV(SPI, CTRLR0, TMOD, TX_ONLY)) { - context->data_tx += SPI_DMA_MAX_SIZE; + context->data_tx += SEDI_DMA_PERIPH_MAX_SIZE; context->dma_tx_finished = false; /* start dma first */ config_and_enable_dma_channel(spi_device, context->tx_dma, @@ -882,7 +879,7 @@ static void callback_dma_transfer(const sedi_dma_t dma, const int chan, lld_spi_dr_address(context->base), len); } else if (context->transfer_mode == SEDI_RBFV(SPI, CTRLR0, TMOD, RX_ONLY)) { - context->data_rx += SPI_DMA_MAX_SIZE; + context->data_rx += SEDI_DMA_PERIPH_MAX_SIZE; context->dma_rx_finished = false; /* Configure rx channel */ context->base->ctrlr1 = len / context->frame_size - 1; @@ -895,8 +892,8 @@ static void callback_dma_transfer(const sedi_dma_t dma, const int chan, (uint32_t)(context->data_rx), len, false); } else { - context->data_tx += SPI_DMA_MAX_SIZE; - context->data_rx += SPI_DMA_MAX_SIZE; + context->data_tx += SEDI_DMA_PERIPH_MAX_SIZE; + context->data_rx += SEDI_DMA_PERIPH_MAX_SIZE; context->dma_tx_finished = false; context->dma_rx_finished = false; /* Enable both channel to do transfer */ @@ -973,17 +970,17 @@ int32_t sedi_spi_dma_transfer(IN sedi_spi_t spi_device, IN uint32_t tx_dma, context->data_tx = (uint8_t *)data_out; context->data_rx = data_in; /* DMA BLOCK TS only 4096, for large data more than 4K, use multiple transfer */ - context->last_dma_counts = (num & (SPI_DMA_MAX_SIZE - 1)); + context->last_dma_counts = (num & (SEDI_DMA_PERIPH_MAX_SIZE - 1)); if (context->last_dma_counts == 0) { - context->dma_cycles = num >> SPI_DMA_MAX_SIZE_SHIFT; - context->last_dma_counts = SPI_DMA_MAX_SIZE; + context->dma_cycles = num >> SEDI_DMA_PERIPH_MAX_SIZE_SHIFT; + context->last_dma_counts = SEDI_DMA_PERIPH_MAX_SIZE; } else { - context->dma_cycles = (num >> SPI_DMA_MAX_SIZE_SHIFT) + 1; + context->dma_cycles = (num >> SEDI_DMA_PERIPH_MAX_SIZE_SHIFT) + 1; } context->dma_idx = context->dma_cycles; if (context->dma_cycles > 1) { - len = SPI_DMA_MAX_SIZE; + len = SEDI_DMA_PERIPH_MAX_SIZE; } #ifdef SPI_DW_2_0 /* Clear the bit field */ @@ -1175,8 +1172,7 @@ int32_t sedi_spi_poll_transfer(IN sedi_spi_t spi_device, IN uint8_t *data_out, } /* Waiting for SPI idle */ - while (lld_spi_is_busy(context->base)) - ; + SEDI_SPI_POLL_WAIT(lld_spi_is_busy(context->base)); lld_spi_enable(context->base, false); context->status.busy = 0U; @@ -1474,8 +1470,7 @@ void spi_isr(IN sedi_spi_t spi_device) end = true; event = SEDI_SPI_EVENT_COMPLETE; /* Wait for Data in FIFO send out while not continuous */ - while (lld_spi_is_busy(context->base)) - ; + SEDI_SPI_POLL_WAIT(lld_spi_is_busy(context->base)); /* If need to reverse rx buffer */ if ((context->transfer_mode != SEDI_RBFV(SPI, CTRLR0, TMOD, TX_ONLY)) && diff --git a/bsp_sedi/drivers/usart/sedi_dw_uart.c b/bsp_sedi/drivers/usart/sedi_dw_uart.c index 58464e5..ad3e7c6 100644 --- a/bsp_sedi/drivers/usart/sedi_dw_uart.c +++ b/bsp_sedi/drivers/usart/sedi_dw_uart.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Intel Corporation + * Copyright (c) 2023 - 2024 Intel Corporation * * SPDX-License-Identifier: BSD-3-Clause */ @@ -80,6 +80,8 @@ ((uint32_t)(((uint32_t)(de_to_re)) << SEDI_RBFO(UART, TAT, DE_to_RE) | \ ((uint32_t)(re_to_de)) << SEDI_RBFO(UART, TAT, RE_to_DE))) +#define SEDI_UART_POLL_WAIT(_cond) SEDI_POLL_WAIT_MUTE((_cond), 100) + /** * UART context to be saved between sleep/resume. * @@ -224,8 +226,7 @@ static void sedi_dma_event_cb(IN sedi_dma_t dma_device, IN int channel_id, IN in /* wait for transfer to complete as data may * still be in the fifo/ tx shift regs. */ - while (!(regs->lsr & SEDI_RBFVM(UART, LSR, TEMT, ENABLED))) { - } + SEDI_UART_POLL_WAIT(!(regs->lsr & SEDI_RBFVM(UART, LSR, TEMT, ENABLED))); if (xfer->callback) { xfer->callback(xfer->cb_param, SEDI_DRIVER_OK, line_err_status, xfer->len); @@ -263,9 +264,7 @@ static void uart_soft_rst_instance(sedi_uart_t uart) *rst_reg &= (~(1 << uart)); /* Wait till reset bit is cleared */ - while (*rst_reg & (1 << uart)) { - __asm volatile("nop"); - } + SEDI_UART_POLL_WAIT(*rst_reg & (1 << uart)); } #endif @@ -302,8 +301,7 @@ static void io_vec_write_callback(void *data, int error, uint32_t status, uint32 uart_write_transfer[uart] = &vec_write_ctxt[uart].xfer; /* Wait for last write transfer to finish completely. */ - while (!(regs->lsr & SEDI_RBFVM(UART, LSR, TEMT, ENABLED))) { - } + SEDI_UART_POLL_WAIT(!(regs->lsr & SEDI_RBFVM(UART, LSR, TEMT, ENABLED))); regs->iir_fcr = (SEDI_RBFM(UART, IIR, FIFOE) | SEDI_UART_FCR_TX_0_RX_1_2_THRESHOLD); @@ -685,6 +683,8 @@ int sedi_uart_get_status(IN sedi_uart_t uart, OUT uint32_t *const status) int sedi_uart_write(IN sedi_uart_t uart, IN uint8_t data) { + int ret; + DBG_CHECK(uart < SEDI_UART_NUM, SEDI_DRIVER_ERROR_PARAMETER); if (is_tx_disabled(uart)) { @@ -693,14 +693,15 @@ int sedi_uart_write(IN sedi_uart_t uart, IN uint8_t data) sedi_uart_regs_t *const regs = SEDI_UART[uart]; - while (!(regs->lsr & SEDI_RBFVM(UART, LSR, TEMT, ENABLED))) { + ret = SEDI_UART_POLL_WAIT(!(regs->lsr & SEDI_RBFVM(UART, LSR, TEMT, ENABLED))); + if (ret) { + return ret; } regs->rbr_thr_dll = data; /* Wait for transaction to complete. */ - while (!(regs->lsr & SEDI_RBFVM(UART, LSR, TEMT, ENABLED))) { - } - return SEDI_DRIVER_OK; + ret = SEDI_UART_POLL_WAIT(!(regs->lsr & SEDI_RBFVM(UART, LSR, TEMT, ENABLED))); + return ret; } int sedi_uart_read(IN sedi_uart_t uart, OUT uint8_t *const data, OUT uint32_t *status) @@ -782,15 +783,12 @@ int sedi_uart_write_buffer(IN sedi_uart_t uart, IN uint8_t *const data, IN uint3 * Because FCR_FIFOE and IER_PTIME are enabled, LSR_THRE * behaves as a TX FIFO full indicator. */ - while (regs->lsr & SEDI_RBFVM(UART, LSR, THRE, ENABLED)) { - } + SEDI_UART_POLL_WAIT(regs->lsr & SEDI_RBFVM(UART, LSR, THRE, ENABLED)); regs->rbr_thr_dll = *d; d++; } /* Wait for transaction to complete. */ - while (!(regs->lsr & SEDI_RBFVM(UART, LSR, TEMT, ENABLED))) { - } - return SEDI_DRIVER_OK; + return SEDI_UART_POLL_WAIT(!(regs->lsr & SEDI_RBFVM(UART, LSR, TEMT, ENABLED))); } int sedi_uart_read_buffer(IN sedi_uart_t uart, OUT uint8_t *const data, IN uint32_t req_len, @@ -1138,6 +1136,7 @@ int sedi_uart_9bit_enable(IN sedi_uart_t uart) int sedi_uart_9bit_send_address(IN sedi_uart_t uart, uint8_t address) { + int ret = SEDI_DRIVER_OK; DBG_CHECK(uart < SEDI_UART_NUM, SEDI_DRIVER_ERROR_PARAMETER); sedi_uart_regs_t *const regs = SEDI_UART[uart]; @@ -1152,22 +1151,22 @@ int sedi_uart_9bit_send_address(IN sedi_uart_t uart, uint8_t address) regs->rbr_thr_dll = (BIT(8) | (uint32_t)address); /* Wait for address to be sent. */ - while (!(regs->lsr & SEDI_RBFVM(UART, LSR, TEMT, ENABLED))) { - } + ret = SEDI_UART_POLL_WAIT(!(regs->lsr & + SEDI_RBFVM(UART, LSR, TEMT, ENABLED))); } else { regs->tar = address; /* Sending the address. */ regs->lcr_ext |= SEDI_RBFVM(UART, LCR_EXT, SEND_ADDR, 1); /* Wait for address to be sent. */ - while (regs->lcr_ext & SEDI_RBFVM(UART, LCR_EXT, SEND_ADDR, 1)) - ; + ret = SEDI_UART_POLL_WAIT(regs->lcr_ext & + SEDI_RBFVM(UART, LCR_EXT, SEND_ADDR, 1)); } } else { /* UART not configured for 9 bit operation. */ - return SEDI_DRIVER_ERROR; + ret = SEDI_DRIVER_ERROR; } - return SEDI_DRIVER_OK; + return ret; } int sedi_uart_9bit_get_config(IN sedi_uart_t uart, sedi_uart_9bit_config_t *cfg) @@ -1969,11 +1968,10 @@ static int sedi_uart_dma_io_polled(sedi_uart_t uart, sedi_dma_t dma_dev, uint32_ } /* wait for transfer to complete */ if (op == WRITE) { - while (!(regs->lsr & SEDI_RBFVM(UART, LSR, TEMT, ENABLED))) { - } + ret = SEDI_UART_POLL_WAIT(!(regs->lsr & SEDI_RBFVM(UART, LSR, TEMT, ENABLED))); } - return SEDI_DRIVER_OK; + return ret; } int sedi_uart_dma_write_async(IN sedi_uart_t uart, IN sedi_uart_dma_xfer_t *const xfer) diff --git a/bsp_sedi/include/driver/sedi_driver_common.h b/bsp_sedi/include/driver/sedi_driver_common.h index d7e7e74..9e0063f 100644 --- a/bsp_sedi/include/driver/sedi_driver_common.h +++ b/bsp_sedi/include/driver/sedi_driver_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Intel Corporation + * Copyright (c) 2023 - 2024 Intel Corporation * * SPDX-License-Identifier: BSD-3-Clause */ @@ -395,4 +395,42 @@ static inline void write64(uint32_t addr, IN uint64_t val) #define CLEAR_REG_BIT(address, cmask) \ write32(address, read32(address) & ~(cmask)) +uint64_t sedi_rtc_get_us(void); + +#define __SEDI_POLL_WAIT(_cond, _ms, _mute) \ + ({ \ + int ret = SEDI_DRIVER_OK; \ + uint64_t us_start; \ + us_start = sedi_rtc_get_us(); \ + while (_cond) { \ + uint64_t us_cur; \ + us_cur = sedi_rtc_get_us(); \ + if (((int64_t)(us_cur - us_start) > ((_ms) * 1000)) && (_cond)) { \ + if (!(_mute)) { \ + SEDI_LOG_ERR("SEDI poll %d ms timeout at %s : %d\n", (_ms),\ + __func__, __LINE__); \ + } \ + ret = SEDI_DRIVER_ERROR_TIMEOUT; \ + break; \ + } \ + } \ + ret; \ + }) + +/*! + * \function SEDI_POLL_WAIT + * \brief SEDI helper function to poll wait ((_cond) == true) at most (_ms) milliseconds. + * \return SEDI_DRIVER_OK or SEDI_DRIVER_ERROR_TIMEOUT + * \ingroup sedi_driver_common + */ +#define SEDI_POLL_WAIT(_cond, _ms) __SEDI_POLL_WAIT(_cond, _ms, false) + +/*! + * \function SEDI_POLL_WAIT_MUTE + * \brief SEDI helper function to poll wait ((_cond) == true) at most (_ms) milliseconds, and don't + * print error log when timeout happens to avoid potential recursive logging. + * \return SEDI_DRIVER_OK or SEDI_DRIVER_ERROR_TIMEOUT + * \ingroup sedi_driver_common + */ +#define SEDI_POLL_WAIT_MUTE(_cond, _ms) __SEDI_POLL_WAIT(_cond, _ms, true) #endif /* _SEDI_DRIVER_COMMON_H_*/ diff --git a/bsp_sedi/include/driver/sedi_driver_hpet.h b/bsp_sedi/include/driver/sedi_driver_hpet.h index b74cbd6..fc88ebb 100644 --- a/bsp_sedi/include/driver/sedi_driver_hpet.h +++ b/bsp_sedi/include/driver/sedi_driver_hpet.h @@ -119,6 +119,8 @@ void sedi_hpet_set_main_counter(uint64_t value); */ uint64_t sedi_hpet_get_main_counter(void); +uint64_t sedi_hpet_get_us(void); + /*! * \brief Enable the timer's interrupt. * \param[in] timer_id: Timer ID to enable interrupt. diff --git a/bsp_sedi/soc/intel_ish/include/sedi_soc.h b/bsp_sedi/soc/intel_ish/include/sedi_soc.h index c50b551..85dd382 100644 --- a/bsp_sedi/soc/intel_ish/include/sedi_soc.h +++ b/bsp_sedi/soc/intel_ish/include/sedi_soc.h @@ -22,7 +22,10 @@ #define ISH_CONFIG_HBW_CLK_DIVIDER (1) #endif -#define SEDI_RTC_TICKS_PER_SECOND (32768 / SEDI_SOC_CLK_DIVISOR) +#define SEDI_RTC_BASE_FREQ (32768) +#define SEDI_RTC_TICKS_PER_SECOND (SEDI_RTC_BASE_FREQ / SEDI_SOC_CLK_DIVISOR) +#define SEDI_RTC_TICKS2US(ticks) (ticks * 1000000 * SEDI_SOC_CLK_DIVISOR \ + / SEDI_RTC_BASE_FREQ) #define SEDI_MHZ_TO_HZ(mhz) ((mhz) * 1000000) diff --git a/bsp_sedi/soc/intel_ish/include/sedi_soc_regs.h b/bsp_sedi/soc/intel_ish/include/sedi_soc_regs.h index a9c1f60..d6bec90 100644 --- a/bsp_sedi/soc/intel_ish/include/sedi_soc_regs.h +++ b/bsp_sedi/soc/intel_ish/include/sedi_soc_regs.h @@ -40,6 +40,10 @@ typedef enum { SEDI_IREG_BASE_DEFINE(DMA, 0, 0x10100000); +/**DMA block TS**/ +#define SEDI_DMA_PERIPH_MAX_SIZE 4096 +#define SEDI_DMA_PERIPH_MAX_SIZE_SHIFT 12 + /****** i2c *****/ /*! * \struct sedi_i2c diff --git a/bsp_sedi/soc/intel_ish/sedi_soc.c b/bsp_sedi/soc/intel_ish/sedi_soc.c index 5604bb7..3751c59 100644 --- a/bsp_sedi/soc/intel_ish/sedi_soc.c +++ b/bsp_sedi/soc/intel_ish/sedi_soc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Intel Corporation + * Copyright (c) 2023 - 2024 Intel Corporation * * SPDX-License-Identifier: BSD-3-Clause */ @@ -43,17 +43,14 @@ void PM_VNN_DRIVER_REQ(vnn_id_t vnn_id) { unsigned int key = sedi_core_irq_lock(); - if (vnn_req_counter[vnn_id] != 0) { - goto out; - } + if (!vnn_req_counter[vnn_id]) + write32(PMU_VNN_REQ_31_0, BIT(vnn_id)); + ++vnn_req_counter[vnn_id]; + + sedi_core_irq_unlock(key); - SEDI_ASSERT((read32(PMU_VNN_REQ_31_0) & BIT(vnn_id)) == 0); - write32(PMU_VNN_REQ_31_0, BIT(vnn_id)); while (!(read32(PMU_VNN_REQ_ACK) & PMU_VNN_REQ_ACK_STS)) ; -out: - vnn_req_counter[vnn_id]++; - sedi_core_irq_unlock(key); } void PM_VNN_DRIVER_DEREQ(vnn_id_t vnn_id)