On 17 February 2016 at 15:21, Prashanth Prakash <pprakash@xxxxxxxxxxxxxx> wrote: > The ACPI spec defines Minimum Request Turnaround Time(MRTT) and > Maximum Periodic Access Rate(MPAR) to prevent the OSPM from sending > too many requests than the platform can handle. For further details > on these parameters please refer to section 14.1.3 of ACPI 6.0 spec. > > This patch includes MRTT/MPAR in deciding if or when a CPPC request > can be sent to the platform to make sure CPPC implementation is > compliant to the spec. > > Signed-off-by: Prashanth Prakash <pprakash@xxxxxxxxxxxxxx> > --- > drivers/acpi/cppc_acpi.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 55 insertions(+), 1 deletion(-) Acked-by: Ashwin Chaugule <ashwin.chaugule@xxxxxxxxxx> > > diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c > index 8a0911a..f00dc7e 100644 > --- a/drivers/acpi/cppc_acpi.c > +++ b/drivers/acpi/cppc_acpi.c > @@ -66,6 +66,7 @@ static u64 comm_base_addr; > static int pcc_subspace_idx = -1; > static bool pcc_channel_acquired; > static ktime_t deadline; > +static unsigned int pcc_mpar, pcc_mrtt; > > /* pcc mapped address + header size + offset within PCC subspace */ > #define GET_PCC_VADDR(offs) (pcc_comm_addr + 0x8 + (offs)) > @@ -85,6 +86,11 @@ static int check_pcc_chan(void) > > /* Retry in case the remote processor was too slow to catch up. */ > while (!ktime_after(ktime_get(), next_deadline)) { > + /* > + * Per spec, prior to boot the PCC space wil be initialized by > + * platform and should have set the command completion bit when > + * PCC can be used by OSPM > + */ > if (readw_relaxed(&generic_comm_base->status) & PCC_CMD_COMPLETE) { > ret = 0; > break; > @@ -104,6 +110,9 @@ static int send_pcc_cmd(u16 cmd) > int ret = -EIO; > struct acpi_pcct_shared_memory *generic_comm_base = > (struct acpi_pcct_shared_memory *) pcc_comm_addr; > + static ktime_t last_cmd_cmpl_time, last_mpar_reset; > + static int mpar_count; > + unsigned int time_delta; > > /* > * For CMD_WRITE we know for a fact the caller should have checked > @@ -115,6 +124,41 @@ static int send_pcc_cmd(u16 cmd) > return ret; > } > > + /* > + * Handle the Minimum Request Turnaround Time(MRTT) > + * "The minimum amount of time that OSPM must wait after the completion > + * of a command before issuing the next command, in microseconds" > + */ > + if (pcc_mrtt) { > + time_delta = ktime_us_delta(ktime_get(), last_cmd_cmpl_time); > + if (pcc_mrtt > time_delta) > + udelay(pcc_mrtt - time_delta); > + } > + > + /* > + * Handle the non-zero Maximum Periodic Access Rate(MPAR) > + * "The maximum number of periodic requests that the subspace channel can > + * support, reported in commands per minute. 0 indicates no limitation." > + * > + * This parameter should be ideally zero or large enough so that it can > + * handle maximum number of requests that all the cores in the system can > + * collectively generate. If it is not, we will follow the spec and just > + * not send the request to the platform after hitting the MPAR limit in > + * any 60s window > + */ > + if (pcc_mpar) { > + if (mpar_count == 0) { > + time_delta = ktime_ms_delta(ktime_get(), last_mpar_reset); > + if (time_delta < 60 * MSEC_PER_SEC) { > + pr_debug("PCC cmd not sent due to MPAR limit"); > + return -EIO; > + } > + last_mpar_reset = ktime_get(); > + mpar_count = pcc_mpar; > + } > + mpar_count--; > + } > + > /* Write to the shared comm region. */ > writew_relaxed(cmd, &generic_comm_base->command); > > @@ -135,9 +179,17 @@ static int send_pcc_cmd(u16 cmd) > * because the actual write()s are done before coming here > * and the next READ or WRITE will check if the channel > * is busy/free at the entry of this call. > + * > + * If Minimum Request Turnaround Time is non-zero, we need > + * to record the completion time of both READ and WRITE > + * command for proper handling of MRTT, so we need to check > + * for pcc_mrtt in addition to CMD_READ > */ > - if (cmd == CMD_READ) > + if (cmd == CMD_READ || pcc_mrtt) { > ret = check_pcc_chan(); > + if (pcc_mrtt) > + last_cmd_cmpl_time = ktime_get(); > + } > > mbox_client_txdone(pcc_channel, ret); > return ret; > @@ -375,6 +427,8 @@ static int register_pcc_channel(int pcc_subspace_idx) > */ > usecs_lat = NUM_RETRIES * cppc_ss->latency; > deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); > + pcc_mrtt = cppc_ss->min_turnaround_time; > + pcc_mpar = cppc_ss->max_access_rate; > > pcc_comm_addr = acpi_os_ioremap(comm_base_addr, len); > if (!pcc_comm_addr) { > -- > Qualcomm Technologies, Inc. on behalf > of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. > is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. > -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html