diff options
| -rw-r--r-- | drivers/acpi/cppc_acpi.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 8a0911a13599..8adac69dba3d 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c | |||
| @@ -66,6 +66,7 @@ static u64 comm_base_addr; | |||
| 66 | static int pcc_subspace_idx = -1; | 66 | static int pcc_subspace_idx = -1; |
| 67 | static bool pcc_channel_acquired; | 67 | static bool pcc_channel_acquired; |
| 68 | static ktime_t deadline; | 68 | static ktime_t deadline; |
| 69 | static unsigned int pcc_mpar, pcc_mrtt; | ||
| 69 | 70 | ||
| 70 | /* pcc mapped address + header size + offset within PCC subspace */ | 71 | /* pcc mapped address + header size + offset within PCC subspace */ |
| 71 | #define GET_PCC_VADDR(offs) (pcc_comm_addr + 0x8 + (offs)) | 72 | #define GET_PCC_VADDR(offs) (pcc_comm_addr + 0x8 + (offs)) |
| @@ -85,6 +86,11 @@ static int check_pcc_chan(void) | |||
| 85 | 86 | ||
| 86 | /* Retry in case the remote processor was too slow to catch up. */ | 87 | /* Retry in case the remote processor was too slow to catch up. */ |
| 87 | while (!ktime_after(ktime_get(), next_deadline)) { | 88 | while (!ktime_after(ktime_get(), next_deadline)) { |
| 89 | /* | ||
| 90 | * Per spec, prior to boot the PCC space wil be initialized by | ||
| 91 | * platform and should have set the command completion bit when | ||
| 92 | * PCC can be used by OSPM | ||
| 93 | */ | ||
| 88 | if (readw_relaxed(&generic_comm_base->status) & PCC_CMD_COMPLETE) { | 94 | if (readw_relaxed(&generic_comm_base->status) & PCC_CMD_COMPLETE) { |
| 89 | ret = 0; | 95 | ret = 0; |
| 90 | break; | 96 | break; |
| @@ -104,6 +110,9 @@ static int send_pcc_cmd(u16 cmd) | |||
| 104 | int ret = -EIO; | 110 | int ret = -EIO; |
| 105 | struct acpi_pcct_shared_memory *generic_comm_base = | 111 | struct acpi_pcct_shared_memory *generic_comm_base = |
| 106 | (struct acpi_pcct_shared_memory *) pcc_comm_addr; | 112 | (struct acpi_pcct_shared_memory *) pcc_comm_addr; |
| 113 | static ktime_t last_cmd_cmpl_time, last_mpar_reset; | ||
| 114 | static int mpar_count; | ||
| 115 | unsigned int time_delta; | ||
| 107 | 116 | ||
| 108 | /* | 117 | /* |
| 109 | * For CMD_WRITE we know for a fact the caller should have checked | 118 | * For CMD_WRITE we know for a fact the caller should have checked |
| @@ -115,6 +124,41 @@ static int send_pcc_cmd(u16 cmd) | |||
| 115 | return ret; | 124 | return ret; |
| 116 | } | 125 | } |
| 117 | 126 | ||
| 127 | /* | ||
| 128 | * Handle the Minimum Request Turnaround Time(MRTT) | ||
| 129 | * "The minimum amount of time that OSPM must wait after the completion | ||
| 130 | * of a command before issuing the next command, in microseconds" | ||
| 131 | */ | ||
| 132 | if (pcc_mrtt) { | ||
| 133 | time_delta = ktime_us_delta(ktime_get(), last_cmd_cmpl_time); | ||
| 134 | if (pcc_mrtt > time_delta) | ||
| 135 | udelay(pcc_mrtt - time_delta); | ||
| 136 | } | ||
| 137 | |||
| 138 | /* | ||
| 139 | * Handle the non-zero Maximum Periodic Access Rate(MPAR) | ||
| 140 | * "The maximum number of periodic requests that the subspace channel can | ||
| 141 | * support, reported in commands per minute. 0 indicates no limitation." | ||
| 142 | * | ||
| 143 | * This parameter should be ideally zero or large enough so that it can | ||
| 144 | * handle maximum number of requests that all the cores in the system can | ||
| 145 | * collectively generate. If it is not, we will follow the spec and just | ||
| 146 | * not send the request to the platform after hitting the MPAR limit in | ||
| 147 | * any 60s window | ||
| 148 | */ | ||
| 149 | if (pcc_mpar) { | ||
| 150 | if (mpar_count == 0) { | ||
| 151 | time_delta = ktime_ms_delta(ktime_get(), last_mpar_reset); | ||
| 152 | if (time_delta < 60 * MSEC_PER_SEC) { | ||
| 153 | pr_debug("PCC cmd not sent due to MPAR limit"); | ||
| 154 | return -EIO; | ||
| 155 | } | ||
| 156 | last_mpar_reset = ktime_get(); | ||
| 157 | mpar_count = pcc_mpar; | ||
| 158 | } | ||
| 159 | mpar_count--; | ||
| 160 | } | ||
| 161 | |||
| 118 | /* Write to the shared comm region. */ | 162 | /* Write to the shared comm region. */ |
| 119 | writew_relaxed(cmd, &generic_comm_base->command); | 163 | writew_relaxed(cmd, &generic_comm_base->command); |
| 120 | 164 | ||
| @@ -135,9 +179,17 @@ static int send_pcc_cmd(u16 cmd) | |||
| 135 | * because the actual write()s are done before coming here | 179 | * because the actual write()s are done before coming here |
| 136 | * and the next READ or WRITE will check if the channel | 180 | * and the next READ or WRITE will check if the channel |
| 137 | * is busy/free at the entry of this call. | 181 | * is busy/free at the entry of this call. |
| 182 | * | ||
| 183 | * If Minimum Request Turnaround Time is non-zero, we need | ||
| 184 | * to record the completion time of both READ and WRITE | ||
| 185 | * command for proper handling of MRTT, so we need to check | ||
| 186 | * for pcc_mrtt in addition to CMD_READ | ||
| 138 | */ | 187 | */ |
| 139 | if (cmd == CMD_READ) | 188 | if (cmd == CMD_READ || pcc_mrtt) { |
| 140 | ret = check_pcc_chan(); | 189 | ret = check_pcc_chan(); |
| 190 | if (pcc_mrtt) | ||
| 191 | last_cmd_cmpl_time = ktime_get(); | ||
| 192 | } | ||
| 141 | 193 | ||
| 142 | mbox_client_txdone(pcc_channel, ret); | 194 | mbox_client_txdone(pcc_channel, ret); |
| 143 | return ret; | 195 | return ret; |
| @@ -375,6 +427,8 @@ static int register_pcc_channel(int pcc_subspace_idx) | |||
| 375 | */ | 427 | */ |
| 376 | usecs_lat = NUM_RETRIES * cppc_ss->latency; | 428 | usecs_lat = NUM_RETRIES * cppc_ss->latency; |
| 377 | deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); | 429 | deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); |
| 430 | pcc_mrtt = cppc_ss->min_turnaround_time; | ||
| 431 | pcc_mpar = cppc_ss->max_access_rate; | ||
| 378 | 432 | ||
| 379 | pcc_comm_addr = acpi_os_ioremap(comm_base_addr, len); | 433 | pcc_comm_addr = acpi_os_ioremap(comm_base_addr, len); |
| 380 | if (!pcc_comm_addr) { | 434 | if (!pcc_comm_addr) { |
