aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Cherian <george.cherian@cavium.com>2017-10-11 04:54:58 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-11-08 18:39:54 -0500
commit85b1407bf6d2f4a1583e9201b8c163703df733cc (patch)
tree7917e008abdc2af39e9be55cf1cee856d4718ee3
parentc4b766c2f3fc4d847f16a3735913b7edf3136343 (diff)
ACPI / CPPC: Make CPPC ACPI driver aware of PCC subspace IDs
Based on ACPI 6.2 Section 8.4.7.1.9 If the PCC register space is used, all PCC registers, for all processors in the same performance domain (as defined by _PSD), must be defined to be in the same subspace. Based on Section 14.1 of ACPI specification, it is possible to have a maximum of 256 PCC subspace IDs. Add support of multiple PCC subspace ID instead of using a single global pcc_data structure. While at that, fix the time_delta check in send_pcc_cmd() so that last_mpar_reset and mpar_count are initialized properly. Signed-off-by: George Cherian <george.cherian@cavium.com> Reviewed-by: Prashanth Prakash <pprakash@codeaurora.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/cppc_acpi.c240
1 files changed, 151 insertions, 89 deletions
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index e5b47f032d9a..21c28433c590 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -48,7 +48,6 @@
48struct cppc_pcc_data { 48struct cppc_pcc_data {
49 struct mbox_chan *pcc_channel; 49 struct mbox_chan *pcc_channel;
50 void __iomem *pcc_comm_addr; 50 void __iomem *pcc_comm_addr;
51 int pcc_subspace_idx;
52 bool pcc_channel_acquired; 51 bool pcc_channel_acquired;
53 ktime_t deadline; 52 ktime_t deadline;
54 unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; 53 unsigned int pcc_mpar, pcc_mrtt, pcc_nominal;
@@ -75,13 +74,16 @@ struct cppc_pcc_data {
75 74
76 /* Wait queue for CPUs whose requests were batched */ 75 /* Wait queue for CPUs whose requests were batched */
77 wait_queue_head_t pcc_write_wait_q; 76 wait_queue_head_t pcc_write_wait_q;
77 ktime_t last_cmd_cmpl_time;
78 ktime_t last_mpar_reset;
79 int mpar_count;
80 int refcount;
78}; 81};
79 82
80/* Structure to represent the single PCC channel */ 83/* Array to represent the PCC channel per subspace id */
81static struct cppc_pcc_data pcc_data = { 84static struct cppc_pcc_data *pcc_data[MAX_PCC_SUBSPACES];
82 .pcc_subspace_idx = -1, 85/* The cpu_pcc_subspace_idx containsper CPU subspace id */
83 .platform_owns_pcc = true, 86static DEFINE_PER_CPU(int, cpu_pcc_subspace_idx);
84};
85 87
86/* 88/*
87 * The cpc_desc structure contains the ACPI register details 89 * The cpc_desc structure contains the ACPI register details
@@ -93,7 +95,8 @@ static struct cppc_pcc_data pcc_data = {
93static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr); 95static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
94 96
95/* pcc mapped address + header size + offset within PCC subspace */ 97/* pcc mapped address + header size + offset within PCC subspace */
96#define GET_PCC_VADDR(offs) (pcc_data.pcc_comm_addr + 0x8 + (offs)) 98#define GET_PCC_VADDR(offs, pcc_ss_id) (pcc_data[pcc_ss_id]->pcc_comm_addr + \
99 0x8 + (offs))
97 100
98/* Check if a CPC register is in PCC */ 101/* Check if a CPC register is in PCC */
99#define CPC_IN_PCC(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \ 102#define CPC_IN_PCC(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \
@@ -188,13 +191,16 @@ static struct kobj_type cppc_ktype = {
188 .default_attrs = cppc_attrs, 191 .default_attrs = cppc_attrs,
189}; 192};
190 193
191static int check_pcc_chan(bool chk_err_bit) 194static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit)
192{ 195{
193 int ret = -EIO, status = 0; 196 int ret = -EIO, status = 0;
194 struct acpi_pcct_shared_memory __iomem *generic_comm_base = pcc_data.pcc_comm_addr; 197 struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id];
195 ktime_t next_deadline = ktime_add(ktime_get(), pcc_data.deadline); 198 struct acpi_pcct_shared_memory __iomem *generic_comm_base =
199 pcc_ss_data->pcc_comm_addr;
200 ktime_t next_deadline = ktime_add(ktime_get(),
201 pcc_ss_data->deadline);
196 202
197 if (!pcc_data.platform_owns_pcc) 203 if (!pcc_ss_data->platform_owns_pcc)
198 return 0; 204 return 0;
199 205
200 /* Retry in case the remote processor was too slow to catch up. */ 206 /* Retry in case the remote processor was too slow to catch up. */
@@ -219,7 +225,7 @@ static int check_pcc_chan(bool chk_err_bit)
219 } 225 }
220 226
221 if (likely(!ret)) 227 if (likely(!ret))
222 pcc_data.platform_owns_pcc = false; 228 pcc_ss_data->platform_owns_pcc = false;
223 else 229 else
224 pr_err("PCC check channel failed. Status=%x\n", status); 230 pr_err("PCC check channel failed. Status=%x\n", status);
225 231
@@ -230,13 +236,12 @@ static int check_pcc_chan(bool chk_err_bit)
230 * This function transfers the ownership of the PCC to the platform 236 * This function transfers the ownership of the PCC to the platform
231 * So it must be called while holding write_lock(pcc_lock) 237 * So it must be called while holding write_lock(pcc_lock)
232 */ 238 */
233static int send_pcc_cmd(u16 cmd) 239static int send_pcc_cmd(int pcc_ss_id, u16 cmd)
234{ 240{
235 int ret = -EIO, i; 241 int ret = -EIO, i;
242 struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id];
236 struct acpi_pcct_shared_memory *generic_comm_base = 243 struct acpi_pcct_shared_memory *generic_comm_base =
237 (struct acpi_pcct_shared_memory *) pcc_data.pcc_comm_addr; 244 (struct acpi_pcct_shared_memory *)pcc_ss_data->pcc_comm_addr;
238 static ktime_t last_cmd_cmpl_time, last_mpar_reset;
239 static int mpar_count;
240 unsigned int time_delta; 245 unsigned int time_delta;
241 246
242 /* 247 /*
@@ -249,24 +254,25 @@ static int send_pcc_cmd(u16 cmd)
249 * before write completion, so first send a WRITE command to 254 * before write completion, so first send a WRITE command to
250 * platform 255 * platform
251 */ 256 */
252 if (pcc_data.pending_pcc_write_cmd) 257 if (pcc_ss_data->pending_pcc_write_cmd)
253 send_pcc_cmd(CMD_WRITE); 258 send_pcc_cmd(pcc_ss_id, CMD_WRITE);
254 259
255 ret = check_pcc_chan(false); 260 ret = check_pcc_chan(pcc_ss_id, false);
256 if (ret) 261 if (ret)
257 goto end; 262 goto end;
258 } else /* CMD_WRITE */ 263 } else /* CMD_WRITE */
259 pcc_data.pending_pcc_write_cmd = FALSE; 264 pcc_ss_data->pending_pcc_write_cmd = FALSE;
260 265
261 /* 266 /*
262 * Handle the Minimum Request Turnaround Time(MRTT) 267 * Handle the Minimum Request Turnaround Time(MRTT)
263 * "The minimum amount of time that OSPM must wait after the completion 268 * "The minimum amount of time that OSPM must wait after the completion
264 * of a command before issuing the next command, in microseconds" 269 * of a command before issuing the next command, in microseconds"
265 */ 270 */
266 if (pcc_data.pcc_mrtt) { 271 if (pcc_ss_data->pcc_mrtt) {
267 time_delta = ktime_us_delta(ktime_get(), last_cmd_cmpl_time); 272 time_delta = ktime_us_delta(ktime_get(),
268 if (pcc_data.pcc_mrtt > time_delta) 273 pcc_ss_data->last_cmd_cmpl_time);
269 udelay(pcc_data.pcc_mrtt - time_delta); 274 if (pcc_ss_data->pcc_mrtt > time_delta)
275 udelay(pcc_ss_data->pcc_mrtt - time_delta);
270 } 276 }
271 277
272 /* 278 /*
@@ -280,18 +286,19 @@ static int send_pcc_cmd(u16 cmd)
280 * not send the request to the platform after hitting the MPAR limit in 286 * not send the request to the platform after hitting the MPAR limit in
281 * any 60s window 287 * any 60s window
282 */ 288 */
283 if (pcc_data.pcc_mpar) { 289 if (pcc_ss_data->pcc_mpar) {
284 if (mpar_count == 0) { 290 if (pcc_ss_data->mpar_count == 0) {
285 time_delta = ktime_ms_delta(ktime_get(), last_mpar_reset); 291 time_delta = ktime_ms_delta(ktime_get(),
286 if (time_delta < 60 * MSEC_PER_SEC) { 292 pcc_ss_data->last_mpar_reset);
293 if ((time_delta < 60 * MSEC_PER_SEC) && pcc_ss_data->last_mpar_reset) {
287 pr_debug("PCC cmd not sent due to MPAR limit"); 294 pr_debug("PCC cmd not sent due to MPAR limit");
288 ret = -EIO; 295 ret = -EIO;
289 goto end; 296 goto end;
290 } 297 }
291 last_mpar_reset = ktime_get(); 298 pcc_ss_data->last_mpar_reset = ktime_get();
292 mpar_count = pcc_data.pcc_mpar; 299 pcc_ss_data->mpar_count = pcc_ss_data->pcc_mpar;
293 } 300 }
294 mpar_count--; 301 pcc_ss_data->mpar_count--;
295 } 302 }
296 303
297 /* Write to the shared comm region. */ 304 /* Write to the shared comm region. */
@@ -300,10 +307,10 @@ static int send_pcc_cmd(u16 cmd)
300 /* Flip CMD COMPLETE bit */ 307 /* Flip CMD COMPLETE bit */
301 writew_relaxed(0, &generic_comm_base->status); 308 writew_relaxed(0, &generic_comm_base->status);
302 309
303 pcc_data.platform_owns_pcc = true; 310 pcc_ss_data->platform_owns_pcc = true;
304 311
305 /* Ring doorbell */ 312 /* Ring doorbell */
306 ret = mbox_send_message(pcc_data.pcc_channel, &cmd); 313 ret = mbox_send_message(pcc_ss_data->pcc_channel, &cmd);
307 if (ret < 0) { 314 if (ret < 0) {
308 pr_err("Err sending PCC mbox message. cmd:%d, ret:%d\n", 315 pr_err("Err sending PCC mbox message. cmd:%d, ret:%d\n",
309 cmd, ret); 316 cmd, ret);
@@ -311,15 +318,15 @@ static int send_pcc_cmd(u16 cmd)
311 } 318 }
312 319
313 /* wait for completion and check for PCC errro bit */ 320 /* wait for completion and check for PCC errro bit */
314 ret = check_pcc_chan(true); 321 ret = check_pcc_chan(pcc_ss_id, true);
315 322
316 if (pcc_data.pcc_mrtt) 323 if (pcc_ss_data->pcc_mrtt)
317 last_cmd_cmpl_time = ktime_get(); 324 pcc_ss_data->last_cmd_cmpl_time = ktime_get();
318 325
319 if (pcc_data.pcc_channel->mbox->txdone_irq) 326 if (pcc