msm: ipa: add support for configuring polling interval/sleep time
Using 1 millisecond Rx polling sleep makes the cpu wake up too often, results in more power consumption. Using 3 milliseconds is helping on MSM8940 in terms of both power and performance. Give provision to change the polling time via device tree entry and use 3 milliseconds for MSM8940. And also give provision to modify the rx polling timeout via debugfs entry for testing purposes. Change-Id: I88de436b29c3000dcebeec4da607dff42d0609fe Acked-by: Mohammad Javid <mjavid@qti.qualcomm.com> Signed-off-by: Utkarsh Saxena <usaxena@codeaurora.org>
This commit is contained in:
parent
cc915a3931
commit
d630f1d6aa
6 changed files with 210 additions and 5 deletions
|
@ -76,6 +76,10 @@ memory allocation over a PCIe bridge
|
|||
- qcom,tethered-flow-control: Boolean context flag to indicate whether
|
||||
apps based flow control is needed for tethered
|
||||
call.
|
||||
- qcom,rx-polling-sleep-ms: Receive Polling Timeout in millisecond,
|
||||
default is 1 millisecond.
|
||||
- qcom,ipa-polling-iteration: IPA Polling Iteration Count,default is 40.
|
||||
|
||||
IPA pipe sub nodes (A2 static pipes configurations):
|
||||
|
||||
-label: two labels are supported, a2-to-ipa and ipa-to-a2 which
|
||||
|
|
|
@ -65,6 +65,10 @@
|
|||
#define IPA2_ACTIVE_CLIENT_LOG_TYPE_RESOURCE 2
|
||||
#define IPA2_ACTIVE_CLIENT_LOG_TYPE_SPECIAL 3
|
||||
|
||||
#define MAX_POLLING_ITERATION 40
|
||||
#define MIN_POLLING_ITERATION 1
|
||||
#define ONE_MSEC 1
|
||||
|
||||
#define IPA_AGGR_STR_IN_BYTES(str) \
|
||||
(strnlen((str), IPA_AGGR_MAX_STR_LENGTH - 1) + 1)
|
||||
|
||||
|
@ -3613,6 +3617,19 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p,
|
|||
ipa_ctx->use_dma_zone = resource_p->use_dma_zone;
|
||||
ipa_ctx->tethered_flow_control = resource_p->tethered_flow_control;
|
||||
|
||||
/* Setting up IPA RX Polling Timeout Seconds */
|
||||
ipa_rx_timeout_min_max_calc(&ipa_ctx->ipa_rx_min_timeout_usec,
|
||||
&ipa_ctx->ipa_rx_max_timeout_usec,
|
||||
resource_p->ipa_rx_polling_sleep_msec);
|
||||
|
||||
/* Setting up ipa polling iteration */
|
||||
if ((resource_p->ipa_polling_iteration >= MIN_POLLING_ITERATION)
|
||||
&& (resource_p->ipa_polling_iteration <= MAX_POLLING_ITERATION))
|
||||
ipa_ctx->ipa_polling_iteration =
|
||||
resource_p->ipa_polling_iteration;
|
||||
else
|
||||
ipa_ctx->ipa_polling_iteration = MAX_POLLING_ITERATION;
|
||||
|
||||
/* default aggregation parameters */
|
||||
ipa_ctx->aggregation_type = IPA_MBIM_16;
|
||||
ipa_ctx->aggregation_byte_limit = 1;
|
||||
|
@ -4268,6 +4285,31 @@ static int get_ipa_dts_configuration(struct platform_device *pdev,
|
|||
if (result)
|
||||
ipa_drv_res->ee = 0;
|
||||
|
||||
/* Get IPA RX Polling Timeout Seconds */
|
||||
result = of_property_read_u32(pdev->dev.of_node,
|
||||
"qcom,rx-polling-sleep-ms",
|
||||
&ipa_drv_res->ipa_rx_polling_sleep_msec);
|
||||
|
||||
if (result) {
|
||||
ipa_drv_res->ipa_rx_polling_sleep_msec = ONE_MSEC;
|
||||
IPADBG("using default polling timeout of 1MSec\n");
|
||||
} else {
|
||||
IPADBG(": found ipa_drv_res->ipa_rx_polling_sleep_sec = %d",
|
||||
ipa_drv_res->ipa_rx_polling_sleep_msec);
|
||||
}
|
||||
|
||||
/* Get IPA Polling Iteration */
|
||||
result = of_property_read_u32(pdev->dev.of_node,
|
||||
"qcom,ipa-polling-iteration",
|
||||
&ipa_drv_res->ipa_polling_iteration);
|
||||
if (result) {
|
||||
ipa_drv_res->ipa_polling_iteration = MAX_POLLING_ITERATION;
|
||||
IPADBG("using default polling iteration\n");
|
||||
} else {
|
||||
IPADBG(": found ipa_drv_res->ipa_polling_iteration = %d",
|
||||
ipa_drv_res->ipa_polling_iteration);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,12 @@
|
|||
* IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES) \
|
||||
+ IPA_MAX_MSG_LEN)
|
||||
|
||||
#define RX_MIN_POLL_CNT "Rx Min Poll Count"
|
||||
#define RX_MAX_POLL_CNT "Rx Max Poll Count"
|
||||
#define MAX_COUNT_LENGTH 6
|
||||
#define MAX_POLLING_ITERATION 40
|
||||
#define MIN_POLLING_ITERATION 1
|
||||
|
||||
#define IPA_DUMP_STATUS_FIELD(f) \
|
||||
pr_err(#f "=0x%x\n", status->f)
|
||||
|
||||
|
@ -110,6 +116,9 @@ static struct dentry *dfile_ip4_nat;
|
|||
static struct dentry *dfile_rm_stats;
|
||||
static struct dentry *dfile_status_stats;
|
||||
static struct dentry *dfile_active_clients;
|
||||
static struct dentry *dfile_ipa_rx_poll_timeout;
|
||||
static struct dentry *dfile_ipa_poll_iteration;
|
||||
|
||||
static char dbg_buff[IPA_MAX_MSG_LEN];
|
||||
static char *active_clients_buf;
|
||||
static s8 ep_reg_idx;
|
||||
|
@ -1597,6 +1606,97 @@ static ssize_t ipa2_clear_active_clients_log(struct file *file,
|
|||
return count;
|
||||
}
|
||||
|
||||
static ssize_t ipa_read_rx_polling_timeout(struct file *file,
|
||||
char __user *ubuf, size_t count, loff_t *ppos)
|
||||
{
|
||||
int min_cnt;
|
||||
int max_cnt;
|
||||
|
||||
if (active_clients_buf == NULL) {
|
||||
IPAERR("Active Clients buffer is not allocated");
|
||||
return 0;
|
||||
}
|
||||
memset(active_clients_buf, 0, IPA_DBG_ACTIVE_CLIENTS_BUF_SIZE);
|
||||
min_cnt = scnprintf(active_clients_buf,
|
||||
IPA_DBG_ACTIVE_CLIENTS_BUF_SIZE,
|
||||
"Rx Min Poll count = %u\n",
|
||||
ipa_ctx->ipa_rx_min_timeout_usec);
|
||||
|
||||
max_cnt = scnprintf(active_clients_buf + min_cnt,
|
||||
IPA_DBG_ACTIVE_CLIENTS_BUF_SIZE,
|
||||
"Rx Max Poll count = %u\n",
|
||||
ipa_ctx->ipa_rx_max_timeout_usec);
|
||||
|
||||
return simple_read_from_buffer(ubuf, count, ppos, active_clients_buf,
|
||||
min_cnt + max_cnt);
|
||||
}
|
||||
|
||||
static ssize_t ipa_write_rx_polling_timeout(struct file *file,
|
||||
const char __user *ubuf, size_t count, loff_t *ppos)
|
||||
{
|
||||
s8 polltime = 0;
|
||||
|
||||
if (sizeof(dbg_buff) < count + 1)
|
||||
return -EFAULT;
|
||||
|
||||
if (copy_from_user(dbg_buff, ubuf, count))
|
||||
return -EFAULT;
|
||||
|
||||
dbg_buff[count] = '\0';
|
||||
|
||||
if (kstrtos8(dbg_buff, 0, &polltime))
|
||||
return -EFAULT;
|
||||
|
||||
ipa_rx_timeout_min_max_calc(&ipa_ctx->ipa_rx_min_timeout_usec,
|
||||
&ipa_ctx->ipa_rx_max_timeout_usec, polltime);
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t ipa_read_polling_iteration(struct file *file,
|
||||
char __user *ubuf, size_t count, loff_t *ppos)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
if (active_clients_buf == NULL) {
|
||||
IPAERR("Active Clients buffer is not allocated");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(active_clients_buf, 0, IPA_DBG_ACTIVE_CLIENTS_BUF_SIZE);
|
||||
|
||||
cnt = scnprintf(active_clients_buf, IPA_DBG_ACTIVE_CLIENTS_BUF_SIZE,
|
||||
"Polling Iteration count = %u\n",
|
||||
ipa_ctx->ipa_polling_iteration);
|
||||
|
||||
return simple_read_from_buffer(ubuf, count, ppos, active_clients_buf,
|
||||
cnt);
|
||||
}
|
||||
|
||||
static ssize_t ipa_write_polling_iteration(struct file *file,
|
||||
const char __user *ubuf, size_t count, loff_t *ppos)
|
||||
{
|
||||
s8 iteration_cnt = 0;
|
||||
|
||||
if (sizeof(dbg_buff) < count + 1)
|
||||
return -EFAULT;
|
||||
|
||||
if (copy_from_user(dbg_buff, ubuf, count))
|
||||
return -EFAULT;
|
||||
|
||||
dbg_buff[count] = '\0';
|
||||
|
||||
if (kstrtos8(dbg_buff, 0, &iteration_cnt))
|
||||
return -EFAULT;
|
||||
|
||||
if ((iteration_cnt >= MIN_POLLING_ITERATION) &&
|
||||
(iteration_cnt <= MAX_POLLING_ITERATION))
|
||||
ipa_ctx->ipa_polling_iteration = iteration_cnt;
|
||||
else
|
||||
ipa_ctx->ipa_polling_iteration = MAX_POLLING_ITERATION;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
const struct file_operations ipa_gen_reg_ops = {
|
||||
.read = ipa_read_gen_reg,
|
||||
};
|
||||
|
@ -1671,6 +1771,16 @@ const struct file_operations ipa2_active_clients = {
|
|||
.write = ipa2_clear_active_clients_log,
|
||||
};
|
||||
|
||||
const struct file_operations ipa_rx_poll_time_ops = {
|
||||
.read = ipa_read_rx_polling_timeout,
|
||||
.write = ipa_write_rx_polling_timeout,
|
||||
};
|
||||
|
||||
const struct file_operations ipa_poll_iteration_ops = {
|
||||
.read = ipa_read_polling_iteration,
|
||||
.write = ipa_write_polling_iteration,
|
||||
};
|
||||
|
||||
void ipa_debugfs_init(void)
|
||||
{
|
||||
const mode_t read_only_mode = S_IRUSR | S_IRGRP | S_IROTH;
|
||||
|
@ -1832,6 +1942,20 @@ void ipa_debugfs_init(void)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
dfile_ipa_rx_poll_timeout = debugfs_create_file("ipa_rx_poll_time",
|
||||
read_write_mode, dent, 0, &ipa_rx_poll_time_ops);
|
||||
if (!dfile_ipa_rx_poll_timeout || IS_ERR(dfile_ipa_rx_poll_timeout)) {
|
||||
IPAERR("fail to create file for debug_fs rx poll timeout\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dfile_ipa_poll_iteration = debugfs_create_file("ipa_poll_iteration",
|
||||
read_write_mode, dent, 0, &ipa_poll_iteration_ops);
|
||||
if (!dfile_ipa_poll_iteration || IS_ERR(dfile_ipa_poll_iteration)) {
|
||||
IPAERR("fail to create file for debug_fs poll iteration\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
file = debugfs_create_u32("enable_clock_scaling", read_write_mode,
|
||||
dent, &ipa_ctx->enable_clock_scaling);
|
||||
if (!file) {
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
|
||||
#define IPA_LAST_DESC_CNT 0xFFFF
|
||||
#define POLLING_INACTIVITY_RX 40
|
||||
#define POLLING_MIN_SLEEP_RX 1010
|
||||
#define POLLING_MAX_SLEEP_RX 1050
|
||||
#define POLLING_INACTIVITY_TX 40
|
||||
#define POLLING_MIN_SLEEP_TX 400
|
||||
#define POLLING_MAX_SLEEP_TX 500
|
||||
|
@ -1045,8 +1043,8 @@ static void ipa_handle_rx(struct ipa_sys_context *sys)
|
|||
if (cnt == 0) {
|
||||
inactive_cycles++;
|
||||
trace_idle_sleep_enter(sys->ep->client);
|
||||
usleep_range(POLLING_MIN_SLEEP_RX,
|
||||
POLLING_MAX_SLEEP_RX);
|
||||
usleep_range(ipa_ctx->ipa_rx_min_timeout_usec,
|
||||
ipa_ctx->ipa_rx_max_timeout_usec);
|
||||
trace_idle_sleep_exit(sys->ep->client);
|
||||
} else {
|
||||
inactive_cycles = 0;
|
||||
|
@ -1059,7 +1057,7 @@ static void ipa_handle_rx(struct ipa_sys_context *sys)
|
|||
if (sys->len == 0)
|
||||
break;
|
||||
|
||||
} while (inactive_cycles <= POLLING_INACTIVITY_RX);
|
||||
} while (inactive_cycles <= ipa_ctx->ipa_polling_iteration);
|
||||
|
||||
trace_poll_to_intr(sys->ep->client);
|
||||
ipa_rx_switch_to_intr_mode(sys);
|
||||
|
|
|
@ -1244,6 +1244,9 @@ struct ipa_context {
|
|||
/* M-release support to know client pipes */
|
||||
struct ipacm_client_info ipacm_client[IPA_MAX_NUM_PIPES];
|
||||
bool tethered_flow_control;
|
||||
u32 ipa_rx_min_timeout_usec;
|
||||
u32 ipa_rx_max_timeout_usec;
|
||||
u32 ipa_polling_iteration;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1295,6 +1298,8 @@ struct ipa_plat_drv_res {
|
|||
bool skip_uc_pipe_reset;
|
||||
bool use_dma_zone;
|
||||
bool tethered_flow_control;
|
||||
u32 ipa_rx_polling_sleep_msec;
|
||||
u32 ipa_polling_iteration;
|
||||
};
|
||||
|
||||
struct ipa_mem_partition {
|
||||
|
@ -1730,6 +1735,9 @@ void ipa_debugfs_init(void);
|
|||
void ipa_debugfs_remove(void);
|
||||
|
||||
void ipa_dump_buff_internal(void *base, dma_addr_t phy_base, u32 size);
|
||||
|
||||
void ipa_rx_timeout_min_max_calc(u32 *min, u32 *max, s8 time);
|
||||
|
||||
#ifdef IPA_DEBUG
|
||||
#define IPA_DUMP_BUFF(base, phy_base, size) \
|
||||
ipa_dump_buff_internal(base, phy_base, size)
|
||||
|
|
|
@ -43,6 +43,11 @@
|
|||
#define IPA_AGGR_GRAN_MAX (32)
|
||||
#define IPA_EOT_COAL_GRAN_MIN (1)
|
||||
#define IPA_EOT_COAL_GRAN_MAX (16)
|
||||
#define MSEC 1000
|
||||
#define MIN_RX_POLL_TIME 1
|
||||
#define MAX_RX_POLL_TIME 5
|
||||
#define UPPER_CUTOFF 50
|
||||
#define LOWER_CUTOFF 10
|
||||
|
||||
#define IPA_DEFAULT_SYS_YELLOW_WM 32
|
||||
|
||||
|
@ -3622,6 +3627,30 @@ void ipa_dump_buff_internal(void *base, dma_addr_t phy_base, u32 size)
|
|||
IPADBG("END\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* void ipa_rx_timeout_min_max_calc() - calc min max timeout time of rx polling
|
||||
* @time: time fom dtsi entry or from debugfs file system
|
||||
* @min: rx polling min timeout
|
||||
* @max: rx polling max timeout
|
||||
* Maximum time could be of 10Msec allowed.
|
||||
*/
|
||||
void ipa_rx_timeout_min_max_calc(u32 *min, u32 *max, s8 time)
|
||||
{
|
||||
if ((time >= MIN_RX_POLL_TIME) &&
|
||||
(time <= MAX_RX_POLL_TIME)) {
|
||||
*min = (time * MSEC) + LOWER_CUTOFF;
|
||||
*max = (time * MSEC) + UPPER_CUTOFF;
|
||||
} else {
|
||||
/* Setting up the default min max time */
|
||||
IPADBG("Setting up default rx polling timeout\n");
|
||||
*min = (MIN_RX_POLL_TIME * MSEC) +
|
||||
LOWER_CUTOFF;
|
||||
*max = (MIN_RX_POLL_TIME * MSEC) +
|
||||
UPPER_CUTOFF;
|
||||
}
|
||||
IPADBG("Rx polling timeout Min = %u len = %u\n", *min, *max);
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa_pipe_mem_init() - initialize the pipe memory
|
||||
* @start_ofst: start offset
|
||||
|
|
Loading…
Add table
Reference in a new issue