aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/cppc_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/cppc_acpi.c')
-rw-r--r--drivers/acpi/cppc_acpi.c66
1 files changed, 31 insertions, 35 deletions
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index 80c123fbfdcf..ed58883d35ee 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -54,6 +54,7 @@ struct cppc_pcc_data {
54 unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; 54 unsigned int pcc_mpar, pcc_mrtt, pcc_nominal;
55 55
56 bool pending_pcc_write_cmd; /* Any pending/batched PCC write cmds? */ 56 bool pending_pcc_write_cmd; /* Any pending/batched PCC write cmds? */
57 bool platform_owns_pcc; /* Ownership of PCC subspace */
57 unsigned int pcc_write_cnt; /* Running count of PCC write commands */ 58 unsigned int pcc_write_cnt; /* Running count of PCC write commands */
58 59
59 /* 60 /*
@@ -79,6 +80,7 @@ struct cppc_pcc_data {
79/* Structure to represent the single PCC channel */ 80/* Structure to represent the single PCC channel */
80static struct cppc_pcc_data pcc_data = { 81static struct cppc_pcc_data pcc_data = {
81 .pcc_subspace_idx = -1, 82 .pcc_subspace_idx = -1,
83 .platform_owns_pcc = true,
82}; 84};
83 85
84/* 86/*
@@ -181,12 +183,15 @@ static struct kobj_type cppc_ktype = {
181 .default_attrs = cppc_attrs, 183 .default_attrs = cppc_attrs,
182}; 184};
183 185
184static int check_pcc_chan(void) 186static int check_pcc_chan(bool chk_err_bit)
185{ 187{
186 int ret = -EIO; 188 int ret = -EIO, status = 0;
187 struct acpi_pcct_shared_memory __iomem *generic_comm_base = pcc_data.pcc_comm_addr; 189 struct acpi_pcct_shared_memory __iomem *generic_comm_base = pcc_data.pcc_comm_addr;
188 ktime_t next_deadline = ktime_add(ktime_get(), pcc_data.deadline); 190 ktime_t next_deadline = ktime_add(ktime_get(), pcc_data.deadline);
189 191
192 if (!pcc_data.platform_owns_pcc)
193 return 0;
194
190 /* Retry in case the remote processor was too slow to catch up. */ 195 /* Retry in case the remote processor was too slow to catch up. */
191 while (!ktime_after(ktime_get(), next_deadline)) { 196 while (!ktime_after(ktime_get(), next_deadline)) {
192 /* 197 /*
@@ -194,8 +199,11 @@ static int check_pcc_chan(void)
194 * platform and should have set the command completion bit when 199 * platform and should have set the command completion bit when
195 * PCC can be used by OSPM 200 * PCC can be used by OSPM
196 */ 201 */
197 if (readw_relaxed(&generic_comm_base->status) & PCC_CMD_COMPLETE) { 202 status = readw_relaxed(&generic_comm_base->status);
203 if (status & PCC_CMD_COMPLETE_MASK) {
198 ret = 0; 204 ret = 0;
205 if (chk_err_bit && (status & PCC_ERROR_MASK))
206 ret = -EIO;
199 break; 207 break;
200 } 208 }
201 /* 209 /*
@@ -205,6 +213,11 @@ static int check_pcc_chan(void)
205 udelay(3); 213 udelay(3);
206 } 214 }
207 215
216 if (likely(!ret))
217 pcc_data.platform_owns_pcc = false;
218 else
219 pr_err("PCC check channel failed. Status=%x\n", status);
220
208 return ret; 221 return ret;
209} 222}
210 223
@@ -234,7 +247,7 @@ static int send_pcc_cmd(u16 cmd)
234 if (pcc_data.pending_pcc_write_cmd) 247 if (pcc_data.pending_pcc_write_cmd)
235 send_pcc_cmd(CMD_WRITE); 248 send_pcc_cmd(CMD_WRITE);
236 249
237 ret = check_pcc_chan(); 250 ret = check_pcc_chan(false);
238 if (ret) 251 if (ret)
239 goto end; 252 goto end;
240 } else /* CMD_WRITE */ 253 } else /* CMD_WRITE */
@@ -282,6 +295,8 @@ static int send_pcc_cmd(u16 cmd)
282 /* Flip CMD COMPLETE bit */ 295 /* Flip CMD COMPLETE bit */
283 writew_relaxed(0, &generic_comm_base->status); 296 writew_relaxed(0, &generic_comm_base->status);
284 297
298 pcc_data.platform_owns_pcc = true;
299
285 /* Ring doorbell */ 300 /* Ring doorbell */
286 ret = mbox_send_message(pcc_data.pcc_channel, &cmd); 301 ret = mbox_send_message(pcc_data.pcc_channel, &cmd);
287 if (ret < 0) { 302 if (ret < 0) {
@@ -290,23 +305,11 @@ static int send_pcc_cmd(u16 cmd)
290 goto end; 305 goto end;
291 } 306 }
292 307
293 /* 308 /* wait for completion and check for PCC errro bit */
294 * For READs we need to ensure the cmd completed to ensure 309 ret = check_pcc_chan(true);
295 * the ensuing read()s can proceed. For WRITEs we dont care 310
296 * because the actual write()s are done before coming here 311 if (pcc_data.pcc_mrtt)
297 * and the next READ or WRITE will check if the channel 312 last_cmd_cmpl_time = ktime_get();
298 * is busy/free at the entry of this call.
299 *
300 * If Minimum Request Turnaround Time is non-zero, we need
301 * to record the completion time of both READ and WRITE
302 * command for proper handling of MRTT, so we need to check
303 * for pcc_mrtt in addition to CMD_READ
304 */
305 if (cmd == CMD_READ || pcc_data.pcc_mrtt) {
306 ret = check_pcc_chan();
307 if (pcc_data.pcc_mrtt)
308 last_cmd_cmpl_time = ktime_get();
309 }
310 313
311 mbox_client_txdone(pcc_data.pcc_channel, ret); 314 mbox_client_txdone(pcc_data.pcc_channel, ret);
312 315
@@ -1059,25 +1062,18 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
1059 */ 1062 */
1060 if (CPC_IN_PCC(desired_reg)) { 1063 if (CPC_IN_PCC(desired_reg)) {
1061 down_read(&pcc_data.pcc_lock); /* BEGIN Phase-I */ 1064 down_read(&pcc_data.pcc_lock); /* BEGIN Phase-I */
1062 /* 1065 if (pcc_data.platform_owns_pcc) {
1063 * If there are pending write commands i.e pending_pcc_write_cmd 1066 ret = check_pcc_chan(false);
1064 * is TRUE, then we know OSPM owns the channel as another CPU
1065 * has already checked for command completion bit and updated
1066 * the corresponding CPC registers
1067 */
1068 if (!pcc_data.pending_pcc_write_cmd) {
1069 ret = check_pcc_chan();
1070 if (ret) { 1067 if (ret) {
1071 up_read(&pcc_data.pcc_lock); 1068 up_read(&pcc_data.pcc_lock);
1072 return ret; 1069 return ret;
1073 } 1070 }
1074 /*
1075 * Update the pending_write to make sure a PCC CMD_READ
1076 * will not arrive and steal the channel during the
1077 * transition to write lock
1078 */
1079 pcc_data.pending_pcc_write_cmd = TRUE;
1080 } 1071 }
1072 /*
1073 * Update the pending_write to make sure a PCC CMD_READ will not
1074 * arrive and steal the channel during the switch to write lock
1075 */
1076 pcc_data.pending_pcc_write_cmd = true;
1081 cpc_desc->write_cmd_id = pcc_data.pcc_write_cnt; 1077 cpc_desc->write_cmd_id = pcc_data.pcc_write_cnt;
1082 cpc_desc->write_cmd_status = 0; 1078 cpc_desc->write_cmd_status = 0;
1083 } 1079 }