Merge "msm: ipa4: support coalescing pipe suspend"

This commit is contained in:
qctecmdr 2019-09-16 10:53:56 -07:00 • committed by Gerrit - the friendly Code Review server
commit 7ce4f7771d
7 changed files with 341 additions and 126 deletions

View file

@ -3719,7 +3719,7 @@ int gsi_config_channel_mode(unsigned long chan_hdl, enum gsi_chan_mode mode)
curr = GSI_CHAN_MODE_CALLBACK;
if (mode == curr) {
GSIERR("already in requested mode %u chan_hdl=%lu\n",
GSIDBG("already in requested mode %u chan_hdl=%lu\n",
curr, chan_hdl);
return -GSI_STATUS_UNSUPPORTED_OP;
}
@ -3730,7 +3730,7 @@ int gsi_config_channel_mode(unsigned long chan_hdl, enum gsi_chan_mode mode)
gsi_writel(1 << ctx->evtr->id, gsi_ctx->base +
GSI_EE_n_CNTXT_SRC_IEOB_IRQ_CLR_OFFS(gsi_ctx->per.ee));
atomic_set(&ctx->poll_mode, mode);
if (ctx->props.prot == GSI_CHAN_PROT_GCI)
if ((ctx->props.prot == GSI_CHAN_PROT_GCI) && ctx->evtr->chan)
atomic_set(&ctx->evtr->chan->poll_mode, mode);
GSIDBG("set gsi_ctx evtr_id %d to %d mode\n",
ctx->evtr->id, mode);
@ -3740,7 +3740,7 @@ int gsi_config_channel_mode(unsigned long chan_hdl, enum gsi_chan_mode mode)
if (curr == GSI_CHAN_MODE_POLL &&
mode == GSI_CHAN_MODE_CALLBACK) {
atomic_set(&ctx->poll_mode, mode);
if (ctx->props.prot == GSI_CHAN_PROT_GCI)
if ((ctx->props.prot == GSI_CHAN_PROT_GCI) && ctx->evtr->chan)
atomic_set(&ctx->evtr->chan->poll_mode, mode);
__gsi_config_ieob_irq(gsi_ctx->per.ee, 1 << ctx->evtr->id, ~0);
GSIDBG("set gsi_ctx evtr_id %d to %d mode\n",

View file

@ -54,6 +54,8 @@
#include "ipa_trace.h"
#include "ipa_odl.h"
#define IPA_SUSPEND_BUSY_TIMEOUT (msecs_to_jiffies(10))
/*
* The following for adding code (ie. for EMULATION) not found on x86.
*/
@ -117,7 +119,7 @@ static void ipa3_load_ipa_fw(struct work_struct *work);
static DECLARE_WORK(ipa3_fw_loading_work, ipa3_load_ipa_fw);
static void ipa_dec_clients_disable_clks_on_wq(struct work_struct *work);
static DECLARE_WORK(ipa_dec_clients_disable_clks_on_wq_work,
static DECLARE_DELAYED_WORK(ipa_dec_clients_disable_clks_on_wq_work,
ipa_dec_clients_disable_clks_on_wq);
static int ipa3_ioctl_add_rt_rule_v2(unsigned long arg);
@ -4815,8 +4817,16 @@ static void __ipa3_dec_client_disable_clks(void)
ret = atomic_sub_return(1, &ipa3_ctx->ipa3_active_clients.cnt);
if (ret > 0)
goto unlock_mutex;
ipa3_suspend_apps_pipes(true);
ipa3_disable_clks();
ret = ipa3_suspend_apps_pipes(true);
if (ret) {
/* HW is busy, retry after some time */
atomic_inc(&ipa3_ctx->ipa3_active_clients.cnt);
queue_delayed_work(ipa3_ctx->power_mgmt_wq,
&ipa_dec_clients_disable_clks_on_wq_work,
IPA_SUSPEND_BUSY_TIMEOUT);
} else {
ipa3_disable_clks();
}
unlock_mutex:
mutex_unlock(&ipa3_ctx->ipa3_active_clients.mutex);
@ -4869,8 +4879,8 @@ void ipa3_dec_client_disable_clks_no_block(
}
/* seems like this is the only client holding the clocks */
queue_work(ipa3_ctx->power_mgmt_wq,
&ipa_dec_clients_disable_clks_on_wq_work);
queue_delayed_work(ipa3_ctx->power_mgmt_wq,
&ipa_dec_clients_disable_clks_on_wq_work, 0);
}
/**

View file

@ -2915,7 +2915,7 @@ int ipa3_create_wdi_mapping(u32 num_buffers, struct ipa_wdi_buffer_info *info);
int ipa3_set_flt_tuple_mask(int pipe_idx, struct ipahal_reg_hash_tuple *tuple);
int ipa3_set_rt_tuple_mask(int tbl_idx, struct ipahal_reg_hash_tuple *tuple);
void ipa3_set_resorce_groups_min_max_limits(void);
void ipa3_suspend_apps_pipes(bool suspend);
int ipa3_suspend_apps_pipes(bool suspend);
int ipa3_flt_read_tbl_from_hw(u32 pipe_idx,
enum ipa_ip_type ip_type,
bool hashable,

View file

@ -7484,12 +7484,10 @@ void ipa3_set_resorce_groups_min_max_limits(void)
IPADBG("EXIT\n");
}
static void ipa3_gsi_poll_after_suspend(struct ipa3_ep_context *ep)
static bool ipa3_gsi_channel_is_quite(struct ipa3_ep_context *ep)
{
bool empty;
IPADBG("switch ch %ld to poll\n", ep->gsi_chan_hdl);
gsi_config_channel_mode(ep->gsi_chan_hdl, GSI_CHAN_MODE_POLL);
gsi_is_channel_empty(ep->gsi_chan_hdl, &empty);
if (!empty) {
IPADBG("ch %ld not empty\n", ep->gsi_chan_hdl);
@ -7498,6 +7496,7 @@ static void ipa3_gsi_poll_after_suspend(struct ipa3_ep_context *ep)
if (!atomic_read(&ep->sys->curr_polling_state))
__ipa_gsi_irq_rx_scedule_poll(ep->sys);
}
return empty;
}
static int __ipa3_stop_gsi_channel(u32 clnt_hdl)
@ -7623,141 +7622,167 @@ int ipa3_stop_gsi_channel(u32 clnt_hdl)
return res;
}
void ipa3_suspend_apps_pipes(bool suspend)
static int _ipa_suspend_resume_pipe(enum ipa_client_type client, bool suspend)
{
struct ipa_ep_cfg_ctrl cfg;
int ipa_ep_idx;
struct ipa3_ep_context *ep;
int res;
memset(&cfg, 0, sizeof(cfg));
cfg.ipa_ep_suspend = suspend;
if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) {
IPAERR("not supported\n");
return -EPERM;
}
ipa_ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_LAN_CONS);
ipa_ep_idx = ipa3_get_ep_mapping(client);
if (ipa_ep_idx < 0) {
IPAERR("IPA client mapping failed\n");
IPADBG("client %d not configured\n", client);
return 0;
}
ep = &ipa3_ctx->ep[ipa_ep_idx];
if (!ep->valid)
return 0;
IPADBG("%s pipe %d\n", suspend ? "suspend" : "unsuspend", ipa_ep_idx);
/*
* move the channel to callback mode.
* This needs to happen before starting the channel to make
* sure we don't loose any interrupt
*/
if (!suspend && !atomic_read(&ep->sys->curr_polling_state) &&
!IPA_CLIENT_IS_APPS_PROD(client))
gsi_config_channel_mode(ep->gsi_chan_hdl,
GSI_CHAN_MODE_CALLBACK);
if (suspend) {
res = __ipa3_stop_gsi_channel(ipa_ep_idx);
if (res) {
IPAERR("failed to stop LAN channel\n");
ipa_assert();
}
} else {
res = gsi_start_channel(ep->gsi_chan_hdl);
if (res) {
IPAERR("failed to start LAN channel\n");
ipa_assert();
}
}
/* Apps prod pipes use common event ring so cannot configure mode*/
if (IPA_CLIENT_IS_APPS_PROD(client))
return 0;
if (suspend) {
IPADBG("switch ch %ld to poll\n", ep->gsi_chan_hdl);
gsi_config_channel_mode(ep->gsi_chan_hdl, GSI_CHAN_MODE_POLL);
if (!ipa3_gsi_channel_is_quite(ep))
return -EAGAIN;
} else if (!atomic_read(&ep->sys->curr_polling_state)) {
IPADBG("switch ch %ld to callback\n", ep->gsi_chan_hdl);
gsi_config_channel_mode(ep->gsi_chan_hdl,
GSI_CHAN_MODE_CALLBACK);
}
return 0;
}
void ipa3_force_close_coal(void)
{
struct ipahal_imm_cmd_pyld *cmd_pyld = NULL;
struct ipahal_imm_cmd_register_write reg_write_cmd = { 0 };
struct ipahal_reg_valmask valmask;
struct ipa3_desc desc;
int ep_idx;
ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_COAL_CONS);
if (ep_idx == IPA_EP_NOT_ALLOCATED || (!ipa3_ctx->ep[ep_idx].valid))
return;
reg_write_cmd.skip_pipeline_clear = false;
reg_write_cmd.pipeline_clear_options = IPAHAL_HPS_CLEAR;
reg_write_cmd.offset = ipahal_get_reg_ofst(IPA_AGGR_FORCE_CLOSE);
ipahal_get_aggr_force_close_valmask(ep_idx, &valmask);
reg_write_cmd.value = valmask.val;
reg_write_cmd.value_mask = valmask.mask;
cmd_pyld = ipahal_construct_imm_cmd(IPA_IMM_CMD_REGISTER_WRITE,
&reg_write_cmd, false);
if (!cmd_pyld) {
IPAERR("fail construct register_write imm cmd\n");
ipa_assert();
return;
}
ep = &ipa3_ctx->ep[ipa_ep_idx];
if (ep->valid) {
IPADBG("%s pipe %d\n", suspend ? "suspend" : "unsuspend",
ipa_ep_idx);
/*
* move the channel to callback mode.
* This needs to happen before starting the channel to make
* sure we don't loose any interrupt
*/
if (!suspend && !atomic_read(&ep->sys->curr_polling_state))
gsi_config_channel_mode(ep->gsi_chan_hdl,
GSI_CHAN_MODE_CALLBACK);
ipa3_init_imm_cmd_desc(&desc, cmd_pyld);
if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) {
if (suspend) {
res = __ipa3_stop_gsi_channel(ipa_ep_idx);
if (res) {
IPAERR("failed to stop LAN channel\n");
ipa_assert();
}
} else {
res = gsi_start_channel(ep->gsi_chan_hdl);
if (res) {
IPAERR("failed to start LAN channel\n");
ipa_assert();
}
}
} else {
ipa3_cfg_ep_ctrl(ipa_ep_idx, &cfg);
IPADBG("Sending 1 descriptor for coal force close\n");
if (ipa3_send_cmd_timeout(1, &desc,
IPA_DMA_TASK_FOR_GSI_TIMEOUT_MSEC)) {
IPAERR("ipa3_send_cmd failed\n");
ipa_assert();
}
ipahal_destroy_imm_cmd(cmd_pyld);
}
int ipa3_suspend_apps_pipes(bool suspend)
{
int res;
enum ipa_client_type client;
if (suspend)
ipa3_force_close_coal();
for (client = 0; client < IPA_CLIENT_MAX; client++) {
if (IPA_CLIENT_IS_APPS_CONS(client)) {
res = _ipa_suspend_resume_pipe(client, suspend);
if (res)
goto undo_cons;
}
if (suspend)
ipa3_gsi_poll_after_suspend(ep);
}
ipa_ep_idx = ipa_get_ep_mapping(IPA_CLIENT_APPS_WAN_CONS);
/* Considering the case for SSR. */
if (ipa_ep_idx == -1) {
IPADBG("Invalid mapping for IPA_CLIENT_APPS_WAN_CONS\n");
return;
}
ep = &ipa3_ctx->ep[ipa_ep_idx];
if (ep->valid) {
IPADBG("%s pipe %d\n", suspend ? "suspend" : "unsuspend",
ipa_ep_idx);
/*
* move the channel to callback mode.
* This needs to happen before starting the channel to make
* sure we don't loose any interrupt
*/
if (!suspend && !atomic_read(&ep->sys->curr_polling_state))
gsi_config_channel_mode(ep->gsi_chan_hdl,
GSI_CHAN_MODE_CALLBACK);
if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) {
if (suspend) {
res = __ipa3_stop_gsi_channel(ipa_ep_idx);
if (res) {
IPAERR("failed to stop WAN channel\n");
ipa_assert();
}
} else if (!atomic_read(&ipa3_ctx->is_ssr)) {
/* If SSR was alreday started not required to
* start WAN channel,Because in SSR will stop
* channel and reset the channel.
*/
res = gsi_start_channel(ep->gsi_chan_hdl);
if (res) {
IPAERR("failed to start WAN channel\n");
ipa_assert();
}
}
} else {
ipa3_cfg_ep_ctrl(ipa_ep_idx, &cfg);
if (suspend) {
struct ipahal_reg_tx_wrapper tx;
int ep_idx;
ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_COAL_CONS);
if (ep_idx == IPA_EP_NOT_ALLOCATED ||
(!ipa3_ctx->ep[ep_idx].valid))
goto do_prod;
ipahal_read_reg_fields(IPA_STATE_TX_WRAPPER, &tx);
if (tx.coal_slave_open_frame != 0) {
IPADBG("COAL frame is open 0x%x\n",
tx.coal_slave_open_frame);
goto undo_cons;
}
usleep_range(IPA_TAG_SLEEP_MIN_USEC, IPA_TAG_SLEEP_MAX_USEC);
res = ipahal_read_reg_n(IPA_SUSPEND_IRQ_INFO_EE_n,
ipa3_ctx->ee);
if (res) {
IPADBG("suspend irq is pending 0x%x\n", res);
goto undo_cons;
}
}
do_prod:
for (client = 0; client < IPA_CLIENT_MAX; client++) {
if (IPA_CLIENT_IS_APPS_PROD(client)) {
res = _ipa_suspend_resume_pipe(client, suspend);
if (res)
goto undo_prod;
}
if (suspend)
ipa3_gsi_poll_after_suspend(ep);
}
ipa_ep_idx = ipa_get_ep_mapping(IPA_CLIENT_ODL_DPL_CONS);
/* Considering the case for SSR. */
if (ipa_ep_idx == -1) {
IPADBG("Invalid mapping for IPA_CLIENT_ODL_DPL_CONS\n");
return;
}
ep = &ipa3_ctx->ep[ipa_ep_idx];
if (ep->valid) {
IPADBG("%s pipe %d\n", suspend ? "suspend" : "unsuspend",
ipa_ep_idx);
/*
* move the channel to callback mode.
* This needs to happen before starting the channel to make
* sure we don't loose any interrupt
*/
if (!suspend && !atomic_read(&ep->sys->curr_polling_state))
gsi_config_channel_mode(ep->gsi_chan_hdl,
GSI_CHAN_MODE_CALLBACK);
if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) {
if (suspend) {
res = __ipa3_stop_gsi_channel(ipa_ep_idx);
if (res) {
IPAERR("failed to stop ODL channel\n");
ipa_assert();
}
} else if (!atomic_read(&ipa3_ctx->is_ssr)) {
/* If SSR was alreday started not required to
* start WAN channel,Because in SSR will stop
* channel and reset the channel.
*/
res = gsi_start_channel(ep->gsi_chan_hdl);
if (res) {
IPAERR("failed to start ODL channel\n");
ipa_assert();
}
}
} else {
ipa3_cfg_ep_ctrl(ipa_ep_idx, &cfg);
}
if (suspend)
ipa3_gsi_poll_after_suspend(ep);
}
return 0;
undo_prod:
for (client--; client < IPA_CLIENT_MAX && client >= 0; client--)
if (IPA_CLIENT_IS_APPS_PROD(client))
_ipa_suspend_resume_pipe(client, !suspend);
client = IPA_CLIENT_MAX;
undo_cons:
for (client--; client < IPA_CLIENT_MAX && client >= 0; client--)
if (IPA_CLIENT_IS_APPS_CONS(client))
_ipa_suspend_resume_pipe(client, !suspend);
return res;
}
int ipa3_allocate_dma_task_for_gsi(void)

View file

@ -1180,6 +1180,112 @@ static void ipareg_parse_comp_cfg_v4_5(
IPA_COMP_CFG_IPA_FULL_FLUSH_WAIT_RSC_CLOSURE_EN_BMSK_v4_5);
}
static void ipareg_parse_state_tx_wrapper_v4_5(
enum ipahal_reg_name reg, void *fields, u32 val)
{
struct ipahal_reg_tx_wrapper *tx =
(struct ipahal_reg_tx_wrapper *)fields;
tx->tx0_idle = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_TX0_IDLE_SHFT,
IPA_STATE_TX_WRAPPER_TX0_IDLE_BMSK);
tx->tx1_idle = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_TX1_IDLE_SHFT,
IPA_STATE_TX_WRAPPER_TX1_IDLE_BMSK);
tx->ipa_prod_ackmngr_db_empty = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_DB_EMPTY_SHFT,
IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_DB_EMPTY_BMSK);
tx->ipa_prod_ackmngr_state_idle = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_STATE_IDLE_SHFT,
IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_STATE_IDLE_BMSK);
tx->ipa_prod_prod_bresp_empty = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_IPA_PROD_BRESP_EMPTY_SHFT,
IPA_STATE_TX_WRAPPER_IPA_PROD_BRESP_EMPTY_BMSK);
tx->ipa_prod_prod_bresp_toggle_idle = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_IPA_PROD_BRESP_EMPTY_SHFT,
IPA_STATE_TX_WRAPPER_IPA_PROD_BRESP_EMPTY_BMSK);
tx->ipa_mbim_pkt_fms_idle = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_IPA_MBIM_PKT_FMS_IDLE_SHFT,
IPA_STATE_TX_WRAPPER_IPA_MBIM_PKT_FMS_IDLE_BMSK);
tx->mbim_direct_dma = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_MBIM_DIRECT_DMA_SHFT,
IPA_STATE_TX_WRAPPER_MBIM_DIRECT_DMA_BMSK);
tx->trnseq_force_valid = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_TRNSEQ_FORCE_VALID_SHFT,
IPA_STATE_TX_WRAPPER_TRNSEQ_FORCE_VALID_BMSK);
tx->pkt_drop_cnt_idle = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_PKT_DROP_CNT_IDLE_SHFT,
IPA_STATE_TX_WRAPPER_PKT_DROP_CNT_IDLE_BMSK);
tx->nlo_direct_dma = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_NLO_DIRECT_DMA_SHFT,
IPA_STATE_TX_WRAPPER_NLO_DIRECT_DMA_BMSK);
tx->coal_direct_dma = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_COAL_DIRECT_DMA_SHFT,
IPA_STATE_TX_WRAPPER_COAL_DIRECT_DMA_BMSK);
tx->coal_slave_idle = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_COAL_SLAVE_IDLE_SHFT,
IPA_STATE_TX_WRAPPER_COAL_SLAVE_IDLE_BMSK);
tx->coal_slave_ctx_idle = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_COAL_SLAVE_CTX_IDLE_SHFT,
IPA_STATE_TX_WRAPPER_COAL_SLAVE_CTX_IDLE_BMSK);
tx->coal_slave_open_frame = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_COAL_SLAVE_OPEN_FRAME_SHFT,
IPA_STATE_TX_WRAPPER_COAL_SLAVE_OPEN_FRAME_BMSK);
}
static void ipareg_parse_state_tx_wrapper_v4_7(
enum ipahal_reg_name reg, void *fields, u32 val)
{
struct ipahal_reg_tx_wrapper *tx =
(struct ipahal_reg_tx_wrapper *)fields;
tx->tx0_idle = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_TX0_IDLE_SHFT_v4_7,
IPA_STATE_TX_WRAPPER_TX0_IDLE_BMSK_v4_7);
tx->tx1_idle = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_TX1_IDLE_SHFT_v4_7,
IPA_STATE_TX_WRAPPER_TX1_IDLE_BMSK_v4_7);
tx->ipa_prod_ackmngr_db_empty = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_DB_EMPTY_SHFT_v4_7,
IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_DB_EMPTY_BMSK_v4_7);
tx->ipa_prod_ackmngr_state_idle = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_STATE_IDLE_SHFT_v4_7,
IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_STATE_IDLE_BMSK_v4_7);
tx->ipa_prod_prod_bresp_empty = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_IPA_PROD_BRESP_EMPTY_SHFT_v4_7,
IPA_STATE_TX_WRAPPER_IPA_PROD_BRESP_EMPTY_BMSK_v4_7);
tx->coal_slave_idle = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_COAL_SLAVE_IDLE_SHFT_v4_7,
IPA_STATE_TX_WRAPPER_COAL_SLAVE_IDLE_BMSK_v4_7);
tx->coal_slave_ctx_idle = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_COAL_SLAVE_CTX_IDLE_SHFT_v4_7,
IPA_STATE_TX_WRAPPER_COAL_SLAVE_CTX_IDLE_BMSK_v4_7);
tx->coal_slave_open_frame = IPA_GETFIELD_FROM_REG(val,
IPA_STATE_TX_WRAPPER_COAL_SLAVE_OPEN_FRAME_SHFT_v4_7,
IPA_STATE_TX_WRAPPER_COAL_SLAVE_OPEN_FRAME_BMSK_v4_7);
}
static void ipareg_construct_qcncm(
enum ipahal_reg_name reg, const void *fields, u32 *val)
{
@ -2968,6 +3074,9 @@ static struct ipahal_reg_obj ipahal_reg_objs[IPA_HW_MAX][IPA_REG_MAX] = {
[IPA_HW_v4_5][IPA_COMP_CFG] = {
ipareg_construct_comp_cfg_v4_5, ipareg_parse_comp_cfg_v4_5,
0x0000003C, 0, 0, 0, 0},
[IPA_HW_v4_5][IPA_STATE_TX_WRAPPER] = {
ipareg_construct_dummy, ipareg_parse_state_tx_wrapper_v4_5,
0x00000090, 0, 0, 0, 1 },
[IPA_HW_v4_5][IPA_STATE_FETCHER_MASK] = {
ipareg_construct_dummy, ipareg_parse_dummy,
-1, 0, 0, 0, 0},
@ -3167,6 +3276,9 @@ static struct ipahal_reg_obj ipahal_reg_objs[IPA_HW_MAX][IPA_REG_MAX] = {
[IPA_HW_v4_5][IPA_COAL_QMAP_CFG] = {
ipareg_construct_coal_qmap_cfg, ipareg_parse_coal_qmap_cfg,
0x00001810, 0, 0, 0, 0},
[IPA_HW_v4_7][IPA_STATE_TX_WRAPPER] = {
ipareg_construct_dummy, ipareg_parse_state_tx_wrapper_v4_7,
0x00000090, 0, 0, 0, 1 },
};
/*

View file

@ -379,6 +379,27 @@ struct ipahal_reg_comp_cfg {
bool enable;
};
/*
* struct ipahal_reg_tx_wrapper- IPA TX Wrapper state information
*/
struct ipahal_reg_tx_wrapper {
bool tx0_idle;
bool tx1_idle;
bool ipa_prod_ackmngr_db_empty;
bool ipa_prod_ackmngr_state_idle;
bool ipa_prod_prod_bresp_empty;
bool ipa_prod_prod_bresp_toggle_idle;
bool ipa_mbim_pkt_fms_idle;
u8 mbim_direct_dma;
bool trnseq_force_valid;
bool pkt_drop_cnt_idle;
u8 nlo_direct_dma;
u8 coal_direct_dma;
bool coal_slave_idle;
bool coal_slave_ctx_idle;
u8 coal_slave_open_frame;
};
/*
* struct ipa_hash_tuple - Hash tuple members for flt and rt
* the fields tells if to be masked or not

View file

@ -626,5 +626,52 @@ int ipahal_reg_init(enum ipa_hw_type ipa_hw_type);
#define IPA_COAL_QMAP_CFG_BMSK 0x1
#define IPA_COAL_QMAP_CFG_SHFT 0
#define IPA_STATE_TX_WRAPPER_COAL_SLAVE_OPEN_FRAME_BMSK 0xf0000000
#define IPA_STATE_TX_WRAPPER_COAL_SLAVE_OPEN_FRAME_SHFT 0x1f
#define IPA_STATE_TX_WRAPPER_COAL_SLAVE_CTX_IDLE_BMSK 0x100000
#define IPA_STATE_TX_WRAPPER_COAL_SLAVE_CTX_IDLE_SHFT 0x10
#define IPA_STATE_TX_WRAPPER_COAL_SLAVE_IDLE_BMSK 0x8000
#define IPA_STATE_TX_WRAPPER_COAL_SLAVE_IDLE_SHFT 0xf
#define IPA_STATE_TX_WRAPPER_COAL_DIRECT_DMA_BMSK 0x6000
#define IPA_STATE_TX_WRAPPER_COAL_DIRECT_DMA_SHFT 0xd
#define IPA_STATE_TX_WRAPPER_NLO_DIRECT_DMA_BMSK 0x1800
#define IPA_STATE_TX_WRAPPER_NLO_DIRECT_DMA_SHFT 0xb
#define IPA_STATE_TX_WRAPPER_PKT_DROP_CNT_IDLE_BMSK 0x400
#define IPA_STATE_TX_WRAPPER_PKT_DROP_CNT_IDLE_SHFT 0xa
#define IPA_STATE_TX_WRAPPER_TRNSEQ_FORCE_VALID_BMSK 0x200
#define IPA_STATE_TX_WRAPPER_TRNSEQ_FORCE_VALID_SHFT 0x9
#define IPA_STATE_TX_WRAPPER_MBIM_DIRECT_DMA_BMSK 0x180
#define IPA_STATE_TX_WRAPPER_MBIM_DIRECT_DMA_SHFT 0x7
#define IPA_STATE_TX_WRAPPER_IPA_MBIM_PKT_FMS_IDLE_BMSK 0x40
#define IPA_STATE_TX_WRAPPER_IPA_MBIM_PKT_FMS_IDLE_SHFT 0x6
#define IPA_STATE_TX_WRAPPER_IPA_PROD_BRESP_TOGGLE_IDLE_BMSK 0x20
#define IPA_STATE_TX_WRAPPER_IPA_PROD_BRESP_TOGGLE_IDLE_SHFT 0x5
#define IPA_STATE_TX_WRAPPER_IPA_PROD_BRESP_EMPTY_BMSK 0x10
#define IPA_STATE_TX_WRAPPER_IPA_PROD_BRESP_EMPTY_SHFT 0x4
#define IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_STATE_IDLE_BMSK 0x8
#define IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_STATE_IDLE_SHFT 0x3
#define IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_DB_EMPTY_BMSK 0x4
#define IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_DB_EMPTY_SHFT 0x2
#define IPA_STATE_TX_WRAPPER_TX1_IDLE_BMSK 0x2
#define IPA_STATE_TX_WRAPPER_TX1_IDLE_SHFT 0x1
#define IPA_STATE_TX_WRAPPER_TX0_IDLE_BMSK 0x1
#define IPA_STATE_TX_WRAPPER_TX0_IDLE_SHFT 0x0
#define IPA_STATE_TX_WRAPPER_COAL_SLAVE_OPEN_FRAME_BMSK_v4_7 0xf0000000
#define IPA_STATE_TX_WRAPPER_COAL_SLAVE_OPEN_FRAME_SHFT_v4_7 28
#define IPA_STATE_TX_WRAPPER_COAL_SLAVE_CTX_IDLE_BMSK_v4_7 0x80000
#define IPA_STATE_TX_WRAPPER_COAL_SLAVE_CTX_IDLE_SHFT_v4_7 19
#define IPA_STATE_TX_WRAPPER_COAL_SLAVE_IDLE_BMSK_v4_7 0x40000
#define IPA_STATE_TX_WRAPPER_COAL_SLAVE_IDLE_SHFT_v4_7 18
#define IPA_STATE_TX_WRAPPER_IPA_PROD_BRESP_EMPTY_BMSK_v4_7 0x10
#define IPA_STATE_TX_WRAPPER_IPA_PROD_BRESP_EMPTY_SHFT_v4_7 4
#define IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_STATE_IDLE_BMSK_v4_7 0x8
#define IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_STATE_IDLE_SHFT_v4_7 3
#define IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_DB_EMPTY_BMSK_v4_7 0x4
#define IPA_STATE_TX_WRAPPER_IPA_PROD_ACKMNGR_DB_EMPTY_SHFT_v4_7 2
#define IPA_STATE_TX_WRAPPER_TX1_IDLE_BMSK_v4_7 0x2
#define IPA_STATE_TX_WRAPPER_TX1_IDLE_SHFT_v4_7 1
#define IPA_STATE_TX_WRAPPER_TX0_IDLE_BMSK_v4_7 0x1
#define IPA_STATE_TX_WRAPPER_TX0_IDLE_SHFT_v4_7 0
#endif /* _IPAHAL_REG_I_H_ */