1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#define pr_fmt(fmt) "ACPI CPPC: " fmt
35
36#include <linux/delay.h>
37#include <linux/iopoll.h>
38#include <linux/ktime.h>
39#include <linux/rwsem.h>
40#include <linux/wait.h>
41#include <linux/topology.h>
42
43#include <acpi/cppc_acpi.h>
44
45struct cppc_pcc_data {
46 struct mbox_chan *pcc_channel;
47 void __iomem *pcc_comm_addr;
48 bool pcc_channel_acquired;
49 unsigned int deadline_us;
50 unsigned int pcc_mpar, pcc_mrtt, pcc_nominal;
51
52 bool pending_pcc_write_cmd;
53 bool platform_owns_pcc;
54 unsigned int pcc_write_cnt;
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 struct rw_semaphore pcc_lock;
71
72
73 wait_queue_head_t pcc_write_wait_q;
74 ktime_t last_cmd_cmpl_time;
75 ktime_t last_mpar_reset;
76 int mpar_count;
77 int refcount;
78};
79
80
81static struct cppc_pcc_data *pcc_data[MAX_PCC_SUBSPACES];
82
83static DEFINE_PER_CPU(int, cpu_pcc_subspace_idx);
84
85
86
87
88
89
90
91
92static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
93
94
95#define GET_PCC_VADDR(offs, pcc_ss_id) (pcc_data[pcc_ss_id]->pcc_comm_addr + \
96 0x8 + (offs))
97
98
99#define CPC_IN_PCC(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \
100 (cpc)->cpc_entry.reg.space_id == \
101 ACPI_ADR_SPACE_PLATFORM_COMM)
102
103
104#define IS_NULL_REG(reg) ((reg)->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY && \
105 (reg)->address == 0 && \
106 (reg)->bit_width == 0 && \
107 (reg)->bit_offset == 0 && \
108 (reg)->access_width == 0)
109
110
111#define CPC_SUPPORTED(cpc) ((cpc)->type == ACPI_TYPE_INTEGER ? \
112 !!(cpc)->cpc_entry.int_value : \
113 !IS_NULL_REG(&(cpc)->cpc_entry.reg))
114
115
116
117
118
119#define NUM_RETRIES 500ULL
120
121#define define_one_cppc_ro(_name) \
122static struct kobj_attribute _name = \
123__ATTR(_name, 0444, show_##_name, NULL)
124
125#define to_cpc_desc(a) container_of(a, struct cpc_desc, kobj)
126
127#define show_cppc_data(access_fn, struct_name, member_name) \
128 static ssize_t show_##member_name(struct kobject *kobj, \
129 struct kobj_attribute *attr, char *buf) \
130 { \
131 struct cpc_desc *cpc_ptr = to_cpc_desc(kobj); \
132 struct struct_name st_name = {0}; \
133 int ret; \
134 \
135 ret = access_fn(cpc_ptr->cpu_id, &st_name); \
136 if (ret) \
137 return ret; \
138 \
139 return scnprintf(buf, PAGE_SIZE, "%llu\n", \
140 (u64)st_name.member_name); \
141 } \
142 define_one_cppc_ro(member_name)
143
144show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, highest_perf);
145show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_perf);
146show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_perf);
147show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_nonlinear_perf);
148show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, lowest_freq);
149show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_freq);
150
151show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf);
152show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);
153
154static ssize_t show_feedback_ctrs(struct kobject *kobj,
155 struct kobj_attribute *attr, char *buf)
156{
157 struct cpc_desc *cpc_ptr = to_cpc_desc(kobj);
158 struct cppc_perf_fb_ctrs fb_ctrs = {0};
159 int ret;
160
161 ret = cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs);
162 if (ret)
163 return ret;
164
165 return scnprintf(buf, PAGE_SIZE, "ref:%llu del:%llu\n",
166 fb_ctrs.reference, fb_ctrs.delivered);
167}
168define_one_cppc_ro(feedback_ctrs);
169
170static struct attribute *cppc_attrs[] = {
171 &feedback_ctrs.attr,
172 &reference_perf.attr,
173 &wraparound_time.attr,
174 &highest_perf.attr,
175 &lowest_perf.attr,
176 &lowest_nonlinear_perf.attr,
177 &nominal_perf.attr,
178 &nominal_freq.attr,
179 &lowest_freq.attr,
180 NULL
181};
182
183static struct kobj_type cppc_ktype = {
184 .sysfs_ops = &kobj_sysfs_ops,
185 .default_attrs = cppc_attrs,
186};
187
188static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit)
189{
190 int ret, status;
191 struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id];
192 struct acpi_pcct_shared_memory __iomem *generic_comm_base =
193 pcc_ss_data->pcc_comm_addr;
194
195 if (!pcc_ss_data->platform_owns_pcc)
196 return 0;
197
198
199
200
201
202 ret = readw_relaxed_poll_timeout(&generic_comm_base->status, status,
203 status & PCC_CMD_COMPLETE_MASK, 3,
204 pcc_ss_data->deadline_us);
205
206 if (likely(!ret)) {
207 pcc_ss_data->platform_owns_pcc = false;
208 if (chk_err_bit && (status & PCC_ERROR_MASK))
209 ret = -EIO;
210 }
211
212 if (unlikely(ret))
213 pr_err("PCC check channel failed for ss: %d. ret=%d\n",
214 pcc_ss_id, ret);
215
216 return ret;
217}
218
219
220
221
222
223static int send_pcc_cmd(int pcc_ss_id, u16 cmd)
224{
225 int ret = -EIO, i;
226 struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id];
227 struct acpi_pcct_shared_memory __iomem *generic_comm_base =
228 pcc_ss_data->pcc_comm_addr;
229 unsigned int time_delta;
230
231
232
233
234
235 if (cmd == CMD_READ) {
236
237
238
239
240
241 if (pcc_ss_data->pending_pcc_write_cmd)
242 send_pcc_cmd(pcc_ss_id, CMD_WRITE);
243
244 ret = check_pcc_chan(pcc_ss_id, false);
245 if (ret)
246 goto end;
247 } else
248 pcc_ss_data->pending_pcc_write_cmd = FALSE;
249
250
251
252
253
254
255 if (pcc_ss_data->pcc_mrtt) {
256 time_delta = ktime_us_delta(ktime_get(),
257 pcc_ss_data->last_cmd_cmpl_time);
258 if (pcc_ss_data->pcc_mrtt > time_delta)
259 udelay(pcc_ss_data->pcc_mrtt - time_delta);
260 }
261
262
263
264
265
266
267
268
269
270
271
272
273 if (pcc_ss_data->pcc_mpar) {
274 if (pcc_ss_data->mpar_count == 0) {
275 time_delta = ktime_ms_delta(ktime_get(),
276 pcc_ss_data->last_mpar_reset);
277 if ((time_delta < 60 * MSEC_PER_SEC) && pcc_ss_data->last_mpar_reset) {
278 pr_debug("PCC cmd for subspace %d not sent due to MPAR limit",
279 pcc_ss_id);
280 ret = -EIO;
281 goto end;
282 }
283 pcc_ss_data->last_mpar_reset = ktime_get();
284 pcc_ss_data->mpar_count = pcc_ss_data->pcc_mpar;
285 }
286 pcc_ss_data->mpar_count--;
287 }
288
289
290 writew_relaxed(cmd, &generic_comm_base->command);
291
292
293 writew_relaxed(0, &generic_comm_base->status);
294
295 pcc_ss_data->platform_owns_pcc = true;
296
297
298 ret = mbox_send_message(pcc_ss_data->pcc_channel, &cmd);
299 if (ret < 0) {
300 pr_err("Err sending PCC mbox message. ss: %d cmd:%d, ret:%d\n",
301 pcc_ss_id, cmd, ret);
302 goto end;
303 }
304
305
306 ret = check_pcc_chan(pcc_ss_id, true);
307
308 if (pcc_ss_data->pcc_mrtt)
309 pcc_ss_data->last_cmd_cmpl_time = ktime_get();
310
311 if (pcc_ss_data->pcc_channel->mbox->txdone_irq)
312 mbox_chan_txdone(pcc_ss_data->pcc_channel, ret);
313 else
314 mbox_client_txdone(pcc_ss_data->pcc_channel, ret);
315
316end:
317 if (cmd == CMD_WRITE) {
318 if (unlikely(ret)) {
319 for_each_possible_cpu(i) {
320 struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i);
321
322 if (!desc)
323 continue;
324
325 if (desc->write_cmd_id == pcc_ss_data->pcc_write_cnt)
326 desc->write_cmd_status = ret;
327 }
328 }
329 pcc_ss_data->pcc_write_cnt++;
330 wake_up_all(&pcc_ss_data->pcc_write_wait_q);
331 }
332
333 return ret;
334}
335
336static void cppc_chan_tx_done(struct mbox_client *cl, void *msg, int ret)
337{
338 if (ret < 0)
339 pr_debug("TX did not complete: CMD sent:%x, ret:%d\n",
340 *(u16 *)msg, ret);
341 else
342 pr_debug("TX completed. CMD sent:%x, ret:%d\n",
343 *(u16 *)msg, ret);
344}
345
346static struct mbox_client cppc_mbox_cl = {
347 .tx_done = cppc_chan_tx_done,
348 .knows_txdone = true,
349};
350
351static int acpi_get_psd(struct cpc_desc *cpc_ptr, acpi_handle handle)
352{
353 int result = -EFAULT;
354 acpi_status status = AE_OK;
355 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
356 struct acpi_buffer format = {sizeof("NNNNN"), "NNNNN"};
357 struct acpi_buffer state = {0, NULL};
358 union acpi_object *psd = NULL;
359 struct acpi_psd_package *pdomain;
360
361 status = acpi_evaluate_object_typed(handle, "_PSD", NULL,
362 &buffer, ACPI_TYPE_PACKAGE);
363 if (status == AE_NOT_FOUND)
364 return 0;
365 if (ACPI_FAILURE(status))
366 return -ENODEV;
367
368 psd = buffer.pointer;
369 if (!psd || psd->package.count != 1) {
370 pr_debug("Invalid _PSD data\n");
371 goto end;
372 }
373
374 pdomain = &(cpc_ptr->domain_info);
375
376 state.length = sizeof(struct acpi_psd_package);
377 state.pointer = pdomain;
378
379 status = acpi_extract_package(&(psd->package.elements[0]),
380 &format, &state);
381 if (ACPI_FAILURE(status)) {
382 pr_debug("Invalid _PSD data for CPU:%d\n", cpc_ptr->cpu_id);
383 goto end;
384 }
385
386 if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) {
387 pr_debug("Unknown _PSD:num_entries for CPU:%d\n", cpc_ptr->cpu_id);
388 goto end;
389 }
390
391 if (pdomain->revision != ACPI_PSD_REV0_REVISION) {
392 pr_debug("Unknown _PSD:revision for CPU: %d\n", cpc_ptr->cpu_id);
393 goto end;
394 }
395
396 if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
397 pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
398 pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
399 pr_debug("Invalid _PSD:coord_type for CPU:%d\n", cpc_ptr->cpu_id);
400 goto end;
401 }
402
403 result = 0;
404end:
405 kfree(buffer.pointer);
406 return result;
407}
408
409bool acpi_cpc_valid(void)
410{
411 struct cpc_desc *cpc_ptr;
412 int cpu;
413
414 for_each_possible_cpu(cpu) {
415 cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
416 if (!cpc_ptr)
417 return false;
418 }
419
420 return true;
421}
422EXPORT_SYMBOL_GPL(acpi_cpc_valid);
423
424
425
426
427
428
429
430
431int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data)
432{
433 struct cpc_desc *cpc_ptr, *match_cpc_ptr;
434 struct acpi_psd_package *match_pdomain;
435 struct acpi_psd_package *pdomain;
436 int count_target, i;
437
438
439
440
441
442 cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
443 if (!cpc_ptr)
444 return -EFAULT;
445
446 pdomain = &(cpc_ptr->domain_info);
447 cpumask_set_cpu(cpu, cpu_data->shared_cpu_map);
448 if (pdomain->num_processors <= 1)
449 return 0;
450
451
452 count_target = pdomain->num_processors;
453 if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
454 cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ALL;
455 else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL)
456 cpu_data->shared_type = CPUFREQ_SHARED_TYPE_HW;
457 else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
458 cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY;
459
460 for_each_possible_cpu(i) {
461 if (i == cpu)
462 continue;
463
464 match_cpc_ptr = per_cpu(cpc_desc_ptr, i);
465 if (!match_cpc_ptr)
466 goto err_fault;
467
468 match_pdomain = &(match_cpc_ptr->domain_info);
469 if (match_pdomain->domain != pdomain->domain)
470 continue;
471
472
473 if (match_pdomain->num_processors != count_target)
474 goto err_fault;
475
476 if (pdomain->coord_type != match_pdomain->coord_type)
477 goto err_fault;
478
479 cpumask_set_cpu(i, cpu_data->shared_cpu_map);
480 }
481
482 return 0;
483
484err_fault:
485
486 cpumask_clear(cpu_data->shared_cpu_map);
487 cpumask_set_cpu(cpu, cpu_data->shared_cpu_map);
488 cpu_data->shared_type = CPUFREQ_SHARED_TYPE_NONE;
489
490 return -EFAULT;
491}
492EXPORT_SYMBOL_GPL(acpi_get_psd_map);
493
494static int register_pcc_channel(int pcc_ss_idx)
495{
496 struct acpi_pcct_hw_reduced *cppc_ss;
497 u64 usecs_lat;
498
499 if (pcc_ss_idx >= 0) {
500 pcc_data[pcc_ss_idx]->pcc_channel =
501 pcc_mbox_request_channel(&cppc_mbox_cl, pcc_ss_idx);
502
503 if (IS_ERR(pcc_data[pcc_ss_idx]->pcc_channel)) {
504 pr_err("Failed to find PCC channel for subspace %d\n",
505 pcc_ss_idx);
506 return -ENODEV;
507 }
508
509
510
511
512
513
514
515 cppc_ss = (pcc_data[pcc_ss_idx]->pcc_channel)->con_priv;
516
517 if (!cppc_ss) {
518 pr_err("No PCC subspace found for %d CPPC\n",
519 pcc_ss_idx);
520 return -ENODEV;
521 }
522
523
524
525
526
527
528 usecs_lat = NUM_RETRIES * cppc_ss->latency;
529 pcc_data[pcc_ss_idx]->deadline_us = usecs_lat;
530 pcc_data[pcc_ss_idx]->pcc_mrtt = cppc_ss->min_turnaround_time;
531 pcc_data[pcc_ss_idx]->pcc_mpar = cppc_ss->max_access_rate;
532 pcc_data[pcc_ss_idx]->pcc_nominal = cppc_ss->latency;
533
534 pcc_data[pcc_ss_idx]->pcc_comm_addr =
535 acpi_os_ioremap(cppc_ss->base_address, cppc_ss->length);
536 if (!pcc_data[pcc_ss_idx]->pcc_comm_addr) {
537 pr_err("Failed to ioremap PCC comm region mem for %d\n",
538 pcc_ss_idx);
539 return -ENOMEM;
540 }
541
542
543 pcc_data[pcc_ss_idx]->pcc_channel_acquired = true;
544 }
545
546 return 0;
547}
548
549
550
551
552
553
554
555
556
557bool __weak cpc_ffh_supported(void)
558{
559 return false;
560}
561
562
563
564
565
566
567
568
569
570
571
572static int pcc_data_alloc(int pcc_ss_id)
573{
574 if (pcc_ss_id < 0 || pcc_ss_id >= MAX_PCC_SUBSPACES)
575 return -EINVAL;
576
577 if (pcc_data[pcc_ss_id]) {
578 pcc_data[pcc_ss_id]->refcount++;
579 } else {
580 pcc_data[pcc_ss_id] = kzalloc(sizeof(struct cppc_pcc_data),
581 GFP_KERNEL);
582 if (!pcc_data[pcc_ss_id])
583 return -ENOMEM;
584 pcc_data[pcc_ss_id]->refcount++;
585 }
586
587 return 0;
588}
589
590
591static bool is_cppc_supported(int revision, int num_ent)
592{
593 int expected_num_ent;
594
595 switch (revision) {
596 case CPPC_V2_REV:
597 expected_num_ent = CPPC_V2_NUM_ENT;
598 break;
599 case CPPC_V3_REV:
600 expected_num_ent = CPPC_V3_NUM_ENT;
601 break;
602 default:
603 pr_debug("Firmware exports unsupported CPPC revision: %d\n",
604 revision);
605 return false;
606 }
607
608 if (expected_num_ent != num_ent) {
609 pr_debug("Firmware exports %d entries. Expected: %d for CPPC rev:%d\n",
610 num_ent, expected_num_ent, revision);
611 return false;
612 }
613
614 return true;
615}
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663#ifndef init_freq_invariance_cppc
664static inline void init_freq_invariance_cppc(void) { }
665#endif
666
667
668
669
670
671
672
673int acpi_cppc_processor_probe(struct acpi_processor *pr)
674{
675 struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
676 union acpi_object *out_obj, *cpc_obj;
677 struct cpc_desc *cpc_ptr;
678 struct cpc_reg *gas_t;
679 struct device *cpu_dev;
680 acpi_handle handle = pr->handle;
681 unsigned int num_ent, i, cpc_rev;
682 int pcc_subspace_id = -1;
683 acpi_status status;
684 int ret = -EFAULT;
685
686
687 status = acpi_evaluate_object_typed(handle, "_CPC", NULL, &output,
688 ACPI_TYPE_PACKAGE);
689 if (ACPI_FAILURE(status)) {
690 ret = -ENODEV;
691 goto out_buf_free;
692 }
693
694 out_obj = (union acpi_object *) output.pointer;
695
696 cpc_ptr = kzalloc(sizeof(struct cpc_desc), GFP_KERNEL);
697 if (!cpc_ptr) {
698 ret = -ENOMEM;
699 goto out_buf_free;
700 }
701
702
703 cpc_obj = &out_obj->package.elements[0];
704 if (cpc_obj->type == ACPI_TYPE_INTEGER) {
705 num_ent = cpc_obj->integer.value;
706 } else {
707 pr_debug("Unexpected entry type(%d) for NumEntries\n",
708 cpc_obj->type);
709 goto out_free;
710 }
711 cpc_ptr->num_entries = num_ent;
712
713
714 cpc_obj = &out_obj->package.elements[1];
715 if (cpc_obj->type == ACPI_TYPE_INTEGER) {
716 cpc_rev = cpc_obj->integer.value;
717 } else {
718 pr_debug("Unexpected entry type(%d) for Revision\n",
719 cpc_obj->type);
720 goto out_free;
721 }
722 cpc_ptr->version = cpc_rev;
723
724 if (!is_cppc_supported(cpc_rev, num_ent))
725 goto out_free;
726
727
728 for (i = 2; i < num_ent; i++) {
729 cpc_obj = &out_obj->package.elements[i];
730
731 if (cpc_obj->type == ACPI_TYPE_INTEGER) {
732 cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_INTEGER;
733 cpc_ptr->cpc_regs[i-2].cpc_entry.int_value = cpc_obj->integer.value;
734 } else if (cpc_obj->type == ACPI_TYPE_BUFFER) {
735 gas_t = (struct cpc_reg *)
736 cpc_obj->buffer.pointer;
737
738
739
740
741
742
743
744 if (gas_t->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) {
745 if (pcc_subspace_id < 0) {
746 pcc_subspace_id = gas_t->access_width;
747 if (pcc_data_alloc(pcc_subspace_id))
748 goto out_free;
749 } else if (pcc_subspace_id != gas_t->access_width) {
750 pr_debug("Mismatched PCC ids.\n");
751 goto out_free;
752 }
753 } else if (gas_t->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
754 if (gas_t->address) {
755 void __iomem *addr;
756
757 addr = ioremap(gas_t->address, gas_t->bit_width/8);
758 if (!addr)
759 goto out_free;
760 cpc_ptr->cpc_regs[i-2].sys_mem_vaddr = addr;
761 }
762 } else {
763 if (gas_t->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_supported()) {
764
765 pr_debug("Unsupported register type: %d\n", gas_t->space_id);
766 goto out_free;
767 }
768 }
769
770 cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER;
771 memcpy(&cpc_ptr->cpc_regs[i-2].cpc_entry.reg, gas_t, sizeof(*gas_t));
772 } else {
773 pr_debug("Err in entry:%d in CPC table of CPU:%d\n", i, pr->id);
774 goto out_free;
775 }
776 }
777 per_cpu(cpu_pcc_subspace_idx, pr->id) = pcc_subspace_id;
778
779
780
781
782
783
784 for (i = num_ent - 2; i < MAX_CPC_REG_ENT; i++) {
785 cpc_ptr->cpc_regs[i].type = ACPI_TYPE_INTEGER;
786 cpc_ptr->cpc_regs[i].cpc_entry.int_value = 0;
787 }
788
789
790
791 cpc_ptr->cpu_id = pr->id;
792
793
794 ret = acpi_get_psd(cpc_ptr, handle);
795 if (ret)
796 goto out_free;
797
798
799 if (pcc_subspace_id >= 0 && !pcc_data[pcc_subspace_id]->pcc_channel_acquired) {
800 ret = register_pcc_channel(pcc_subspace_id);
801 if (ret)
802 goto out_free;
803
804 init_rwsem(&pcc_data[pcc_subspace_id]->pcc_lock);
805 init_waitqueue_head(&pcc_data[pcc_subspace_id]->pcc_write_wait_q);
806 }
807
808
809 pr_debug("Parsed CPC struct for CPU: %d\n", pr->id);
810
811
812 cpu_dev = get_cpu_device(pr->id);
813 if (!cpu_dev) {
814 ret = -EINVAL;
815 goto out_free;
816 }
817
818
819 per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr;
820
821 ret = kobject_init_and_add(&cpc_ptr->kobj, &cppc_ktype, &cpu_dev->kobj,
822 "acpi_cppc");
823 if (ret) {
824 per_cpu(cpc_desc_ptr, pr->id) = NULL;
825 kobject_put(&cpc_ptr->kobj);
826 goto out_free;
827 }
828
829 init_freq_invariance_cppc();
830
831 kfree(output.pointer);
832 return 0;
833
834out_free:
835
836 for (i = 2; i < cpc_ptr->num_entries; i++) {
837 void __iomem *addr = cpc_ptr->cpc_regs[i-2].sys_mem_vaddr;
838
839 if (addr)
840 iounmap(addr);
841 }
842 kfree(cpc_ptr);
843
844out_buf_free:
845 kfree(output.pointer);
846 return ret;
847}
848EXPORT_SYMBOL_GPL(acpi_cppc_processor_probe);
849
850
851
852
853
854
855
856void acpi_cppc_processor_exit(struct acpi_processor *pr)
857{
858 struct cpc_desc *cpc_ptr;
859 unsigned int i;
860 void __iomem *addr;
861 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, pr->id);
862
863 if (pcc_ss_id >= 0 && pcc_data[pcc_ss_id]) {
864 if (pcc_data[pcc_ss_id]->pcc_channel_acquired) {
865 pcc_data[pcc_ss_id]->refcount--;
866 if (!pcc_data[pcc_ss_id]->refcount) {
867 pcc_mbox_free_channel(pcc_data[pcc_ss_id]->pcc_channel);
868 kfree(pcc_data[pcc_ss_id]);
869 pcc_data[pcc_ss_id] = NULL;
870 }
871 }
872 }
873
874 cpc_ptr = per_cpu(cpc_desc_ptr, pr->id);
875 if (!cpc_ptr)
876 return;
877
878
879 for (i = 2; i < cpc_ptr->num_entries; i++) {
880 addr = cpc_ptr->cpc_regs[i-2].sys_mem_vaddr;
881 if (addr)
882 iounmap(addr);
883 }
884
885 kobject_put(&cpc_ptr->kobj);
886 kfree(cpc_ptr);
887}
888EXPORT_SYMBOL_GPL(acpi_cppc_processor_exit);
889
890
891
892
893
894
895
896
897
898
899
900int __weak cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val)
901{
902 return -ENOTSUPP;
903}
904
905
906
907
908
909
910
911
912
913
914
915int __weak cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val)
916{
917 return -ENOTSUPP;
918}
919
920
921
922
923
924
925
926static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val)
927{
928 int ret_val = 0;
929 void __iomem *vaddr = NULL;
930 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
931 struct cpc_reg *reg = ®_res->cpc_entry.reg;
932
933 if (reg_res->type == ACPI_TYPE_INTEGER) {
934 *val = reg_res->cpc_entry.int_value;
935 return ret_val;
936 }
937
938 *val = 0;
939 if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0)
940 vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id);
941 else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
942 vaddr = reg_res->sys_mem_vaddr;
943 else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE)
944 return cpc_read_ffh(cpu, reg, val);
945 else
946 return acpi_os_read_memory((acpi_physical_address)reg->address,
947 val, reg->bit_width);
948
949 switch (reg->bit_width) {
950 case 8:
951 *val = readb_relaxed(vaddr);
952 break;
953 case 16:
954 *val = readw_relaxed(vaddr);
955 break;
956 case 32:
957 *val = readl_relaxed(vaddr);
958 break;
959 case 64:
960 *val = readq_relaxed(vaddr);
961 break;
962 default:
963 pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n",
964 reg->bit_width, pcc_ss_id);
965 ret_val = -EFAULT;
966 }
967
968 return ret_val;
969}
970
971static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
972{
973 int ret_val = 0;
974 void __iomem *vaddr = NULL;
975 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
976 struct cpc_reg *reg = ®_res->cpc_entry.reg;
977
978 if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0)
979 vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id);
980 else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
981 vaddr = reg_res->sys_mem_vaddr;
982 else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE)
983 return cpc_write_ffh(cpu, reg, val);
984 else
985 return acpi_os_write_memory((acpi_physical_address)reg->address,
986 val, reg->bit_width);
987
988 switch (reg->bit_width) {
989 case 8:
990 writeb_relaxed(val, vaddr);
991 break;
992 case 16:
993 writew_relaxed(val, vaddr);
994 break;
995 case 32:
996 writel_relaxed(val, vaddr);
997 break;
998 case 64:
999 writeq_relaxed(val, vaddr);
1000 break;
1001 default:
1002 pr_debug("Error: Cannot write %u bit width to PCC for ss: %d\n",
1003 reg->bit_width, pcc_ss_id);
1004 ret_val = -EFAULT;
1005 break;
1006 }
1007
1008 return ret_val;
1009}
1010
1011static int cppc_get_perf(int cpunum, enum cppc_regs reg_idx, u64 *perf)
1012{
1013 struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);
1014 struct cpc_register_resource *reg = &cpc_desc->cpc_regs[reg_idx];
1015
1016 if (CPC_IN_PCC(reg)) {
1017 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
1018 struct cppc_pcc_data *pcc_ss_data = NULL;
1019 int ret = 0;
1020
1021 if (pcc_ss_id < 0)
1022 return -EIO;
1023
1024 pcc_ss_data = pcc_data[pcc_ss_id];
1025
1026 down_write(&pcc_ss_data->pcc_lock);
1027
1028 if (send_pcc_cmd(pcc_ss_id, CMD_READ) >= 0)
1029 cpc_read(cpunum, reg, perf);
1030 else
1031 ret = -EIO;
1032
1033 up_write(&pcc_ss_data->pcc_lock);
1034
1035 return ret;
1036 }
1037
1038 cpc_read(cpunum, reg, perf);
1039
1040 return 0;
1041}
1042
1043
1044
1045
1046
1047
1048
1049
1050int cppc_get_desired_perf(int cpunum, u64 *desired_perf)
1051{
1052 return cppc_get_perf(cpunum, DESIRED_PERF, desired_perf);
1053}
1054EXPORT_SYMBOL_GPL(cppc_get_desired_perf);
1055
1056
1057
1058
1059
1060
1061
1062
1063int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf)
1064{
1065 return cppc_get_perf(cpunum, NOMINAL_PERF, nominal_perf);
1066}
1067
1068
1069
1070
1071
1072
1073
1074
1075int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
1076{
1077 struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);
1078 struct cpc_register_resource *highest_reg, *lowest_reg,
1079 *lowest_non_linear_reg, *nominal_reg, *guaranteed_reg,
1080 *low_freq_reg = NULL, *nom_freq_reg = NULL;
1081 u64 high, low, guaranteed, nom, min_nonlinear, low_f = 0, nom_f = 0;
1082 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
1083 struct cppc_pcc_data *pcc_ss_data = NULL;
1084 int ret = 0, regs_in_pcc = 0;
1085
1086 if (!cpc_desc) {
1087 pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
1088 return -ENODEV;
1089 }
1090
1091 highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF];
1092 lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF];
1093 lowest_non_linear_reg = &cpc_desc->cpc_regs[LOW_NON_LINEAR_PERF];
1094 nominal_reg = &cpc_desc->cpc_regs[NOMINAL_PERF];
1095 low_freq_reg = &cpc_desc->cpc_regs[LOWEST_FREQ];
1096 nom_freq_reg = &cpc_desc->cpc_regs[NOMINAL_FREQ];
1097 guaranteed_reg = &cpc_desc->cpc_regs[GUARANTEED_PERF];
1098
1099
1100 if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) ||
1101 CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg) ||
1102 CPC_IN_PCC(low_freq_reg) || CPC_IN_PCC(nom_freq_reg)) {
1103 if (pcc_ss_id < 0) {
1104 pr_debug("Invalid pcc_ss_id\n");
1105 return -ENODEV;
1106 }
1107 pcc_ss_data = pcc_data[pcc_ss_id];
1108 regs_in_pcc = 1;
1109 down_write(&pcc_ss_data->pcc_lock);
1110
1111 if (send_pcc_cmd(pcc_ss_id, CMD_READ) < 0) {
1112 ret = -EIO;
1113 goto out_err;
1114 }
1115 }
1116
1117 cpc_read(cpunum, highest_reg, &high);
1118 perf_caps->highest_perf = high;
1119
1120 cpc_read(cpunum, lowest_reg, &low);
1121 perf_caps->lowest_perf = low;
1122
1123 cpc_read(cpunum, nominal_reg, &nom);
1124 perf_caps->nominal_perf = nom;
1125
1126 if (guaranteed_reg->type != ACPI_TYPE_BUFFER ||
1127 IS_NULL_REG(&guaranteed_reg->cpc_entry.reg)) {
1128 perf_caps->guaranteed_perf = 0;
1129 } else {
1130 cpc_read(cpunum, guaranteed_reg, &guaranteed);
1131 perf_caps->guaranteed_perf = guaranteed;
1132 }
1133
1134 cpc_read(cpunum, lowest_non_linear_reg, &min_nonlinear);
1135 perf_caps->lowest_nonlinear_perf = min_nonlinear;
1136
1137 if (!high || !low || !nom || !min_nonlinear)
1138 ret = -EFAULT;
1139
1140
1141 if (CPC_SUPPORTED(low_freq_reg))
1142 cpc_read(cpunum, low_freq_reg, &low_f);
1143
1144 if (CPC_SUPPORTED(nom_freq_reg))
1145 cpc_read(cpunum, nom_freq_reg, &nom_f);
1146
1147 perf_caps->lowest_freq = low_f;
1148 perf_caps->nominal_freq = nom_f;
1149
1150
1151out_err:
1152 if (regs_in_pcc)
1153 up_write(&pcc_ss_data->pcc_lock);
1154 return ret;
1155}
1156EXPORT_SYMBOL_GPL(cppc_get_perf_caps);
1157
1158
1159
1160
1161
1162
1163
1164
1165int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
1166{
1167 struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);
1168 struct cpc_register_resource *delivered_reg, *reference_reg,
1169 *ref_perf_reg, *ctr_wrap_reg;
1170 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
1171 struct cppc_pcc_data *pcc_ss_data = NULL;
1172 u64 delivered, reference, ref_perf, ctr_wrap_time;
1173 int ret = 0, regs_in_pcc = 0;
1174
1175 if (!cpc_desc) {
1176 pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
1177 return -ENODEV;
1178 }
1179
1180 delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR];
1181 reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR];
1182 ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF];
1183 ctr_wrap_reg = &cpc_desc->cpc_regs[CTR_WRAP_TIME];
1184
1185
1186
1187
1188
1189 if (!CPC_SUPPORTED(ref_perf_reg))
1190 ref_perf_reg = &cpc_desc->cpc_regs[NOMINAL_PERF];
1191
1192
1193 if (CPC_IN_PCC(delivered_reg) || CPC_IN_PCC(reference_reg) ||
1194 CPC_IN_PCC(ctr_wrap_reg) || CPC_IN_PCC(ref_perf_reg)) {
1195 if (pcc_ss_id < 0) {
1196 pr_debug("Invalid pcc_ss_id\n");
1197 return -ENODEV;
1198 }
1199 pcc_ss_data = pcc_data[pcc_ss_id];
1200 down_write(&pcc_ss_data->pcc_lock);
1201 regs_in_pcc = 1;
1202
1203 if (send_pcc_cmd(pcc_ss_id, CMD_READ) < 0) {
1204 ret = -EIO;
1205 goto out_err;
1206 }
1207 }
1208
1209 cpc_read(cpunum, delivered_reg, &delivered);
1210 cpc_read(cpunum, reference_reg, &reference);
1211 cpc_read(cpunum, ref_perf_reg, &ref_perf);
1212
1213
1214
1215
1216
1217
1218 ctr_wrap_time = (u64)(~((u64)0));
1219 if (CPC_SUPPORTED(ctr_wrap_reg))
1220 cpc_read(cpunum, ctr_wrap_reg, &ctr_wrap_time);
1221
1222 if (!delivered || !reference || !ref_perf) {
1223 ret = -EFAULT;
1224 goto out_err;
1225 }
1226
1227 perf_fb_ctrs->delivered = delivered;
1228 perf_fb_ctrs->reference = reference;
1229 perf_fb_ctrs->reference_perf = ref_perf;
1230 perf_fb_ctrs->wraparound_time = ctr_wrap_time;
1231out_err:
1232 if (regs_in_pcc)
1233 up_write(&pcc_ss_data->pcc_lock);
1234 return ret;
1235}
1236EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs);
1237
1238
1239
1240
1241
1242
1243
1244
1245int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
1246{
1247 struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
1248 struct cpc_register_resource *desired_reg;
1249 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
1250 struct cppc_pcc_data *pcc_ss_data = NULL;
1251 int ret = 0;
1252
1253 if (!cpc_desc) {
1254 pr_debug("No CPC descriptor for CPU:%d\n", cpu);
1255 return -ENODEV;
1256 }
1257
1258 desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF];
1259
1260
1261
1262
1263
1264
1265
1266
1267 if (CPC_IN_PCC(desired_reg)) {
1268 if (pcc_ss_id < 0) {
1269 pr_debug("Invalid pcc_ss_id\n");
1270 return -ENODEV;
1271 }
1272 pcc_ss_data = pcc_data[pcc_ss_id];
1273 down_read(&pcc_ss_data->pcc_lock);
1274 if (pcc_ss_data->platform_owns_pcc) {
1275 ret = check_pcc_chan(pcc_ss_id, false);
1276 if (ret) {
1277 up_read(&pcc_ss_data->pcc_lock);
1278 return ret;
1279 }
1280 }
1281
1282
1283
1284
1285 pcc_ss_data->pending_pcc_write_cmd = true;
1286 cpc_desc->write_cmd_id = pcc_ss_data->pcc_write_cnt;
1287 cpc_desc->write_cmd_status = 0;
1288 }
1289
1290
1291
1292
1293
1294 cpc_write(cpu, desired_reg, perf_ctrls->desired_perf);
1295
1296 if (CPC_IN_PCC(desired_reg))
1297 up_read(&pcc_ss_data->pcc_lock);
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344 if (CPC_IN_PCC(desired_reg)) {
1345 if (down_write_trylock(&pcc_ss_data->pcc_lock)) {
1346
1347 if (pcc_ss_data->pending_pcc_write_cmd)
1348 send_pcc_cmd(pcc_ss_id, CMD_WRITE);
1349 up_write(&pcc_ss_data->pcc_lock);
1350 } else
1351
1352 wait_event(pcc_ss_data->pcc_write_wait_q,
1353 cpc_desc->write_cmd_id != pcc_ss_data->pcc_write_cnt);
1354
1355
1356 ret = cpc_desc->write_cmd_status;
1357 }
1358 return ret;
1359}
1360EXPORT_SYMBOL_GPL(cppc_set_perf);
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370unsigned int cppc_get_transition_latency(int cpu_num)
1371{
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383 unsigned int latency_ns = 0;
1384 struct cpc_desc *cpc_desc;
1385 struct cpc_register_resource *desired_reg;
1386 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu_num);
1387 struct cppc_pcc_data *pcc_ss_data;
1388
1389 cpc_desc = per_cpu(cpc_desc_ptr, cpu_num);
1390 if (!cpc_desc)
1391 return CPUFREQ_ETERNAL;
1392
1393 desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF];
1394 if (!CPC_IN_PCC(desired_reg))
1395 return CPUFREQ_ETERNAL;
1396
1397 if (pcc_ss_id < 0)
1398 return CPUFREQ_ETERNAL;
1399
1400 pcc_ss_data = pcc_data[pcc_ss_id];
1401 if (pcc_ss_data->pcc_mpar)
1402 latency_ns = 60 * (1000 * 1000 * 1000 / pcc_ss_data->pcc_mpar);
1403
1404 latency_ns = max(latency_ns, pcc_ss_data->pcc_nominal * 1000);
1405 latency_ns = max(latency_ns, pcc_ss_data->pcc_mrtt * 1000);
1406
1407 return latency_ns;
1408}
1409EXPORT_SYMBOL_GPL(cppc_get_transition_latency);
1410