Merge "msm: ipa: Update IPA_SRAM_DIRECT_ACCESS_n for IPA4.5"

This commit is contained in:
qctecmdr Service 2018-08-07 10:57:09 -07:00 committed by Gerrit - the friendly Code Review server
commit fdcb7e4106
19 changed files with 697 additions and 86 deletions

View File

@ -57,7 +57,7 @@
(BAM_DMA_MAX_PKT_NUMBER * (sizeof(struct sps_iovec)))
#define TX_TIMEOUT (5 * HZ)
#define MIN_TX_ERROR_SLEEP_PERIOD 500
#define DEFAULT_AGGR_TIME_LIMIT 1
#define DEFAULT_AGGR_TIME_LIMIT 1000 /* 1ms */
#define DEFAULT_AGGR_PKT_LIMIT 0
#define RNDIS_IPA_ERROR(fmt, args...) \
@ -328,7 +328,7 @@ static struct ipa_ep_cfg ipa_to_usb_ep_cfg = {
.aggr = IPA_GENERIC,
.aggr_byte_limit = 4,
.aggr_time_limit = DEFAULT_AGGR_TIME_LIMIT,
.aggr_pkt_limit = DEFAULT_AGGR_PKT_LIMIT
.aggr_pkt_limit = DEFAULT_AGGR_PKT_LIMIT,
},
.deaggr = {
.deaggr_hdr_len = 0,

View File

@ -2649,18 +2649,18 @@ int _ipa_init_sram_v3(void)
unsigned long phys_addr;
IPADBG(
"ipa_wrapper_base(0x%08X) ipa_reg_base_ofst(0x%08X) IPA_SRAM_DIRECT_ACCESS_n(0x%08X) smem_restricted_bytes(0x%08X) smem_sz(0x%08X)\n",
"ipa_wrapper_base(0x%08X) ipa_reg_base_ofst(0x%08X) IPA_SW_AREA_RAM_DIRECT_ACCESS_n(0x%08X) smem_restricted_bytes(0x%08X) smem_sz(0x%08X)\n",
ipa3_ctx->ipa_wrapper_base,
ipa3_ctx->ctrl->ipa_reg_base_ofst,
ipahal_get_reg_n_ofst(
IPA_SRAM_DIRECT_ACCESS_n,
IPA_SW_AREA_RAM_DIRECT_ACCESS_n,
ipa3_ctx->smem_restricted_bytes / 4),
ipa3_ctx->smem_restricted_bytes,
ipa3_ctx->smem_sz);
phys_addr = ipa3_ctx->ipa_wrapper_base +
ipa3_ctx->ctrl->ipa_reg_base_ofst +
ipahal_get_reg_n_ofst(IPA_SRAM_DIRECT_ACCESS_n,
ipahal_get_reg_n_ofst(IPA_SW_AREA_RAM_DIRECT_ACCESS_n,
ipa3_ctx->smem_restricted_bytes / 4);
ipa_sram_mmio = ioremap(phys_addr, ipa3_ctx->smem_sz);
@ -4094,7 +4094,6 @@ void ipa3_suspend_handler(enum ipa_irq_type interrupt,
IPADBG("interrupt=%d, interrupt_data=%u\n",
interrupt, suspend_data);
memset(&holb_cfg, 0, sizeof(holb_cfg));
holb_cfg.tmr_val = 0;
for (i = 0; i < ipa3_ctx->ipa_num_pipes; i++, bmsk = bmsk << 1) {
if ((suspend_data & bmsk) && (ipa3_ctx->ep[i].valid)) {

View File

@ -21,7 +21,6 @@
*/
#define IPA_HOLB_TMR_EN 0x1
#define IPA_HOLB_TMR_DIS 0x0
#define IPA_HOLB_TMR_DEFAULT_VAL 0x1ff
#define IPA_POLL_AGGR_STATE_RETRIES_NUM 3
#define IPA_POLL_AGGR_STATE_SLEEP_MSEC 1

View File

@ -117,12 +117,18 @@ static ssize_t ipa3_read_gen_reg(struct file *file, char __user *ubuf,
"IPA_COMP_HW_VERSION=0x%x\n"
"IPA_ROUTE=0x%x\n"
"IPA_SHARED_MEM_RESTRICTED=0x%x\n"
"IPA_SHARED_MEM_SIZE=0x%x\n",
"IPA_SHARED_MEM_SIZE=0x%x\n"
"IPA_QTIME_TIMESTAMP_CFG=0x%x\n"
"IPA_TIMERS_PULSE_GRAN_CFG=0x%x\n"
"IPA_TIMERS_XO_CLK_DIV_CFG=0x%x\n",
ipahal_read_reg(IPA_VERSION),
ipahal_read_reg(IPA_COMP_HW_VERSION),
ipahal_read_reg(IPA_ROUTE),
smem_sz.shared_mem_baddr,
smem_sz.shared_mem_sz);
smem_sz.shared_mem_sz,
ipahal_read_reg(IPA_QTIME_TIMESTAMP_CFG),
ipahal_read_reg(IPA_TIMERS_PULSE_GRAN_CFG),
ipahal_read_reg(IPA_TIMERS_XO_CLK_DIV_CFG));
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();

View File

@ -244,9 +244,10 @@ int ipa3_dma_init(void)
ipa_dma_ctx_t = kzalloc(sizeof(*(ipa3_dma_ctx)), GFP_KERNEL);
if (!ipa_dma_ctx_t)
if (!ipa_dma_ctx_t) {
res = -ENOMEM;
goto init_unlock;
}
ipa_dma_ctx_t->ipa_dma_xfer_wrapper_cache =
kmem_cache_create("IPA DMA XFER WRAPPER",
@ -821,7 +822,7 @@ int ipa3_dma_async_memcpy(u64 dest, u64 src, int len,
ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_MEMCPY_DMA_ASYNC_PROD);
if (-1 == ep_idx) {
IPADMA_ERR("Client %u is not mapped\n",
IPA_CLIENT_MEMCPY_DMA_SYNC_PROD);
IPA_CLIENT_MEMCPY_DMA_ASYNC_PROD);
return -EFAULT;
}
prod_sys = ipa3_ctx->ep[ep_idx].sys;

View File

@ -33,7 +33,7 @@
/* 8K less 1 nominal MTU (1500 bytes) rounded to units of KB */
#define IPA_MTU 1500
#define IPA_GENERIC_AGGR_BYTE_LIMIT 6
#define IPA_GENERIC_AGGR_TIME_LIMIT 1
#define IPA_GENERIC_AGGR_TIME_LIMIT 500 /* 0.5msec */
#define IPA_GENERIC_AGGR_PKT_LIMIT 0
#define IPA_GENERIC_RX_BUFF_BASE_SZ 8192

View File

@ -1623,7 +1623,7 @@ int ipa3_flt_read_tbl_from_hw(u32 pipe_idx, enum ipa_ip_type ip_type,
/* map IPA SRAM */
ipa_sram_mmio = ioremap(ipa3_ctx->ipa_wrapper_base +
ipa3_ctx->ctrl->ipa_reg_base_ofst +
ipahal_get_reg_n_ofst(IPA_SRAM_DIRECT_ACCESS_n,
ipahal_get_reg_n_ofst(IPA_SW_AREA_RAM_DIRECT_ACCESS_n,
ipa3_ctx->smem_restricted_bytes / 4),
ipa3_ctx->smem_sz);
if (!ipa_sram_mmio) {

View File

@ -146,7 +146,7 @@ static int ipa3_nat_ipv6ct_mmap(struct file *filp, struct vm_area_struct *vma)
phys_addr = ipa3_ctx->ipa_wrapper_base +
ipa3_ctx->ctrl->ipa_reg_base_ofst +
ipahal_get_reg_n_ofst(IPA_SRAM_DIRECT_ACCESS_n,
ipahal_get_reg_n_ofst(IPA_SW_AREA_RAM_DIRECT_ACCESS_n,
dev->smem_offset);
if (remap_pfn_range(

View File

@ -1938,7 +1938,7 @@ int ipa3_rt_read_tbl_from_hw(u32 tbl_idx, enum ipa_ip_type ip_type,
/* map IPA SRAM */
ipa_sram_mmio = ioremap(ipa3_ctx->ipa_wrapper_base +
ipa3_ctx->ctrl->ipa_reg_base_ofst +
ipahal_get_reg_n_ofst(IPA_SRAM_DIRECT_ACCESS_n,
ipahal_get_reg_n_ofst(IPA_SW_AREA_RAM_DIRECT_ACCESS_n,
ipa3_ctx->smem_restricted_bytes / 4),
ipa3_ctx->smem_sz);
if (!ipa_sram_mmio) {

View File

@ -249,7 +249,8 @@ static void ipa3_log_evt_hdlr(void)
if (ipa3_ctx->uc_ctx.uc_event_top_ofst +
sizeof(struct IpaHwEventLogInfoData_t) >=
ipa3_ctx->ctrl->ipa_reg_base_ofst +
ipahal_get_reg_n_ofst(IPA_SRAM_DIRECT_ACCESS_n, 0) +
ipahal_get_reg_n_ofst(
IPA_SW_AREA_RAM_DIRECT_ACCESS_n, 0) +
ipa3_ctx->smem_sz) {
IPAERR("uc_top 0x%x outside SRAM\n",
ipa3_ctx->uc_ctx.uc_event_top_ofst);
@ -657,7 +658,7 @@ int ipa3_uc_interface_init(void)
phys_addr = ipa3_ctx->ipa_wrapper_base +
ipa3_ctx->ctrl->ipa_reg_base_ofst +
ipahal_get_reg_n_ofst(IPA_SRAM_DIRECT_ACCESS_n, 0);
ipahal_get_reg_n_ofst(IPA_SW_AREA_RAM_DIRECT_ACCESS_n, 0);
ipa3_ctx->uc_ctx.uc_sram_mmio = ioremap(phys_addr,
IPA_RAM_UC_SMEM_SIZE);
if (!ipa3_ctx->uc_ctx.uc_sram_mmio) {

View File

@ -556,7 +556,7 @@ static void ipa3_uc_mhi_event_log_info_hdlr(
if (ipa3_uc_mhi_ctx->mhi_uc_stats_ofst +
sizeof(struct IpaHwStatsMhiInfoData_t) >=
ipa3_ctx->ctrl->ipa_reg_base_ofst +
ipahal_get_reg_n_ofst(IPA_SRAM_DIRECT_ACCESS_n, 0) +
ipahal_get_reg_n_ofst(IPA_SW_AREA_RAM_DIRECT_ACCESS_n, 0) +
ipa3_ctx->smem_sz) {
IPAERR("uc_mhi_stats 0x%x outside SRAM\n",
ipa3_uc_mhi_ctx->mhi_uc_stats_ofst);

View File

@ -56,7 +56,7 @@ struct IpaHwEventLogInfoData_t *uc_event_top_mmio)
if (ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_ofst +
sizeof(struct Ipa3HwStatsNTNInfoData_t) >=
ipa3_ctx->ctrl->ipa_reg_base_ofst +
ipahal_get_reg_n_ofst(IPA_SRAM_DIRECT_ACCESS_n, 0) +
ipahal_get_reg_n_ofst(IPA_SW_AREA_RAM_DIRECT_ACCESS_n, 0) +
ipa3_ctx->smem_sz) {
IPAERR("uc_ntn_stats 0x%x outside SRAM\n",
ipa3_ctx->uc_ntn_ctx.ntn_uc_stats_ofst);

View File

@ -373,7 +373,7 @@ struct IpaHwEventLogInfoData_t *uc_event_top_mmio)
if (ipa3_ctx->uc_wdi_ctx.wdi_uc_stats_ofst +
sizeof(struct IpaHwStatsWDIInfoData_t) >=
ipa3_ctx->ctrl->ipa_reg_base_ofst +
ipahal_get_reg_n_ofst(IPA_SRAM_DIRECT_ACCESS_n, 0) +
ipahal_get_reg_n_ofst(IPA_SW_AREA_RAM_DIRECT_ACCESS_n, 0) +
ipa3_ctx->smem_sz) {
IPAERR("uc_wdi_stats 0x%x outside SRAM\n",
ipa3_ctx->uc_wdi_ctx.wdi_uc_stats_ofst);

View File

@ -82,9 +82,14 @@
/* In IPAv3 only endpoints 0-3 can be configured to deaggregation */
#define IPA_EP_SUPPORTS_DEAGGR(idx) ((idx) >= 0 && (idx) <= 3)
/* configure IPA spare register 1 in order to have correct IPA version
* set bits 0,2,3 and 4. see SpareBits documentation.xlsx
#define IPA_TAG_TIMER_TIMESTAMP_SHFT (14) /* ~0.8msec */
#define IPA_NAT_TIMER_TIMESTAMP_SHFT (24) /* ~0.8sec */
/*
* Units of time per a specific granularity
* The limitation based on H/W HOLB/AGGR time limit field width
*/
#define IPA_TIMER_SCALED_TIME_LIMIT 31
/* HPS, DPS sequencers Types*/
@ -3208,6 +3213,65 @@ static void ipa3_cfg_qsb(void)
ipahal_write_reg_fields(IPA_QSB_MAX_READS, &max_reads);
}
/* relevant starting IPA4.5 */
static void ipa_cfg_qtime(void)
{
struct ipahal_reg_qtime_timestamp_cfg ts_cfg;
struct ipahal_reg_timers_pulse_gran_cfg gran_cfg;
struct ipahal_reg_timers_xo_clk_div_cfg div_cfg;
u32 val;
/* Configure timestamp resolution */
memset(&ts_cfg, 0, sizeof(ts_cfg));
ts_cfg.dpl_timestamp_lsb = 0;
ts_cfg.dpl_timestamp_sel = false; /* DPL: use legacy 1ms resolution */
ts_cfg.tag_timestamp_lsb = IPA_TAG_TIMER_TIMESTAMP_SHFT;
ts_cfg.nat_timestamp_lsb = IPA_NAT_TIMER_TIMESTAMP_SHFT;
val = ipahal_read_reg(IPA_QTIME_TIMESTAMP_CFG);
IPADBG("qtime timestamp before cfg: 0x%x\n", val);
ipahal_write_reg_fields(IPA_QTIME_TIMESTAMP_CFG, &ts_cfg);
val = ipahal_read_reg(IPA_QTIME_TIMESTAMP_CFG);
IPADBG("qtime timestamp after cfg: 0x%x\n", val);
/* Configure timers pulse generators granularity */
memset(&gran_cfg, 0, sizeof(gran_cfg));
gran_cfg.gran_0 = IPA_TIMERS_TIME_GRAN_100_USEC;
gran_cfg.gran_1 = IPA_TIMERS_TIME_GRAN_1_MSEC;
gran_cfg.gran_2 = IPA_TIMERS_TIME_GRAN_10_USEC;
val = ipahal_read_reg(IPA_TIMERS_PULSE_GRAN_CFG);
IPADBG("timer pulse granularity before cfg: 0x%x\n", val);
ipahal_write_reg_fields(IPA_TIMERS_PULSE_GRAN_CFG, &gran_cfg);
val = ipahal_read_reg(IPA_TIMERS_PULSE_GRAN_CFG);
IPADBG("timer pulse granularity after cfg: 0x%x\n", val);
/* Configure timers XO Clock divider */
memset(&div_cfg, 0, sizeof(div_cfg));
ipahal_read_reg_fields(IPA_TIMERS_XO_CLK_DIV_CFG, &div_cfg);
IPADBG("timer XO clk divider before cfg: enabled=%d divider=%u\n",
div_cfg.enable, div_cfg.value);
/* Make sure divider is disabled */
if (div_cfg.enable) {
div_cfg.enable = false;
ipahal_write_reg_fields(IPA_TIMERS_XO_CLK_DIV_CFG, &div_cfg);
}
/* At emulation systems XO clock is lower than on real target.
* (e.g. 19.2Mhz compared to 96Khz)
* Use lowest possible divider.
*/
if (ipa3_ctx->ipa3_hw_mode == IPA_HW_MODE_VIRTUAL ||
ipa3_ctx->ipa3_hw_mode == IPA_HW_MODE_EMULATION) {
div_cfg.value = 0;
}
div_cfg.enable = true; /* Enable the divider */
ipahal_write_reg_fields(IPA_TIMERS_XO_CLK_DIV_CFG, &div_cfg);
ipahal_read_reg_fields(IPA_TIMERS_XO_CLK_DIV_CFG, &div_cfg);
IPADBG("timer XO clk divider after cfg: enabled=%d divider=%u\n",
div_cfg.enable, div_cfg.value);
}
/**
* ipa3_init_hw() - initialize HW
*
@ -3267,9 +3331,13 @@ int ipa3_init_hw(void)
ipa3_cfg_qsb();
/* set granularity for 0.5 msec*/
cnt_cfg.aggr_granularity = GRAN_VALUE_500_USEC;
ipahal_write_reg_fields(IPA_COUNTER_CFG, &cnt_cfg);
if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) {
/* set aggr granularity for 0.5 msec*/
cnt_cfg.aggr_granularity = GRAN_VALUE_500_USEC;
ipahal_write_reg_fields(IPA_COUNTER_CFG, &cnt_cfg);
} else {
ipa_cfg_qtime();
}
ipa_comp_cfg();
@ -4210,6 +4278,89 @@ const char *ipa3_get_aggr_type_str(enum ipa_aggr_type aggr_type)
return "undefined";
}
static u32 ipa3_time_gran_usec_step(enum ipa_timers_time_gran_type gran)
{
switch (gran) {
case IPA_TIMERS_TIME_GRAN_10_USEC: return 10;
case IPA_TIMERS_TIME_GRAN_20_USEC: return 20;
case IPA_TIMERS_TIME_GRAN_50_USEC: return 50;
case IPA_TIMERS_TIME_GRAN_100_USEC: return 100;
case IPA_TIMERS_TIME_GRAN_1_MSEC: return 1000;
case IPA_TIMERS_TIME_GRAN_10_MSEC: return 10000;
case IPA_TIMERS_TIME_GRAN_100_MSEC: return 100000;
case IPA_TIMERS_TIME_GRAN_NEAR_HALF_SEC: return 655350;
default:
IPAERR("Invalid granularity time unit %d\n", gran);
ipa_assert();
break;
};
return 100;
}
/*
* ipa3_process_timer_cfg() - Check and produce timer config
*
* Relevant for IPA 4.5 and above
*
* Assumes clocks are voted
*/
static int ipa3_process_timer_cfg(u32 time_us,
u8 *pulse_gen, u8 *time_units)
{
struct ipahal_reg_timers_pulse_gran_cfg gran_cfg;
u32 gran0_step, gran1_step;
IPADBG("time in usec=%u\n", time_us);
if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_5) {
IPAERR("Invalid IPA version %d\n", ipa3_ctx->ipa_hw_type);
return -EPERM;
}
if (!time_us) {
*pulse_gen = 0;
*time_units = 0;
return 0;
}
ipahal_read_reg_fields(IPA_TIMERS_PULSE_GRAN_CFG, &gran_cfg);
gran0_step = ipa3_time_gran_usec_step(gran_cfg.gran_0);
gran1_step = ipa3_time_gran_usec_step(gran_cfg.gran_1);
/* gran_2 is not used by AP */
IPADBG("gran0 usec step=%u gran1 usec step=%u\n",
gran0_step, gran1_step);
/* Lets try pulse generator #0 granularity */
if (!(time_us % gran0_step)) {
if ((time_us / gran0_step) <= IPA_TIMER_SCALED_TIME_LIMIT) {
*pulse_gen = 0;
*time_units = time_us / gran0_step;
IPADBG("Matched: generator=0, units=%u\n",
*time_units);
return 0;
}
IPADBG("gran0 cannot be used due to range limit\n");
}
/* Lets try pulse generator #1 granularity */
if (!(time_us % gran1_step)) {
if ((time_us / gran1_step) <= IPA_TIMER_SCALED_TIME_LIMIT) {
*pulse_gen = 1;
*time_units = time_us / gran1_step;
IPADBG("Matched: generator=1, units=%u\n",
*time_units);
return 0;
}
IPADBG("gran1 cannot be used due to range limit\n");
}
IPAERR("Cannot match requested time to configured granularities\n");
return -EPERM;
}
/**
* ipa3_cfg_ep_aggr() - IPA end-point aggregation configuration
* @clnt_hdl: [in] opaque client handle assigned by IPA to client
@ -4221,6 +4372,8 @@ const char *ipa3_get_aggr_type_str(enum ipa_aggr_type aggr_type)
*/
int ipa3_cfg_ep_aggr(u32 clnt_hdl, const struct ipa_ep_cfg_aggr *ep_aggr)
{
int res = 0;
if (clnt_hdl >= ipa3_ctx->ipa_num_pipes ||
ipa3_ctx->ep[clnt_hdl].valid == 0 || ep_aggr == NULL) {
IPAERR("bad parm, clnt_hdl = %d , ep_valid = %d\n",
@ -4252,11 +4405,41 @@ int ipa3_cfg_ep_aggr(u32 clnt_hdl, const struct ipa_ep_cfg_aggr *ep_aggr)
IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(clnt_hdl));
ipahal_write_reg_n_fields(IPA_ENDP_INIT_AGGR_n, clnt_hdl, ep_aggr);
if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) {
res = ipa3_process_timer_cfg(ep_aggr->aggr_time_limit,
&ipa3_ctx->ep[clnt_hdl].cfg.aggr.pulse_generator,
&ipa3_ctx->ep[clnt_hdl].cfg.aggr.scaled_time);
if (res) {
IPAERR("failed to process AGGR timer tmr=%u\n",
ep_aggr->aggr_time_limit);
ipa_assert();
res = -EINVAL;
goto complete;
}
} else {
/*
* Global aggregation granularity is 0.5msec.
* So if H/W programmed with 1msec, it will be
* 0.5msec defacto.
* So finest granularity is 0.5msec
*/
if (ep_aggr->aggr_time_limit % 500) {
IPAERR("given time limit %u is not in 0.5msec\n",
ep_aggr->aggr_time_limit);
WARN_ON(1);
res = -EINVAL;
goto complete;
}
/* Due to described above global granularity */
ipa3_ctx->ep[clnt_hdl].cfg.aggr.aggr_time_limit *= 2;
}
ipahal_write_reg_n_fields(IPA_ENDP_INIT_AGGR_n, clnt_hdl,
&ipa3_ctx->ep[clnt_hdl].cfg.aggr);
complete:
IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl));
return 0;
return res;
}
/**
@ -4382,21 +4565,33 @@ int ipa3_cfg_ep_holb(u32 clnt_hdl, const struct ipa_ep_cfg_holb *ep_holb)
ipahal_write_reg_n_fields(IPA_ENDP_INIT_HOL_BLOCK_EN_n, clnt_hdl,
ep_holb);
/* Configure timer */
if (ipa3_ctx->ipa_hw_type == IPA_HW_v4_2) {
ipa3_cal_ep_holb_scale_base_val(ep_holb->tmr_val,
&ipa3_ctx->ep[clnt_hdl].holb);
ipahal_write_reg_n_fields(IPA_ENDP_INIT_HOL_BLOCK_TIMER_n,
clnt_hdl, &ipa3_ctx->ep[clnt_hdl].holb);
} else {
ipahal_write_reg_n_fields(IPA_ENDP_INIT_HOL_BLOCK_TIMER_n,
clnt_hdl, ep_holb);
goto success;
}
if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5) {
int res;
res = ipa3_process_timer_cfg(ep_holb->tmr_val * 1000,
&ipa3_ctx->ep[clnt_hdl].holb.pulse_generator,
&ipa3_ctx->ep[clnt_hdl].holb.scaled_time);
if (res) {
IPAERR("failed to process HOLB timer tmr=%u\n",
ep_holb->tmr_val);
ipa_assert();
return res;
}
}
success:
ipahal_write_reg_n_fields(IPA_ENDP_INIT_HOL_BLOCK_TIMER_n,
clnt_hdl, &ipa3_ctx->ep[clnt_hdl].holb);
IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl));
IPADBG("cfg holb %u ep=%d tmr=%d\n", ep_holb->en, clnt_hdl,
ep_holb->tmr_val);
ep_holb->tmr_val);
return 0;
}

View File

@ -35,6 +35,7 @@ static const char *ipareg_name_to_str[IPA_REG_MAX] = {
__stringify(IPA_ENABLED_PIPES),
__stringify(IPA_VERSION),
__stringify(IPA_TAG_TIMER),
__stringify(IPA_NAT_TIMER),
__stringify(IPA_COMP_HW_VERSION),
__stringify(IPA_COMP_CFG),
__stringify(IPA_STATE_TX_WRAPPER),
@ -83,7 +84,7 @@ static const char *ipareg_name_to_str[IPA_REG_MAX] = {
__stringify(IPA_ENDP_INIT_PROD_CFG_n),
__stringify(IPA_ENDP_INIT_RSRC_GRP_n),
__stringify(IPA_SHARED_MEM_SIZE),
__stringify(IPA_SRAM_DIRECT_ACCESS_n),
__stringify(IPA_SW_AREA_RAM_DIRECT_ACCESS_n),
__stringify(IPA_DEBUG_CNT_CTRL_n),
__stringify(IPA_UC_MAILBOX_m_n),
__stringify(IPA_FILT_ROUT_HASH_FLUSH),
@ -116,6 +117,9 @@ static const char *ipareg_name_to_str[IPA_REG_MAX] = {
__stringify(IPA_HPS_SEQUENCER_FIRST),
__stringify(IPA_HPS_SEQUENCER_LAST),
__stringify(IPA_CLKON_CFG),
__stringify(IPA_QTIME_TIMESTAMP_CFG),
__stringify(IPA_TIMERS_PULSE_GRAN_CFG),
__stringify(IPA_TIMERS_XO_CLK_DIV_CFG),
__stringify(IPA_STAT_QUOTA_BASE_n),
__stringify(IPA_STAT_QUOTA_MASK_n),
__stringify(IPA_STAT_TETHERING_BASE_n),
@ -799,6 +803,155 @@ static void ipareg_parse_clkon_cfg_v4_5(
IPA_CLKON_CFG_CGC_OPEN_DPL_FIFO_BMSK_V4_5);
}
static void ipareg_construct_qtime_timestamp_cfg(
enum ipahal_reg_name reg, const void *fields, u32 *val)
{
const struct ipahal_reg_qtime_timestamp_cfg *ts_cfg =
(const struct ipahal_reg_qtime_timestamp_cfg *)fields;
if (!ts_cfg->dpl_timestamp_sel &&
ts_cfg->dpl_timestamp_lsb) {
IPAHAL_ERR("non zero DPL shift while legacy mode\n");
WARN_ON(1);
}
IPA_SETFIELD_IN_REG(*val,
ts_cfg->dpl_timestamp_lsb,
IPA_QTIME_TIMESTAMP_CFG_DPL_TIMESTAMP_LSB_SHFT,
IPA_QTIME_TIMESTAMP_CFG_DPL_TIMESTAMP_LSB_BMSK);
IPA_SETFIELD_IN_REG(*val,
ts_cfg->dpl_timestamp_sel ? 1 : 0,
IPA_QTIME_TIMESTAMP_CFG_DPL_TIMESTAMP_SEL_SHFT,
IPA_QTIME_TIMESTAMP_CFG_DPL_TIMESTAMP_SEL_BMSK);
IPA_SETFIELD_IN_REG(*val,
ts_cfg->tag_timestamp_lsb,
IPA_QTIME_TIMESTAMP_CFG_TAG_TIMESTAMP_LSB_SHFT,
IPA_QTIME_TIMESTAMP_CFG_TAG_TIMESTAMP_LSB_BMSK);
IPA_SETFIELD_IN_REG(*val,
ts_cfg->nat_timestamp_lsb,
IPA_QTIME_TIMESTAMP_CFG_NAT_TIMESTAMP_LSB_SHFT,
IPA_QTIME_TIMESTAMP_CFG_NAT_TIMESTAMP_LSB_BMSK);
}
static u8 ipareg_timers_pulse_gran_code(
enum ipa_timers_time_gran_type gran)
{
switch (gran) {
case IPA_TIMERS_TIME_GRAN_10_USEC: return 0;
case IPA_TIMERS_TIME_GRAN_20_USEC: return 1;
case IPA_TIMERS_TIME_GRAN_50_USEC: return 2;
case IPA_TIMERS_TIME_GRAN_100_USEC: return 3;
case IPA_TIMERS_TIME_GRAN_1_MSEC: return 4;
case IPA_TIMERS_TIME_GRAN_10_MSEC: return 5;
case IPA_TIMERS_TIME_GRAN_100_MSEC: return 6;
case IPA_TIMERS_TIME_GRAN_NEAR_HALF_SEC: return 7;
default:
IPAHAL_ERR("Invalid granularity %d\n", gran);
break;
};
return 3;
}
static enum ipa_timers_time_gran_type
ipareg_timers_pulse_gran_decode(u8 code)
{
switch (code) {
case 0: return IPA_TIMERS_TIME_GRAN_10_USEC;
case 1: return IPA_TIMERS_TIME_GRAN_20_USEC;
case 2: return IPA_TIMERS_TIME_GRAN_50_USEC;
case 3: return IPA_TIMERS_TIME_GRAN_100_USEC;
case 4: return IPA_TIMERS_TIME_GRAN_1_MSEC;
case 5: return IPA_TIMERS_TIME_GRAN_10_MSEC;
case 6: return IPA_TIMERS_TIME_GRAN_100_MSEC;
case 7: return IPA_TIMERS_TIME_GRAN_NEAR_HALF_SEC;
default:
IPAHAL_ERR("Invalid coded granularity %d\n", code);
break;
};
return IPA_TIMERS_TIME_GRAN_100_USEC;
}
static void ipareg_construct_timers_pulse_gran_cfg(
enum ipahal_reg_name reg, const void *fields, u32 *val)
{
const struct ipahal_reg_timers_pulse_gran_cfg *gran_cfg =
(const struct ipahal_reg_timers_pulse_gran_cfg *)fields;
IPA_SETFIELD_IN_REG(*val,
ipareg_timers_pulse_gran_code(gran_cfg->gran_0),
IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_SHFT(0),
IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_BMSK(0));
IPA_SETFIELD_IN_REG(*val,
ipareg_timers_pulse_gran_code(gran_cfg->gran_1),
IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_SHFT(1),
IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_BMSK(1));
IPA_SETFIELD_IN_REG(*val,
ipareg_timers_pulse_gran_code(gran_cfg->gran_2),
IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_SHFT(2),
IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_BMSK(2));
}
static void ipareg_parse_timers_pulse_gran_cfg(
enum ipahal_reg_name reg, void *fields, u32 val)
{
u8 code;
struct ipahal_reg_timers_pulse_gran_cfg *gran_cfg =
(struct ipahal_reg_timers_pulse_gran_cfg *)fields;
code = IPA_GETFIELD_FROM_REG(val,
IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_SHFT(0),
IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_BMSK(0));
gran_cfg->gran_0 = ipareg_timers_pulse_gran_decode(code);
code = IPA_GETFIELD_FROM_REG(val,
IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_SHFT(1),
IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_BMSK(1));
gran_cfg->gran_1 = ipareg_timers_pulse_gran_decode(code);
code = IPA_GETFIELD_FROM_REG(val,
IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_SHFT(2),
IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_BMSK(2));
gran_cfg->gran_2 = ipareg_timers_pulse_gran_decode(code);
}
static void ipareg_construct_timers_xo_clk_div_cfg(
enum ipahal_reg_name reg, const void *fields, u32 *val)
{
const struct ipahal_reg_timers_xo_clk_div_cfg *div_cfg =
(const struct ipahal_reg_timers_xo_clk_div_cfg *)fields;
IPA_SETFIELD_IN_REG(*val,
div_cfg->enable ? 1 : 0,
IPA_TIMERS_XO_CLK_DIV_CFG_ENABLE_SHFT,
IPA_TIMERS_XO_CLK_DIV_CFG_ENABLE_BMSK);
IPA_SETFIELD_IN_REG(*val,
div_cfg->value,
IPA_TIMERS_XO_CLK_DIV_CFG_VALUE_SHFT,
IPA_TIMERS_XO_CLK_DIV_CFG_VALUE_BMSK);
}
static void ipareg_parse_timers_xo_clk_div_cfg(
enum ipahal_reg_name reg, void *fields, u32 val)
{
struct ipahal_reg_timers_xo_clk_div_cfg *div_cfg =
(struct ipahal_reg_timers_xo_clk_div_cfg *)fields;
div_cfg->enable =
IPA_GETFIELD_FROM_REG(val,
IPA_TIMERS_XO_CLK_DIV_CFG_ENABLE_SHFT,
IPA_TIMERS_XO_CLK_DIV_CFG_ENABLE_BMSK);
div_cfg->value =
IPA_GETFIELD_FROM_REG(val,
IPA_TIMERS_XO_CLK_DIV_CFG_VALUE_SHFT,
IPA_TIMERS_XO_CLK_DIV_CFG_VALUE_BMSK);
}
static void ipareg_construct_comp_cfg_comon(
const struct ipahal_reg_comp_cfg *comp_cfg, u32 *val)
{
@ -1340,6 +1493,27 @@ static void ipareg_construct_endp_init_hol_block_timer_n_v4_2(
IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_BASE_VALUE_BMSK_V_4_2);
}
static void ipareg_construct_endp_init_hol_block_timer_n_v4_5(
enum ipahal_reg_name reg, const void *fields, u32 *val)
{
struct ipa_ep_cfg_holb *ep_holb =
(struct ipa_ep_cfg_holb *)fields;
if (ep_holb->pulse_generator != !!ep_holb->pulse_generator) {
IPAHAL_ERR("Pulse generator is not 0 or 1 %d\n",
ep_holb->pulse_generator);
WARN_ON(1);
}
IPA_SETFIELD_IN_REG(*val, ep_holb->scaled_time,
IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_TIME_LIMIT_SHFT_V4_5,
IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_TIME_LIMIT_BMSK_V4_5);
IPA_SETFIELD_IN_REG(*val, ep_holb->pulse_generator,
IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_GRAN_SEL_SHFT_V4_5,
IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_GRAN_SEL_BMSK_V4_5);
}
static void ipareg_construct_endp_init_ctrl_n(enum ipahal_reg_name reg,
const void *fields, u32 *val)
{
@ -1479,6 +1653,7 @@ static void ipareg_parse_endp_init_aggr_n(enum ipahal_reg_name reg,
ep_aggr->aggr_time_limit =
((val & IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_BMSK) >>
IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_SHFT);
ep_aggr->aggr_time_limit *= 1000; /* HW works in msec */
ep_aggr->aggr_pkt_limit =
((val & IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_BMSK) >>
IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_SHFT);
@ -1491,14 +1666,48 @@ static void ipareg_parse_endp_init_aggr_n(enum ipahal_reg_name reg,
IPA_ENDP_INIT_AGGR_n_AGGR_HARD_BYTE_LIMIT_ENABLE_SHFT);
}
static void ipareg_parse_endp_init_aggr_n_v4_5(enum ipahal_reg_name reg,
void *fields, u32 val)
{
struct ipa_ep_cfg_aggr *ep_aggr =
(struct ipa_ep_cfg_aggr *)fields;
memset(ep_aggr, 0, sizeof(struct ipa_ep_cfg_aggr));
ep_aggr->aggr_en =
(((val & IPA_ENDP_INIT_AGGR_n_AGGR_EN_BMSK_V4_5) >>
IPA_ENDP_INIT_AGGR_n_AGGR_EN_SHFT_V4_5)
== IPA_ENABLE_AGGR);
ep_aggr->aggr =
((val & IPA_ENDP_INIT_AGGR_n_AGGR_TYPE_BMSK_V4_5) >>
IPA_ENDP_INIT_AGGR_n_AGGR_TYPE_SHFT_V4_5);
ep_aggr->aggr_byte_limit =
((val & IPA_ENDP_INIT_AGGR_n_AGGR_BYTE_LIMIT_BMSK_V4_5) >>
IPA_ENDP_INIT_AGGR_n_AGGR_BYTE_LIMIT_SHFT_V4_5);
ep_aggr->scaled_time =
((val & IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_BMSK_V4_5) >>
IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_SHFT_V4_5);
ep_aggr->aggr_pkt_limit =
((val & IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_BMSK_V4_5) >>
IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_SHFT_V4_5);
ep_aggr->aggr_sw_eof_active =
((val & IPA_ENDP_INIT_AGGR_n_AGGR_SW_EOF_ACTIVE_BMSK_V4_5) >>
IPA_ENDP_INIT_AGGR_n_AGGR_SW_EOF_ACTIVE_SHFT_V4_5);
ep_aggr->aggr_hard_byte_limit_en =
((val &
IPA_ENDP_INIT_AGGR_n_AGGR_HARD_BYTE_LIMIT_ENABLE_BMSK_V4_5)
>>
IPA_ENDP_INIT_AGGR_n_AGGR_HARD_BYTE_LIMIT_ENABLE_SHFT_V4_5);
ep_aggr->pulse_generator =
((val & IPA_ENDP_INIT_AGGR_n_AGGR_GRAN_SEL_BMSK_V4_5) >>
IPA_ENDP_INIT_AGGR_n_AGGR_GRAN_SEL_SHFT_V4_5);
}
static void ipareg_construct_endp_init_aggr_n(enum ipahal_reg_name reg,
const void *fields, u32 *val)
{
struct ipa_ep_cfg_aggr *ep_aggr =
(struct ipa_ep_cfg_aggr *)fields;
u32 byte_limit;
u32 pkt_limit;
IPA_SETFIELD_IN_REG(*val, ep_aggr->aggr_en,
IPA_ENDP_INIT_AGGR_n_AGGR_EN_SHFT,
@ -1508,25 +1717,16 @@ static void ipareg_construct_endp_init_aggr_n(enum ipahal_reg_name reg,
IPA_ENDP_INIT_AGGR_n_AGGR_TYPE_SHFT,
IPA_ENDP_INIT_AGGR_n_AGGR_TYPE_BMSK);
/* make sure aggregation size does not cross HW boundaries */
byte_limit = (ep_aggr->aggr_byte_limit >
ipahal_aggr_get_max_byte_limit()) ?
ipahal_aggr_get_max_byte_limit() :
ep_aggr->aggr_byte_limit;
IPA_SETFIELD_IN_REG(*val, byte_limit,
IPA_SETFIELD_IN_REG(*val, ep_aggr->aggr_byte_limit,
IPA_ENDP_INIT_AGGR_n_AGGR_BYTE_LIMIT_SHFT,
IPA_ENDP_INIT_AGGR_n_AGGR_BYTE_LIMIT_BMSK);
IPA_SETFIELD_IN_REG(*val, ep_aggr->aggr_time_limit,
/* HW works in msec */
IPA_SETFIELD_IN_REG(*val, ep_aggr->aggr_time_limit / 1000,
IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_SHFT,
IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_BMSK);
/* make sure aggregation size does not cross HW boundaries */
pkt_limit = (ep_aggr->aggr_pkt_limit >
ipahal_aggr_get_max_pkt_limit()) ?
ipahal_aggr_get_max_pkt_limit() :
ep_aggr->aggr_pkt_limit;
IPA_SETFIELD_IN_REG(*val, pkt_limit,
IPA_SETFIELD_IN_REG(*val, ep_aggr->aggr_pkt_limit,
IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_SHFT,
IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_BMSK);
@ -1540,6 +1740,52 @@ static void ipareg_construct_endp_init_aggr_n(enum ipahal_reg_name reg,
IPA_ENDP_INIT_AGGR_n_AGGR_HARD_BYTE_LIMIT_ENABLE_BMSK);
}
static void ipareg_construct_endp_init_aggr_n_v4_5(enum ipahal_reg_name reg,
const void *fields, u32 *val)
{
struct ipa_ep_cfg_aggr *ep_aggr =
(struct ipa_ep_cfg_aggr *)fields;
IPA_SETFIELD_IN_REG(*val, ep_aggr->aggr_en,
IPA_ENDP_INIT_AGGR_n_AGGR_EN_SHFT_V4_5,
IPA_ENDP_INIT_AGGR_n_AGGR_EN_BMSK_V4_5);
IPA_SETFIELD_IN_REG(*val, ep_aggr->aggr,
IPA_ENDP_INIT_AGGR_n_AGGR_TYPE_SHFT_V4_5,
IPA_ENDP_INIT_AGGR_n_AGGR_TYPE_BMSK_V4_5);
IPA_SETFIELD_IN_REG(*val, ep_aggr->aggr_byte_limit,
IPA_ENDP_INIT_AGGR_n_AGGR_BYTE_LIMIT_SHFT_V4_5,
IPA_ENDP_INIT_AGGR_n_AGGR_BYTE_LIMIT_BMSK_V4_5);
IPA_SETFIELD_IN_REG(*val, ep_aggr->scaled_time,
IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_SHFT_V4_5,
IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_BMSK_V4_5);
IPA_SETFIELD_IN_REG(*val, ep_aggr->aggr_pkt_limit,
IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_SHFT_V4_5,
IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_BMSK_V4_5);
IPA_SETFIELD_IN_REG(*val, ep_aggr->aggr_sw_eof_active,
IPA_ENDP_INIT_AGGR_n_AGGR_SW_EOF_ACTIVE_SHFT_V4_5,
IPA_ENDP_INIT_AGGR_n_AGGR_SW_EOF_ACTIVE_BMSK_V4_5);
/* At IPAv3 hard_byte_limit is not supported */
if (ep_aggr->aggr_hard_byte_limit_en) {
IPAHAL_ERR("hard byte limit aggr is not supported\n");
WARN_ON(1);
}
ep_aggr->aggr_hard_byte_limit_en = 0;
IPA_SETFIELD_IN_REG(*val, ep_aggr->aggr_hard_byte_limit_en,
IPA_ENDP_INIT_AGGR_n_AGGR_HARD_BYTE_LIMIT_ENABLE_SHFT_V4_5,
IPA_ENDP_INIT_AGGR_n_AGGR_HARD_BYTE_LIMIT_ENABLE_BMSK_V4_5);
IPA_SETFIELD_IN_REG(*val, ep_aggr->pulse_generator,
IPA_ENDP_INIT_AGGR_n_AGGR_GRAN_SEL_SHFT_V4_5,
IPA_ENDP_INIT_AGGR_n_AGGR_GRAN_SEL_BMSK_V4_5);
}
static void ipareg_construct_endp_init_hdr_ext_n(enum ipahal_reg_name reg,
const void *fields, u32 *val)
{
@ -2074,7 +2320,7 @@ static struct ipahal_reg_obj ipahal_reg_objs[IPA_HW_MAX][IPA_REG_MAX] = {
[IPA_HW_v3_0][IPA_SHARED_MEM_SIZE] = {
ipareg_construct_dummy, ipareg_parse_shared_mem_size,
0x00000054, 0, 0, 0, 0},
[IPA_HW_v3_0][IPA_SRAM_DIRECT_ACCESS_n] = {
[IPA_HW_v3_0][IPA_SW_AREA_RAM_DIRECT_ACCESS_n] = {
ipareg_construct_dummy, ipareg_parse_dummy,
0x00007000, 0x4, 0, 0, 0},
[IPA_HW_v3_0][IPA_DEBUG_CNT_CTRL_n] = {
@ -2577,6 +2823,17 @@ static struct ipahal_reg_obj ipahal_reg_objs[IPA_HW_MAX][IPA_REG_MAX] = {
[IPA_HW_v4_5][IPA_CLKON_CFG] = {
ipareg_construct_clkon_cfg_v4_5, ipareg_parse_clkon_cfg_v4_5,
0x00000044, 0, 0, 0, 0},
[IPA_HW_v4_5][IPA_QTIME_TIMESTAMP_CFG] = {
ipareg_construct_qtime_timestamp_cfg, ipareg_parse_dummy,
0x00000024c, 0, 0, 0, 1},
[IPA_HW_v4_5][IPA_TIMERS_PULSE_GRAN_CFG] = {
ipareg_construct_timers_pulse_gran_cfg,
ipareg_parse_timers_pulse_gran_cfg,
0x000000254, 0, 0, 0, 1},
[IPA_HW_v4_5][IPA_TIMERS_XO_CLK_DIV_CFG] = {
ipareg_construct_timers_xo_clk_div_cfg,
ipareg_parse_timers_xo_clk_div_cfg,
0x000000250, 0, 0, 0, 1},
[IPA_HW_v4_5][IPA_ENDP_INIT_SEQ_n] = {
ipareg_construct_dummy, ipareg_parse_dummy,
0x0000083C, 0x70, 0, 13, 1},
@ -2652,6 +2909,24 @@ static struct ipahal_reg_obj ipahal_reg_objs[IPA_HW_MAX][IPA_REG_MAX] = {
[IPA_HW_v4_5][IPA_HPS_SEQUENCER_LAST] = {
ipareg_construct_dummy, ipareg_parse_dummy,
0x0000257c, 0, 0, 0, 0},
[IPA_HW_v4_5][IPA_NAT_TIMER] = {
ipareg_construct_dummy, ipareg_parse_dummy,
0x00000058, 0, 0, 0, 1},
[IPA_HW_v4_5][IPA_ENDP_INIT_HOL_BLOCK_EN_n] = {
ipareg_construct_endp_init_hol_block_en_n,
ipareg_parse_dummy,
0x0000082c, 0x70, 13, 31, 1},
[IPA_HW_v4_5][IPA_ENDP_INIT_HOL_BLOCK_TIMER_n] = {
ipareg_construct_endp_init_hol_block_timer_n_v4_5,
ipareg_parse_dummy,
0x00000830, 0x70, 13, 31, 1},
[IPA_HW_v4_5][IPA_ENDP_INIT_AGGR_n] = {
ipareg_construct_endp_init_aggr_n_v4_5,
ipareg_parse_endp_init_aggr_n_v4_5,
0x00000824, 0x70, 0, 31, 1},
[IPA_HW_v4_5][IPA_SW_AREA_RAM_DIRECT_ACCESS_n] = {
ipareg_construct_dummy, ipareg_parse_dummy,
0x000010000, 0x4, 0, 0, 0},
};
/*
@ -2996,20 +3271,6 @@ u32 ipahal_get_reg_base(void)
* specific functions.
*/
u32 ipahal_aggr_get_max_byte_limit(void)
{
return
IPA_ENDP_INIT_AGGR_n_AGGR_BYTE_LIMIT_BMSK >>
IPA_ENDP_INIT_AGGR_n_AGGR_BYTE_LIMIT_SHFT;
}
u32 ipahal_aggr_get_max_pkt_limit(void)
{
return
IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_BMSK >>
IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_SHFT;
}
void ipahal_get_aggr_force_close_valmask(int ep_idx,
struct ipahal_reg_valmask *valmask)
{

View File

@ -36,6 +36,7 @@ enum ipahal_reg_name {
IPA_ENABLED_PIPES,
IPA_VERSION,
IPA_TAG_TIMER,
IPA_NAT_TIMER,
IPA_COMP_HW_VERSION,
IPA_COMP_CFG,
IPA_STATE_TX_WRAPPER,
@ -84,7 +85,7 @@ enum ipahal_reg_name {
IPA_ENDP_INIT_PROD_CFG_n,
IPA_ENDP_INIT_RSRC_GRP_n,
IPA_SHARED_MEM_SIZE,
IPA_SRAM_DIRECT_ACCESS_n,
IPA_SW_AREA_RAM_DIRECT_ACCESS_n,
IPA_DEBUG_CNT_CTRL_n,
IPA_UC_MAILBOX_m_n,
IPA_FILT_ROUT_HASH_FLUSH,
@ -117,6 +118,9 @@ enum ipahal_reg_name {
IPA_HPS_SEQUENCER_FIRST,
IPA_HPS_SEQUENCER_LAST,
IPA_CLKON_CFG,
IPA_QTIME_TIMESTAMP_CFG,
IPA_TIMERS_PULSE_GRAN_CFG,
IPA_TIMERS_XO_CLK_DIV_CFG,
IPA_STAT_QUOTA_BASE_n,
IPA_STAT_QUOTA_MASK_n,
IPA_STAT_TETHERING_BASE_n,
@ -200,12 +204,12 @@ struct ipahal_reg_endp_init_mode {
};
/*
* struct ipahal_reg_shared_mem_size - IPA SHARED_MEM_SIZE register
* struct ipahal_reg_shared_mem_size - IPA_SHARED_MEM_SIZE register
* @shared_mem_sz: Available size [in 8Bytes] of SW partition within
* IPA shared memory.
* @shared_mem_baddr: Offset of SW partition within IPA
* shared memory[in 8Bytes]. To get absolute address of SW partition,
* add this offset to IPA_SRAM_DIRECT_ACCESS_n baddr.
* add this offset to IPA_SW_AREA_RAM_DIRECT_ACCESS_n baddr.
*/
struct ipahal_reg_shared_mem_size {
u32 shared_mem_sz;
@ -278,6 +282,83 @@ struct ipahal_reg_clkon_cfg {
bool open_rx;
};
/*
* struct ipahal_reg_qtime_timestamp_cfg - IPA timestamp configuration
* Relevant starting IPA 4.5.
* IPA timestamps are based on QTIMER which is 56bit length which is
* based on XO clk running at 19.2MHz (52nsec resolution).
* Specific timestamps (TAG, NAT, DPL) my require lower resolution.
* This can be achieved by omitting LSB bits from 56bit QTIMER.
* e.g. if we omit (shift) 24 bit then we get (2^24)*(52n)=0.87sec resolution.
*
* @dpl_timestamp_lsb: Shifting Qtime value. Value will be used as LSB of
* DPL timestamp.
* @dpl_timestamp_sel: if false, DPL timestamp will be based on legacy
* DPL_TIMER which counts in 1ms. if true, it will be based on QTIME
* value shifted by dpl_timestamp_lsb.
* @tag_timestamp_lsb: Shifting Qtime value. Value will be used as LSB of
* TAG timestamp.
* @nat_timestamp_lsb: Shifting Qtime value. Value will be used as LSB of
* NAT timestamp.
*/
struct ipahal_reg_qtime_timestamp_cfg {
u32 dpl_timestamp_lsb;
bool dpl_timestamp_sel;
u32 tag_timestamp_lsb;
u32 nat_timestamp_lsb;
};
/*
* enum ipa_timers_time_gran_type - Time granularity to be used with timers
*
* e.g. for HOLB and Aggregation timers
*/
enum ipa_timers_time_gran_type {
IPA_TIMERS_TIME_GRAN_10_USEC,
IPA_TIMERS_TIME_GRAN_20_USEC,
IPA_TIMERS_TIME_GRAN_50_USEC,
IPA_TIMERS_TIME_GRAN_100_USEC,
IPA_TIMERS_TIME_GRAN_1_MSEC,
IPA_TIMERS_TIME_GRAN_10_MSEC,
IPA_TIMERS_TIME_GRAN_100_MSEC,
IPA_TIMERS_TIME_GRAN_NEAR_HALF_SEC, /* 0.65536s */
IPA_TIMERS_TIME_GRAN_MAX,
};
/*
* struct ipahal_reg_timers_pulse_gran_cfg - Counters tick granularities
* Relevant starting IPA 4.5.
* IPA timers are based on XO CLK running 19.2MHz (52ns resolution) deviced
* by clock divider (see IPA_TIMERS_XO_CLK_DIV_CFG) - default 100Khz (10usec).
* IPA timers instances (e.g. HOLB or AGGR) may require different resolutions.
* There are 3 global pulse generators with configurable granularity. Each
* timer instance can choose one of the three generators to work with.
* Each generator granularity can be one of supported ones.
*
* @gran_X: granularity tick of counterX
*/
struct ipahal_reg_timers_pulse_gran_cfg {
enum ipa_timers_time_gran_type gran_0;
enum ipa_timers_time_gran_type gran_1;
enum ipa_timers_time_gran_type gran_2;
};
/*
* struct ipahal_reg_timers_xo_clk_div_cfg - IPA timers clock divider
* Used to control clock divider which gets XO_CLK of 19.2MHz as input.
* Output of CDIV is used to generate IPA timers granularity
*
* @enable: Enable of the clock divider for all IPA and GSI timers.
* clock is disabled by default, and need to be enabled when system is up.
* @value: Divided value to be used by CDIV. POR value is set to 191
* to generate 100KHz clk based on XO_CLK.
* Values of ipahal_reg_timers_pulse_gran_cfg are based on this default.
*/
struct ipahal_reg_timers_xo_clk_div_cfg {
bool enable;
u32 value;
};
/*
* struct ipahal_reg_comp_cfg- IPA Core QMB/Master Port selection
*
@ -661,12 +742,10 @@ u32 ipahal_get_reg_base(void);
* These functions supply specific register values for specific operations
* that cannot be reached by generic functions.
* E.g. To disable aggregation, need to write to specific bits of the AGGR
* register. The other bits should be untouched. This oeprate is very specific
* and cannot be generically defined. For such operations we define these
* specific functions.
* register. The other bits should be untouched. This operation is very
* specific and cannot be generically defined. For such operations we define
* these specific functions.
*/
u32 ipahal_aggr_get_max_byte_limit(void);
u32 ipahal_aggr_get_max_pkt_limit(void);
void ipahal_get_aggr_force_close_valmask(int ep_idx,
struct ipahal_reg_valmask *valmask);
void ipahal_get_fltrt_hash_flush_valmask(

View File

@ -70,7 +70,7 @@ int ipahal_reg_init(enum ipa_hw_type ipa_hw_type);
#define IPA_ENDP_INIT_HDR_EXT_n_HDR_PAD_TO_ALIGNMENT_SHFT 0xa
#define IPA_ENDP_INIT_HDR_EXT_n_HDR_PAD_TO_ALIGNMENT_BMSK_v3_0 0x3c00
/* IPA_ENDP_INIT_AGGR_N register */
/* IPA_ENDP_INIT_AGGR_n register */
#define IPA_ENDP_INIT_AGGR_n_AGGR_HARD_BYTE_LIMIT_ENABLE_BMSK 0x1000000
#define IPA_ENDP_INIT_AGGR_n_AGGR_HARD_BYTE_LIMIT_ENABLE_SHFT 0x18
#define IPA_ENDP_INIT_AGGR_n_AGGR_FORCE_CLOSE_BMSK 0x400000
@ -88,6 +88,25 @@ int ipahal_reg_init(enum ipa_hw_type ipa_hw_type);
#define IPA_ENDP_INIT_AGGR_n_AGGR_EN_BMSK 0x3
#define IPA_ENDP_INIT_AGGR_n_AGGR_EN_SHFT 0x0
#define IPA_ENDP_INIT_AGGR_n_AGGR_GRAN_SEL_BMSK_V4_5 0x8000000
#define IPA_ENDP_INIT_AGGR_n_AGGR_GRAN_SEL_SHFT_V4_5 27
#define IPA_ENDP_INIT_AGGR_n_AGGR_HARD_BYTE_LIMIT_ENABLE_BMSK_V4_5 0x4000000
#define IPA_ENDP_INIT_AGGR_n_AGGR_HARD_BYTE_LIMIT_ENABLE_SHFT_V4_5 26
#define IPA_ENDP_INIT_AGGR_n_AGGR_FORCE_CLOSE_BMSK_V4_5 0x1000000
#define IPA_ENDP_INIT_AGGR_n_AGGR_FORCE_CLOSE_SHFT_V4_5 24
#define IPA_ENDP_INIT_AGGR_n_AGGR_SW_EOF_ACTIVE_BMSK_V4_5 0x800000
#define IPA_ENDP_INIT_AGGR_n_AGGR_SW_EOF_ACTIVE_SHFT_V4_5 23
#define IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_BMSK_V4_5 0x7e0000
#define IPA_ENDP_INIT_AGGR_n_AGGR_PKT_LIMIT_SHFT_V4_5 17
#define IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_BMSK_V4_5 0x1f000
#define IPA_ENDP_INIT_AGGR_n_AGGR_TIME_LIMIT_SHFT_V4_5 12
#define IPA_ENDP_INIT_AGGR_n_AGGR_BYTE_LIMIT_BMSK_V4_5 0x7e0
#define IPA_ENDP_INIT_AGGR_n_AGGR_BYTE_LIMIT_SHFT_V4_5 5
#define IPA_ENDP_INIT_AGGR_n_AGGR_TYPE_BMSK_V4_5 0x1c
#define IPA_ENDP_INIT_AGGR_n_AGGR_TYPE_SHFT_V4_5 2
#define IPA_ENDP_INIT_AGGR_n_AGGR_EN_BMSK_V4_5 0x3
#define IPA_ENDP_INIT_AGGR_n_AGGR_EN_SHFT_V4_5 0
/* IPA_AGGR_FORCE_CLOSE register */
#define IPA_AGGR_FORCE_CLOSE_AGGR_FORCE_CLOSE_PIPE_BITMAP_BMSK 0x3fffffff
#define IPA_AGGR_FORCE_CLOSE_AGGR_FORCE_CLOSE_PIPE_BITMAP_SHFT 0
@ -165,6 +184,11 @@ int ipahal_reg_init(enum ipa_hw_type ipa_hw_type);
#define IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_SCALE_SHFT_V_4_2 0x8
#define IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_SCALE_BMSK_V_4_2 0x1f00
#define IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_TIME_LIMIT_BMSK_V4_5 0x1F
#define IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_TIME_LIMIT_SHFT_V4_5 0
#define IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_GRAN_SEL_BMSK_V4_5 0x100
#define IPA_ENDP_INIT_HOL_BLOCK_TIMER_n_GRAN_SEL_SHFT_V4_5 8
/* IPA_ENDP_INIT_DEAGGR_n register */
#define IPA_ENDP_INIT_DEAGGR_n_MAX_PACKET_LEN_BMSK 0xFFFF0000
#define IPA_ENDP_INIT_DEAGGR_n_MAX_PACKET_LEN_SHFT 0x10
@ -334,6 +358,26 @@ int ipahal_reg_init(enum ipa_hw_type ipa_hw_type);
#define IPA_CLKON_CFG_OPEN_RX_BMSK 0x1
#define IPA_CLKON_CFG_OPEN_RX_SHFT 0
/* IPA_QTIME_TIMESTAMP_CFG register */
#define IPA_QTIME_TIMESTAMP_CFG_DPL_TIMESTAMP_LSB_SHFT 0
#define IPA_QTIME_TIMESTAMP_CFG_DPL_TIMESTAMP_LSB_BMSK 0x1F
#define IPA_QTIME_TIMESTAMP_CFG_DPL_TIMESTAMP_SEL_SHFT 7
#define IPA_QTIME_TIMESTAMP_CFG_DPL_TIMESTAMP_SEL_BMSK 0x80
#define IPA_QTIME_TIMESTAMP_CFG_TAG_TIMESTAMP_LSB_SHFT 8
#define IPA_QTIME_TIMESTAMP_CFG_TAG_TIMESTAMP_LSB_BMSK 0x1F00
#define IPA_QTIME_TIMESTAMP_CFG_NAT_TIMESTAMP_LSB_SHFT 16
#define IPA_QTIME_TIMESTAMP_CFG_NAT_TIMESTAMP_LSB_BMSK 0x1F0000
/* IPA_TIMERS_PULSE_GRAN_CFG register */
#define IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_SHFT(x) (3 * (x))
#define IPA_TIMERS_PULSE_GRAN_CFG_GRAN_X_BMSK(x) (0x7 << (3 * (x)))
/* IPA_TIMERS_XO_CLK_DIV_CFG register */
#define IPA_TIMERS_XO_CLK_DIV_CFG_VALUE_SHFT 0
#define IPA_TIMERS_XO_CLK_DIV_CFG_VALUE_BMSK 0x1FF
#define IPA_TIMERS_XO_CLK_DIV_CFG_ENABLE_SHFT 31
#define IPA_TIMERS_XO_CLK_DIV_CFG_ENABLE_BMSK 0x80000000
/* IPA_ENDP_FILTER_ROUTER_HSH_CFG_n register */
#define IPA_ENDP_FILTER_ROUTER_HSH_CFG_n_FILTER_HASH_MSK_SRC_ID_SHFT 0
#define IPA_ENDP_FILTER_ROUTER_HSH_CFG_n_FILTER_HASH_MSK_SRC_ID_BMSK 0x1
@ -460,7 +504,7 @@ int ipahal_reg_init(enum ipa_hw_type ipa_hw_type);
#define IPA_HPS_FTCH_ARB_QUEUE_WEIGHTS_RX_HPS_QUEUE_WEIGHT_3_SHFT (0xc)
/* IPA_COUNTER_CFG register */
#define IPA_COUNTER_CFG_AGGR_GRANULARITY_BMSK (0xff0)
#define IPA_COUNTER_CFG_AGGR_GRANULARITY_BMSK (0x1f0)
#define IPA_COUNTER_CFG_AGGR_GRANULARITY_SHFT (0x4)
/* IPA_COMP_CFG register*/

View File

@ -15,7 +15,7 @@
#include "ipa_ut_framework.h"
#define IPA_TEST_DMA_WQ_NAME_BUFF_SZ 64
#define IPA_TEST_DMA_MT_TEST_NUM_WQ 400
#define IPA_TEST_DMA_MT_TEST_NUM_WQ 200
#define IPA_TEST_DMA_MEMCPY_BUFF_SIZE 16384
#define IPA_TEST_DMA_MAX_PKT_SIZE 0xFF00
#define IPA_DMA_TEST_LOOP_NUM 1000

View File

@ -248,12 +248,13 @@ struct ipa_ep_cfg_mode {
* to 0, there is no aggregation, every packet is sent
* independently according to the aggregation structure
* Valid for Output Pipes only (IPA Producer )
* @aggr_time_limit: Timer to close aggregated packet (<=32ms) When set to 0,
* @aggr_time_limit: Timer to close aggregated packet When set to 0,
* there is no time limitation on the aggregation. When
* both, Aggr_Byte_Limit and Aggr_Time_Limit are set to 0,
* there is no aggregation, every packet is sent
* independently according to the aggregation structure
* Valid for Output Pipes only (IPA Producer)
* Valid for Output Pipes only (IPA Producer).
* Time unit is -->> usec <<--
* @aggr_pkt_limit: Defines if EOF close aggregation or not. if set to false
* HW closes aggregation (sends EOT) only based on its
* aggregation config (byte/time limit, etc). if set to
@ -275,6 +276,13 @@ struct ipa_ep_cfg_mode {
* aggregation closure. Valid for Output Pipes only (IPA
* Producer). EOF affects only Pipes configured for generic
* aggregation.
* @pulse_generator: Pulse generator number to be used.
* For internal use.
* Supported starting IPA4.5.
* @scaled_time: Time limit in accordance to the pulse generator
* granularity.
* For internal use
* Supported starting IPA4.5
*/
struct ipa_ep_cfg_aggr {
enum ipa_aggr_en_type aggr_en;
@ -284,6 +292,8 @@ struct ipa_ep_cfg_aggr {
u32 aggr_pkt_limit;
u32 aggr_hard_byte_limit_en;
bool aggr_sw_eof_active;
u8 pulse_generator;
u8 scaled_time;
};
/**
@ -304,16 +314,26 @@ struct ipa_ep_cfg_route {
* @tmr_val: duration in units of 128 IPA clk clock cyles [0,511], 1 clk=1.28us
* IPAv2.5 support 32 bit HOLB timeout value, previous versions
* supports 16 bit
* splitting timer value into 2 fields for IPA4.2 new timer value is:
* BASE_VALUE* (2^SCALE)
* @base_val : base value of the timer
* @scale : scale value for timer
* IPAv4.2: splitting timer value into 2 fields. Timer value is:
* BASE_VALUE * (2^SCALE)
* IPA4.5: tmr_val is in -->>msec<<--. Range is dynamic based
* on H/W configuration. (IPA4.5 absolute maximum is 0.65535*31 -> ~20sec).
* @base_val : IPA4.2 only field. base value of the timer.
* @scale : IPA4.2 only field. scale value for timer.
* @pulse_generator: Pulse generator number to be used.
* For internal use.
* Supported starting IPA4.5.
* @scaled_time: Time limit in accordance to the pulse generator granularity
* For internal use
* Supported starting IPA4.5
*/
struct ipa_ep_cfg_holb {
u16 en;
u32 tmr_val;
u32 base_val;
u32 scale;
u16 en;
u8 pulse_generator;
u8 scaled_time;
};
/**
@ -1642,6 +1662,12 @@ static inline int ipa_cfg_ep_holb(u32 clnt_hdl,
return -EPERM;
}
static inline int ipa_cfg_ep_holb_by_client(enum ipa_client_type client,
const struct ipa_ep_cfg_holb *ep_holb)
{
return -EPERM;
}
static inline int ipa_cfg_ep_cfg(u32 clnt_hdl,
const struct ipa_ep_cfg_cfg *ipa_ep_cfg)
{