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.c108
1 files changed, 71 insertions, 37 deletions
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index 2e981732805b..fea58e209b5b 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -62,7 +62,6 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
62/* This layer handles all the PCC specifics for CPPC. */ 62/* This layer handles all the PCC specifics for CPPC. */
63static struct mbox_chan *pcc_channel; 63static struct mbox_chan *pcc_channel;
64static void __iomem *pcc_comm_addr; 64static void __iomem *pcc_comm_addr;
65static u64 comm_base_addr;
66static int pcc_subspace_idx = -1; 65static int pcc_subspace_idx = -1;
67static bool pcc_channel_acquired; 66static bool pcc_channel_acquired;
68static ktime_t deadline; 67static ktime_t deadline;
@@ -394,7 +393,6 @@ EXPORT_SYMBOL_GPL(acpi_get_psd_map);
394static int register_pcc_channel(int pcc_subspace_idx) 393static int register_pcc_channel(int pcc_subspace_idx)
395{ 394{
396 struct acpi_pcct_hw_reduced *cppc_ss; 395 struct acpi_pcct_hw_reduced *cppc_ss;
397 unsigned int len;
398 u64 usecs_lat; 396 u64 usecs_lat;
399 397
400 if (pcc_subspace_idx >= 0) { 398 if (pcc_subspace_idx >= 0) {
@@ -419,12 +417,6 @@ static int register_pcc_channel(int pcc_subspace_idx)
419 return -ENODEV; 417 return -ENODEV;
420 } 418 }
421 419
422 /*
423 * This is the shared communication region
424 * for the OS and Platform to communicate over.
425 */
426 comm_base_addr = cppc_ss->base_address;
427 len = cppc_ss->length;
428 420
429 /* 421 /*
430 * cppc_ss->latency is just a Nominal value. In reality 422 * cppc_ss->latency is just a Nominal value. In reality
@@ -436,7 +428,7 @@ static int register_pcc_channel(int pcc_subspace_idx)
436 pcc_mrtt = cppc_ss->min_turnaround_time; 428 pcc_mrtt = cppc_ss->min_turnaround_time;
437 pcc_mpar = cppc_ss->max_access_rate; 429 pcc_mpar = cppc_ss->max_access_rate;
438 430
439 pcc_comm_addr = acpi_os_ioremap(comm_base_addr, len); 431 pcc_comm_addr = acpi_os_ioremap(cppc_ss->base_address, cppc_ss->length);
440 if (!pcc_comm_addr) { 432 if (!pcc_comm_addr) {
441 pr_err("Failed to ioremap PCC comm region mem\n"); 433 pr_err("Failed to ioremap PCC comm region mem\n");
442 return -ENOMEM; 434 return -ENOMEM;
@@ -545,6 +537,8 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
545 goto out_free; 537 goto out_free;
546 } 538 }
547 539
540 cpc_ptr->num_entries = num_ent;
541
548 /* Second entry should be revision. */ 542 /* Second entry should be revision. */
549 cpc_obj = &out_obj->package.elements[1]; 543 cpc_obj = &out_obj->package.elements[1];
550 if (cpc_obj->type == ACPI_TYPE_INTEGER) { 544 if (cpc_obj->type == ACPI_TYPE_INTEGER) {
@@ -585,7 +579,16 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
585 pr_debug("Mismatched PCC ids.\n"); 579 pr_debug("Mismatched PCC ids.\n");
586 goto out_free; 580 goto out_free;
587 } 581 }
588 } else if (gas_t->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) { 582 } else if (gas_t->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
583 if (gas_t->address) {
584 void __iomem *addr;
585
586 addr = ioremap(gas_t->address, gas_t->bit_width/8);
587 if (!addr)
588 goto out_free;
589 cpc_ptr->cpc_regs[i-2].sys_mem_vaddr = addr;
590 }
591 } else {
589 /* Support only PCC and SYS MEM type regs */ 592 /* Support only PCC and SYS MEM type regs */
590 pr_debug("Unsupported register type: %d\n", gas_t->space_id); 593 pr_debug("Unsupported register type: %d\n", gas_t->space_id);
591 goto out_free; 594 goto out_free;
@@ -623,6 +626,13 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
623 return 0; 626 return 0;
624 627
625out_free: 628out_free:
629 /* Free all the mapped sys mem areas for this CPU */
630 for (i = 2; i < cpc_ptr->num_entries; i++) {
631 void __iomem *addr = cpc_ptr->cpc_regs[i-2].sys_mem_vaddr;
632
633 if (addr)
634 iounmap(addr);
635 }
626 kfree(cpc_ptr); 636 kfree(cpc_ptr);
627 637
628out_buf_free: 638out_buf_free:
@@ -640,7 +650,17 @@ EXPORT_SYMBOL_GPL(acpi_cppc_processor_probe);
640void acpi_cppc_processor_exit(struct acpi_processor *pr) 650void acpi_cppc_processor_exit(struct acpi_processor *pr)
641{ 651{
642 struct cpc_desc *cpc_ptr; 652 struct cpc_desc *cpc_ptr;
653 unsigned int i;
654 void __iomem *addr;
643 cpc_ptr = per_cpu(cpc_desc_ptr, pr->id); 655 cpc_ptr = per_cpu(cpc_desc_ptr, pr->id);
656
657 /* Free all the mapped sys mem areas for this CPU */
658 for (i = 2; i < cpc_ptr->num_entries; i++) {
659 addr = cpc_ptr->cpc_regs[i-2].sys_mem_vaddr;
660 if (addr)
661 iounmap(addr);
662 }
663
644 kfree(cpc_ptr); 664 kfree(cpc_ptr);
645} 665}
646EXPORT_SYMBOL_GPL(acpi_cppc_processor_exit); 666EXPORT_SYMBOL_GPL(acpi_cppc_processor_exit);
@@ -651,15 +671,27 @@ EXPORT_SYMBOL_GPL(acpi_cppc_processor_exit);
651 * we can directly write to it. 671 * we can directly write to it.
652 */ 672 */
653 673
654static int cpc_read(struct cpc_reg *reg, u64 *val) 674static int cpc_read(struct cpc_register_resource *reg_res, u64 *val)
655{ 675{
656 int ret_val = 0; 676 int ret_val = 0;
677 void __iomem *vaddr = 0;
678 struct cpc_reg *reg = &reg_res->cpc_entry.reg;
679
680 if (reg_res->type == ACPI_TYPE_INTEGER) {
681 *val = reg_res->cpc_entry.int_value;
682 return ret_val;
683 }
657 684
658 *val = 0; 685 *val = 0;
659 if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { 686 if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM)
660 void __iomem *vaddr = GET_PCC_VADDR(reg->address); 687 vaddr = GET_PCC_VADDR(reg->address);
688 else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
689 vaddr = reg_res->sys_mem_vaddr;
690 else
691 return acpi_os_read_memory((acpi_physical_address)reg->address,
692 val, reg->bit_width);
661 693
662 switch (reg->bit_width) { 694 switch (reg->bit_width) {
663 case 8: 695 case 8:
664 *val = readb_relaxed(vaddr); 696 *val = readb_relaxed(vaddr);
665 break; 697 break;
@@ -674,23 +706,28 @@ static int cpc_read(struct cpc_reg *reg, u64 *val)
674 break; 706 break;
675 default: 707 default:
676 pr_debug("Error: Cannot read %u bit width from PCC\n", 708 pr_debug("Error: Cannot read %u bit width from PCC\n",
677 reg->bit_width); 709 reg->bit_width);
678 ret_val = -EFAULT; 710 ret_val = -EFAULT;
679 } 711 }
680 } else 712
681 ret_val = acpi_os_read_memory((acpi_physical_address)reg->address,
682 val, reg->bit_width);
683 return ret_val; 713 return ret_val;
684} 714}
685 715
686static int cpc_write(struct cpc_reg *reg, u64 val) 716static int cpc_write(struct cpc_register_resource *reg_res, u64 val)
687{ 717{
688 int ret_val = 0; 718 int ret_val = 0;
719 void __iomem *vaddr = 0;
720 struct cpc_reg *reg = &reg_res->cpc_entry.reg;
689 721
690 if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { 722 if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM)
691 void __iomem *vaddr = GET_PCC_VADDR(reg->address); 723 vaddr = GET_PCC_VADDR(reg->address);
724 else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
725 vaddr = reg_res->sys_mem_vaddr;
726 else
727 return acpi_os_write_memory((acpi_physical_address)reg->address,
728 val, reg->bit_width);
692 729
693 switch (reg->bit_width) { 730 switch (reg->bit_width) {
694 case 8: 731 case 8:
695 writeb_relaxed(val, vaddr); 732 writeb_relaxed(val, vaddr);
696 break; 733 break;
@@ -705,13 +742,11 @@ static int cpc_write(struct cpc_reg *reg, u64 val)
705 break; 742 break;
706 default: 743 default:
707 pr_debug("Error: Cannot write %u bit width to PCC\n", 744 pr_debug("Error: Cannot write %u bit width to PCC\n",
708 reg->bit_width); 745 reg->bit_width);
709 ret_val = -EFAULT; 746 ret_val = -EFAULT;
710 break; 747 break;
711 } 748 }
712 } else 749
713 ret_val = acpi_os_write_memory((acpi_physical_address)reg->address,
714 val, reg->bit_width);
715 return ret_val; 750 return ret_val;
716} 751}
717 752
@@ -754,16 +789,16 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
754 } 789 }
755 } 790 }
756 791
757 cpc_read(&highest_reg->cpc_entry.reg, &high); 792 cpc_read(highest_reg, &high);
758 perf_caps->highest_perf = high; 793 perf_caps->highest_perf = high;
759 794
760 cpc_read(&lowest_reg->cpc_entry.reg, &low); 795 cpc_read(lowest_reg, &low);
761 perf_caps->lowest_perf = low; 796 perf_caps->lowest_perf = low;
762 797
763 cpc_read(&ref_perf->cpc_entry.reg, &ref); 798 cpc_read(ref_perf, &ref);
764 perf_caps->reference_perf = ref; 799 perf_caps->reference_perf = ref;
765 800
766 cpc_read(&nom_perf->cpc_entry.reg, &nom); 801 cpc_read(nom_perf, &nom);
767 perf_caps->nominal_perf = nom; 802 perf_caps->nominal_perf = nom;
768 803
769 if (!ref) 804 if (!ref)
@@ -804,7 +839,7 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
804 839
805 /* Are any of the regs PCC ?*/ 840 /* Are any of the regs PCC ?*/
806 if ((delivered_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) || 841 if ((delivered_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) ||
807 (reference_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM)) { 842 (reference_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM)) {
808 /* Ring doorbell once to update PCC subspace */ 843 /* Ring doorbell once to update PCC subspace */
809 if (send_pcc_cmd(CMD_READ) < 0) { 844 if (send_pcc_cmd(CMD_READ) < 0) {
810 ret = -EIO; 845 ret = -EIO;
@@ -812,8 +847,8 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
812 } 847 }
813 } 848 }
814 849
815 cpc_read(&delivered_reg->cpc_entry.reg, &delivered); 850 cpc_read(delivered_reg, &delivered);
816 cpc_read(&reference_reg->cpc_entry.reg, &reference); 851 cpc_read(reference_reg, &reference);
817 852
818 if (!delivered || !reference) { 853 if (!delivered || !reference) {
819 ret = -EFAULT; 854 ret = -EFAULT;
@@ -868,7 +903,7 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
868 * Skip writing MIN/MAX until Linux knows how to come up with 903 * Skip writing MIN/MAX until Linux knows how to come up with
869 * useful values. 904 * useful values.
870 */ 905 */
871 cpc_write(&desired_reg->cpc_entry.reg, perf_ctrls->desired_perf); 906 cpc_write(desired_reg, perf_ctrls->desired_perf);
872 907
873 /* Is this a PCC reg ?*/ 908 /* Is this a PCC reg ?*/
874 if (desired_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { 909 if (desired_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) {
@@ -878,7 +913,6 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
878 } 913 }
879busy_channel: 914busy_channel:
880 spin_unlock(&pcc_lock); 915 spin_unlock(&pcc_lock);
881
882 return ret; 916 return ret;
883} 917}
884EXPORT_SYMBOL_GPL(cppc_set_perf); 918EXPORT_SYMBOL_GPL(cppc_set_perf);