Lines Matching +full:negative +full:- +full:phase
1 // SPDX-License-Identifier: GPL-2.0-only
15 * P-state scale which is tied to CPU frequency only. In brief, the basic
18 * - OS makes a CPU performance request. (Can provide min and max bounds)
20 * - Platform (such as BMC) is free to optimize request within requested bounds
23 * - Platform conveys its decision back to OS
69 * For non-performance critical usecases(init)
97 #define GET_PCC_VADDR(offs, pcc_ss_id) (pcc_data[pcc_ss_id]->pcc_channel->shmem + \
101 #define CPC_IN_PCC(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \
102 (cpc)->cpc_entry.reg.space_id == \
106 #define CPC_IN_FFH(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \
107 (cpc)->cpc_entry.reg.space_id == \
111 #define CPC_IN_SYSTEM_MEMORY(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \
112 (cpc)->cpc_entry.reg.space_id == \
116 #define CPC_IN_SYSTEM_IO(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \
117 (cpc)->cpc_entry.reg.space_id == \
121 #define IS_NULL_REG(reg) ((reg)->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY && \
122 (reg)->address == 0 && \
123 (reg)->bit_width == 0 && \
124 (reg)->bit_offset == 0 && \
125 (reg)->access_width == 0)
128 #define CPC_SUPPORTED(cpc) ((cpc)->type == ACPI_TYPE_INTEGER ? \
129 !!(cpc)->cpc_entry.int_value : \
130 !IS_NULL_REG(&(cpc)->cpc_entry.reg))
133 * Each bit indicates the optionality of the register in per-cpu
140 * Use the index of the register in per-cpu cpc_regs[] to check if
168 ret = access_fn(cpc_ptr->cpu_id, &st_name); \
189 #define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_wid…
192 #define MASK_VAL_READ(reg, val) (((val) >> (reg)->bit_offset) & \
193 GENMASK(((reg)->bit_width) - 1, 0))
195 ((((val) & GENMASK(((reg)->bit_width) - 1, 0)) << (reg)->bit_offset) | \
196 ((prev_val) & ~(GENMASK(((reg)->bit_width) - 1, 0) << (reg)->bit_offset))) \
205 ret = cppc_get_perf_ctrs(cpc_ptr->cpu_id, &fb_ctrs); in show_feedback_ctrs()
239 pcc_ss_data->pcc_channel->shmem; in check_pcc_chan()
241 if (!pcc_ss_data->platform_owns_pcc) in check_pcc_chan()
248 ret = readw_relaxed_poll_timeout(&generic_comm_base->status, status, in check_pcc_chan()
250 pcc_ss_data->deadline_us); in check_pcc_chan()
253 pcc_ss_data->platform_owns_pcc = false; in check_pcc_chan()
255 ret = -EIO; in check_pcc_chan()
271 int ret = -EIO, i; in send_pcc_cmd()
274 pcc_ss_data->pcc_channel->shmem; in send_pcc_cmd()
287 if (pcc_ss_data->pending_pcc_write_cmd) in send_pcc_cmd()
294 pcc_ss_data->pending_pcc_write_cmd = FALSE; in send_pcc_cmd()
301 if (pcc_ss_data->pcc_mrtt) { in send_pcc_cmd()
303 pcc_ss_data->last_cmd_cmpl_time); in send_pcc_cmd()
304 if (pcc_ss_data->pcc_mrtt > time_delta) in send_pcc_cmd()
305 udelay(pcc_ss_data->pcc_mrtt - time_delta); in send_pcc_cmd()
309 * Handle the non-zero Maximum Periodic Access Rate(MPAR) in send_pcc_cmd()
319 if (pcc_ss_data->pcc_mpar) { in send_pcc_cmd()
320 if (pcc_ss_data->mpar_count == 0) { in send_pcc_cmd()
322 pcc_ss_data->last_mpar_reset); in send_pcc_cmd()
323 if ((time_delta < 60 * MSEC_PER_SEC) && pcc_ss_data->last_mpar_reset) { in send_pcc_cmd()
326 ret = -EIO; in send_pcc_cmd()
329 pcc_ss_data->last_mpar_reset = ktime_get(); in send_pcc_cmd()
330 pcc_ss_data->mpar_count = pcc_ss_data->pcc_mpar; in send_pcc_cmd()
332 pcc_ss_data->mpar_count--; in send_pcc_cmd()
336 writew_relaxed(cmd, &generic_comm_base->command); in send_pcc_cmd()
339 writew_relaxed(0, &generic_comm_base->status); in send_pcc_cmd()
341 pcc_ss_data->platform_owns_pcc = true; in send_pcc_cmd()
344 ret = mbox_send_message(pcc_ss_data->pcc_channel->mchan, &cmd); in send_pcc_cmd()
354 if (pcc_ss_data->pcc_mrtt) in send_pcc_cmd()
355 pcc_ss_data->last_cmd_cmpl_time = ktime_get(); in send_pcc_cmd()
357 if (pcc_ss_data->pcc_channel->mchan->mbox->txdone_irq) in send_pcc_cmd()
358 mbox_chan_txdone(pcc_ss_data->pcc_channel->mchan, ret); in send_pcc_cmd()
360 mbox_client_txdone(pcc_ss_data->pcc_channel->mchan, ret); in send_pcc_cmd()
371 if (desc->write_cmd_id == pcc_ss_data->pcc_write_cnt) in send_pcc_cmd()
372 desc->write_cmd_status = ret; in send_pcc_cmd()
375 pcc_ss_data->pcc_write_cnt++; in send_pcc_cmd()
376 wake_up_all(&pcc_ss_data->pcc_write_wait_q); in send_pcc_cmd()
399 int result = -EFAULT; in acpi_get_psd()
412 return -ENODEV; in acpi_get_psd()
415 if (!psd || psd->package.count != 1) { in acpi_get_psd()
420 pdomain = &(cpc_ptr->domain_info); in acpi_get_psd()
425 status = acpi_extract_package(&(psd->package.elements[0]), in acpi_get_psd()
428 pr_debug("Invalid _PSD data for CPU:%d\n", cpc_ptr->cpu_id); in acpi_get_psd()
432 if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) { in acpi_get_psd()
433 pr_debug("Unknown _PSD:num_entries for CPU:%d\n", cpc_ptr->cpu_id); in acpi_get_psd()
437 if (pdomain->revision != ACPI_PSD_REV0_REVISION) { in acpi_get_psd()
438 pr_debug("Unknown _PSD:revision for CPU: %d\n", cpc_ptr->cpu_id); in acpi_get_psd()
442 if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL && in acpi_get_psd()
443 pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY && in acpi_get_psd()
444 pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) { in acpi_get_psd()
445 pr_debug("Invalid _PSD:coord_type for CPU:%d\n", cpc_ptr->cpu_id); in acpi_get_psd()
481 desired_reg = &cpc_ptr->cpc_regs[DESIRED_PERF]; in cppc_allow_fast_switch()
492 * acpi_get_psd_map - Map the CPUs in the freq domain of a given cpu
496 * Return: 0 for success or negative value for err.
506 * Now that we have _PSD data from all CPUs, let's setup P-state in acpi_get_psd_map()
511 return -EFAULT; in acpi_get_psd_map()
513 pdomain = &(cpc_ptr->domain_info); in acpi_get_psd_map()
514 cpumask_set_cpu(cpu, cpu_data->shared_cpu_map); in acpi_get_psd_map()
515 if (pdomain->num_processors <= 1) in acpi_get_psd_map()
519 count_target = pdomain->num_processors; in acpi_get_psd_map()
520 if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL) in acpi_get_psd_map()
521 cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ALL; in acpi_get_psd_map()
522 else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL) in acpi_get_psd_map()
523 cpu_data->shared_type = CPUFREQ_SHARED_TYPE_HW; in acpi_get_psd_map()
524 else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY) in acpi_get_psd_map()
525 cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY; in acpi_get_psd_map()
535 match_pdomain = &(match_cpc_ptr->domain_info); in acpi_get_psd_map()
536 if (match_pdomain->domain != pdomain->domain) in acpi_get_psd_map()
540 if (match_pdomain->num_processors != count_target) in acpi_get_psd_map()
543 if (pdomain->coord_type != match_pdomain->coord_type) in acpi_get_psd_map()
546 cpumask_set_cpu(i, cpu_data->shared_cpu_map); in acpi_get_psd_map()
553 cpumask_clear(cpu_data->shared_cpu_map); in acpi_get_psd_map()
554 cpumask_set_cpu(cpu, cpu_data->shared_cpu_map); in acpi_get_psd_map()
555 cpu_data->shared_type = CPUFREQ_SHARED_TYPE_NONE; in acpi_get_psd_map()
557 return -EFAULT; in acpi_get_psd_map()
572 return -ENODEV; in register_pcc_channel()
575 pcc_data[pcc_ss_idx]->pcc_channel = pcc_chan; in register_pcc_channel()
577 * cppc_ss->latency is just a Nominal value. In reality in register_pcc_channel()
581 usecs_lat = NUM_RETRIES * pcc_chan->latency; in register_pcc_channel()
582 pcc_data[pcc_ss_idx]->deadline_us = usecs_lat; in register_pcc_channel()
583 pcc_data[pcc_ss_idx]->pcc_mrtt = pcc_chan->min_turnaround_time; in register_pcc_channel()
584 pcc_data[pcc_ss_idx]->pcc_mpar = pcc_chan->max_access_rate; in register_pcc_channel()
585 pcc_data[pcc_ss_idx]->pcc_nominal = pcc_chan->latency; in register_pcc_channel()
588 pcc_data[pcc_ss_idx]->pcc_channel_acquired = true; in register_pcc_channel()
595 * cpc_ffh_supported() - check if FFH reading supported
608 * cpc_supported_by_cpu() - check if CPPC is supported by CPU
621 * pcc_data_alloc() - Allocate the pcc_data memory for pcc subspace
627 * with hardware multi-threading support.
634 return -EINVAL; in pcc_data_alloc()
637 pcc_data[pcc_ss_id]->refcount++; in pcc_data_alloc()
642 return -ENOMEM; in pcc_data_alloc()
643 pcc_data[pcc_ss_id]->refcount++; in pcc_data_alloc()
679 * acpi_cppc_processor_probe - Search for per CPU _CPC objects.
682 * Return: 0 for success or negative value for err.
691 acpi_handle handle = pr->handle; in acpi_cppc_processor_probe()
693 int pcc_subspace_id = -1; in acpi_cppc_processor_probe()
695 int ret = -ENODATA; in acpi_cppc_processor_probe()
701 return -ENODEV; in acpi_cppc_processor_probe()
709 ret = -ENODEV; in acpi_cppc_processor_probe()
717 ret = -ENOMEM; in acpi_cppc_processor_probe()
722 cpc_obj = &out_obj->package.elements[0]; in acpi_cppc_processor_probe()
723 if (cpc_obj->type == ACPI_TYPE_INTEGER) { in acpi_cppc_processor_probe()
724 num_ent = cpc_obj->integer.value; in acpi_cppc_processor_probe()
727 num_ent, pr->id); in acpi_cppc_processor_probe()
732 cpc_obj->type, pr->id); in acpi_cppc_processor_probe()
737 cpc_obj = &out_obj->package.elements[1]; in acpi_cppc_processor_probe()
738 if (cpc_obj->type == ACPI_TYPE_INTEGER) { in acpi_cppc_processor_probe()
739 cpc_rev = cpc_obj->integer.value; in acpi_cppc_processor_probe()
742 cpc_obj->type, pr->id); in acpi_cppc_processor_probe()
748 pr->id); in acpi_cppc_processor_probe()
761 num_ent, pr->id); in acpi_cppc_processor_probe()
769 cpc_ptr->num_entries = num_ent; in acpi_cppc_processor_probe()
770 cpc_ptr->version = cpc_rev; in acpi_cppc_processor_probe()
774 cpc_obj = &out_obj->package.elements[i]; in acpi_cppc_processor_probe()
776 if (cpc_obj->type == ACPI_TYPE_INTEGER) { in acpi_cppc_processor_probe()
777 cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_INTEGER; in acpi_cppc_processor_probe()
778 cpc_ptr->cpc_regs[i-2].cpc_entry.int_value = cpc_obj->integer.value; in acpi_cppc_processor_probe()
779 } else if (cpc_obj->type == ACPI_TYPE_BUFFER) { in acpi_cppc_processor_probe()
781 cpc_obj->buffer.pointer; in acpi_cppc_processor_probe()
789 if (gas_t->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { in acpi_cppc_processor_probe()
791 pcc_subspace_id = gas_t->access_width; in acpi_cppc_processor_probe()
794 } else if (pcc_subspace_id != gas_t->access_width) { in acpi_cppc_processor_probe()
796 pr->id); in acpi_cppc_processor_probe()
799 } else if (gas_t->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { in acpi_cppc_processor_probe()
800 if (gas_t->address) { in acpi_cppc_processor_probe()
811 addr = ioremap(gas_t->address, access_width); in acpi_cppc_processor_probe()
814 cpc_ptr->cpc_regs[i-2].sys_mem_vaddr = addr; in acpi_cppc_processor_probe()
816 } else if (gas_t->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { in acpi_cppc_processor_probe()
817 if (gas_t->access_width < 1 || gas_t->access_width > 3) { in acpi_cppc_processor_probe()
819 * 1 = 8-bit, 2 = 16-bit, and 3 = 32-bit. in acpi_cppc_processor_probe()
820 * SystemIO doesn't implement 64-bit in acpi_cppc_processor_probe()
824 gas_t->access_width); in acpi_cppc_processor_probe()
827 if (gas_t->address & OVER_16BTS_MASK) { in acpi_cppc_processor_probe()
828 /* SystemIO registers use 16-bit integer addresses */ in acpi_cppc_processor_probe()
830 gas_t->address); in acpi_cppc_processor_probe()
839 if (gas_t->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_supported()) { in acpi_cppc_processor_probe()
842 gas_t->space_id); in acpi_cppc_processor_probe()
847 cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER; in acpi_cppc_processor_probe()
848 memcpy(&cpc_ptr->cpc_regs[i-2].cpc_entry.reg, gas_t, sizeof(*gas_t)); in acpi_cppc_processor_probe()
851 i, pr->id); in acpi_cppc_processor_probe()
855 per_cpu(cpu_pcc_subspace_idx, pr->id) = pcc_subspace_id; in acpi_cppc_processor_probe()
862 for (i = num_ent - 2; i < MAX_CPC_REG_ENT; i++) { in acpi_cppc_processor_probe()
863 cpc_ptr->cpc_regs[i].type = ACPI_TYPE_INTEGER; in acpi_cppc_processor_probe()
864 cpc_ptr->cpc_regs[i].cpc_entry.int_value = 0; in acpi_cppc_processor_probe()
869 cpc_ptr->cpu_id = pr->id; in acpi_cppc_processor_probe()
870 raw_spin_lock_init(&cpc_ptr->rmw_lock); in acpi_cppc_processor_probe()
878 if (pcc_subspace_id >= 0 && !pcc_data[pcc_subspace_id]->pcc_channel_acquired) { in acpi_cppc_processor_probe()
883 init_rwsem(&pcc_data[pcc_subspace_id]->pcc_lock); in acpi_cppc_processor_probe()
884 init_waitqueue_head(&pcc_data[pcc_subspace_id]->pcc_write_wait_q); in acpi_cppc_processor_probe()
888 pr_debug("Parsed CPC struct for CPU: %d\n", pr->id); in acpi_cppc_processor_probe()
891 cpu_dev = get_cpu_device(pr->id); in acpi_cppc_processor_probe()
893 ret = -EINVAL; in acpi_cppc_processor_probe()
898 per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr; in acpi_cppc_processor_probe()
900 ret = kobject_init_and_add(&cpc_ptr->kobj, &cppc_ktype, &cpu_dev->kobj, in acpi_cppc_processor_probe()
903 per_cpu(cpc_desc_ptr, pr->id) = NULL; in acpi_cppc_processor_probe()
904 kobject_put(&cpc_ptr->kobj); in acpi_cppc_processor_probe()
913 for (i = 2; i < cpc_ptr->num_entries; i++) { in acpi_cppc_processor_probe()
914 void __iomem *addr = cpc_ptr->cpc_regs[i-2].sys_mem_vaddr; in acpi_cppc_processor_probe()
928 * acpi_cppc_processor_exit - Cleanup CPC structs.
938 int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, pr->id); in acpi_cppc_processor_exit()
941 if (pcc_data[pcc_ss_id]->pcc_channel_acquired) { in acpi_cppc_processor_exit()
942 pcc_data[pcc_ss_id]->refcount--; in acpi_cppc_processor_exit()
943 if (!pcc_data[pcc_ss_id]->refcount) { in acpi_cppc_processor_exit()
944 pcc_mbox_free_channel(pcc_data[pcc_ss_id]->pcc_channel); in acpi_cppc_processor_exit()
951 cpc_ptr = per_cpu(cpc_desc_ptr, pr->id); in acpi_cppc_processor_exit()
956 for (i = 2; i < cpc_ptr->num_entries; i++) { in acpi_cppc_processor_exit()
957 addr = cpc_ptr->cpc_regs[i-2].sys_mem_vaddr; in acpi_cppc_processor_exit()
962 kobject_put(&cpc_ptr->kobj); in acpi_cppc_processor_exit()
968 * cpc_read_ffh() - Read FFH register
979 return -ENOTSUPP; in cpc_read_ffh()
983 * cpc_write_ffh() - Write FFH register
994 return -ENOTSUPP; in cpc_write_ffh()
1008 struct cpc_reg *reg = ®_res->cpc_entry.reg; in cpc_read()
1010 if (reg_res->type == ACPI_TYPE_INTEGER) { in cpc_read()
1011 *val = reg_res->cpc_entry.int_value; in cpc_read()
1019 reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { in cpc_read()
1023 status = acpi_os_read_port((acpi_io_address)reg->address, in cpc_read()
1027 reg->address); in cpc_read()
1028 return -EFAULT; in cpc_read()
1033 } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) { in cpc_read()
1039 size = reg->bit_width; in cpc_read()
1040 vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); in cpc_read()
1042 else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) in cpc_read()
1043 vaddr = reg_res->sys_mem_vaddr; in cpc_read()
1044 else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) in cpc_read()
1047 return acpi_os_read_memory((acpi_physical_address)reg->address, in cpc_read()
1064 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { in cpc_read()
1066 size, reg->address); in cpc_read()
1067 } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { in cpc_read()
1071 return -EFAULT; in cpc_read()
1074 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) in cpc_read()
1087 struct cpc_reg *reg = ®_res->cpc_entry.reg; in cpc_write()
1094 reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { in cpc_write()
1097 status = acpi_os_write_port((acpi_io_address)reg->address, in cpc_write()
1101 reg->address); in cpc_write()
1102 return -EFAULT; in cpc_write()
1106 } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) { in cpc_write()
1112 size = reg->bit_width; in cpc_write()
1113 vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); in cpc_write()
1115 else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) in cpc_write()
1116 vaddr = reg_res->sys_mem_vaddr; in cpc_write()
1117 else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) in cpc_write()
1120 return acpi_os_write_memory((acpi_physical_address)reg->address, in cpc_write()
1123 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { in cpc_write()
1127 return -ENODEV; in cpc_write()
1130 raw_spin_lock_irqsave(&cpc_desc->rmw_lock, flags); in cpc_write()
1145 raw_spin_unlock_irqrestore(&cpc_desc->rmw_lock, flags); in cpc_write()
1146 return -EFAULT; in cpc_write()
1165 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { in cpc_write()
1167 size, reg->address); in cpc_write()
1168 } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { in cpc_write()
1172 ret_val = -EFAULT; in cpc_write()
1176 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) in cpc_write()
1177 raw_spin_unlock_irqrestore(&cpc_desc->rmw_lock, flags); in cpc_write()
1190 return -ENODEV; in cppc_get_reg_val_in_pcc()
1195 down_write(&pcc_ss_data->pcc_lock); in cppc_get_reg_val_in_pcc()
1200 ret = -EIO; in cppc_get_reg_val_in_pcc()
1202 up_write(&pcc_ss_data->pcc_lock); in cppc_get_reg_val_in_pcc()
1213 return -EINVAL; in cppc_get_reg_val()
1217 return -ENODEV; in cppc_get_reg_val()
1220 reg = &cpc_desc->cpc_regs[reg_idx]; in cppc_get_reg_val()
1222 if ((reg->type == ACPI_TYPE_INTEGER && IS_OPTIONAL_CPC_REG(reg_idx) && in cppc_get_reg_val()
1223 !reg->cpc_entry.int_value) || (reg->type != ACPI_TYPE_INTEGER && in cppc_get_reg_val()
1224 IS_NULL_REG(®->cpc_entry.reg))) { in cppc_get_reg_val()
1226 return -EOPNOTSUPP; in cppc_get_reg_val()
1243 return -ENODEV; in cppc_set_reg_val_in_pcc()
1252 down_write(&pcc_ss_data->pcc_lock); in cppc_set_reg_val_in_pcc()
1255 up_write(&pcc_ss_data->pcc_lock); in cppc_set_reg_val_in_pcc()
1267 return -ENODEV; in cppc_set_reg_val()
1270 reg = &cpc_desc->cpc_regs[reg_idx]; in cppc_set_reg_val()
1273 if ((reg->type != ACPI_TYPE_BUFFER) || IS_NULL_REG(®->cpc_entry.reg)) { in cppc_set_reg_val()
1275 return -EOPNOTSUPP; in cppc_set_reg_val()
1285 * cppc_get_desired_perf - Get the desired performance register value.
1289 * Return: 0 for success, -EIO otherwise.
1298 * cppc_get_nominal_perf - Get the nominal performance register value.
1302 * Return: 0 for success, -EIO otherwise.
1310 * cppc_get_highest_perf - Get the highest performance register value.
1314 * Return: 0 for success, -EIO otherwise.
1323 * cppc_get_epp_perf - Get the epp register value.
1327 * Return: 0 for success, -EIO otherwise.
1336 * cppc_get_perf_caps - Get a CPU's performance capabilities.
1340 * Return: 0 for success with perf_caps populated else -ERRNO.
1355 return -ENODEV; in cppc_get_perf_caps()
1358 highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF]; in cppc_get_perf_caps()
1359 lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF]; in cppc_get_perf_caps()
1360 lowest_non_linear_reg = &cpc_desc->cpc_regs[LOW_NON_LINEAR_PERF]; in cppc_get_perf_caps()
1361 nominal_reg = &cpc_desc->cpc_regs[NOMINAL_PERF]; in cppc_get_perf_caps()
1362 low_freq_reg = &cpc_desc->cpc_regs[LOWEST_FREQ]; in cppc_get_perf_caps()
1363 nom_freq_reg = &cpc_desc->cpc_regs[NOMINAL_FREQ]; in cppc_get_perf_caps()
1364 guaranteed_reg = &cpc_desc->cpc_regs[GUARANTEED_PERF]; in cppc_get_perf_caps()
1372 return -ENODEV; in cppc_get_perf_caps()
1376 down_write(&pcc_ss_data->pcc_lock); in cppc_get_perf_caps()
1379 ret = -EIO; in cppc_get_perf_caps()
1385 perf_caps->highest_perf = high; in cppc_get_perf_caps()
1388 perf_caps->lowest_perf = low; in cppc_get_perf_caps()
1391 perf_caps->nominal_perf = nom; in cppc_get_perf_caps()
1393 if (guaranteed_reg->type != ACPI_TYPE_BUFFER || in cppc_get_perf_caps()
1394 IS_NULL_REG(&guaranteed_reg->cpc_entry.reg)) { in cppc_get_perf_caps()
1395 perf_caps->guaranteed_perf = 0; in cppc_get_perf_caps()
1398 perf_caps->guaranteed_perf = guaranteed; in cppc_get_perf_caps()
1402 perf_caps->lowest_nonlinear_perf = min_nonlinear; in cppc_get_perf_caps()
1405 ret = -EFAULT; in cppc_get_perf_caps()
1414 perf_caps->lowest_freq = low_f; in cppc_get_perf_caps()
1415 perf_caps->nominal_freq = nom_f; in cppc_get_perf_caps()
1420 up_write(&pcc_ss_data->pcc_lock); in cppc_get_perf_caps()
1426 * cppc_perf_ctrs_in_pcc - Check if any perf counters are in a PCC region.
1444 if (CPC_IN_PCC(&cpc_desc->cpc_regs[DELIVERED_CTR]) || in cppc_perf_ctrs_in_pcc()
1445 CPC_IN_PCC(&cpc_desc->cpc_regs[REFERENCE_CTR]) || in cppc_perf_ctrs_in_pcc()
1446 CPC_IN_PCC(&cpc_desc->cpc_regs[CTR_WRAP_TIME])) in cppc_perf_ctrs_in_pcc()
1450 ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF]; in cppc_perf_ctrs_in_pcc()
1457 ref_perf_reg = &cpc_desc->cpc_regs[NOMINAL_PERF]; in cppc_perf_ctrs_in_pcc()
1468 * cppc_get_perf_ctrs - Read a CPU's performance feedback counters.
1472 * Return: 0 for success with perf_fb_ctrs populated else -ERRNO.
1486 return -ENODEV; in cppc_get_perf_ctrs()
1489 delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR]; in cppc_get_perf_ctrs()
1490 reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR]; in cppc_get_perf_ctrs()
1491 ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF]; in cppc_get_perf_ctrs()
1492 ctr_wrap_reg = &cpc_desc->cpc_regs[CTR_WRAP_TIME]; in cppc_get_perf_ctrs()
1499 ref_perf_reg = &cpc_desc->cpc_regs[NOMINAL_PERF]; in cppc_get_perf_ctrs()
1506 return -ENODEV; in cppc_get_perf_ctrs()
1509 down_write(&pcc_ss_data->pcc_lock); in cppc_get_perf_ctrs()
1513 ret = -EIO; in cppc_get_perf_ctrs()
1532 ret = -EFAULT; in cppc_get_perf_ctrs()
1536 perf_fb_ctrs->delivered = delivered; in cppc_get_perf_ctrs()
1537 perf_fb_ctrs->reference = reference; in cppc_get_perf_ctrs()
1538 perf_fb_ctrs->reference_perf = ref_perf; in cppc_get_perf_ctrs()
1539 perf_fb_ctrs->wraparound_time = ctr_wrap_time; in cppc_get_perf_ctrs()
1542 up_write(&pcc_ss_data->pcc_lock); in cppc_get_perf_ctrs()
1562 return -ENODEV; in cppc_set_epp_perf()
1565 auto_sel_reg = &cpc_desc->cpc_regs[AUTO_SEL_ENABLE]; in cppc_set_epp_perf()
1566 epp_set_reg = &cpc_desc->cpc_regs[ENERGY_PERF]; in cppc_set_epp_perf()
1571 return -ENODEV; in cppc_set_epp_perf()
1581 ret = cpc_write(cpu, epp_set_reg, perf_ctrls->energy_perf); in cppc_set_epp_perf()
1588 down_write(&pcc_ss_data->pcc_lock); in cppc_set_epp_perf()
1591 up_write(&pcc_ss_data->pcc_lock); in cppc_set_epp_perf()
1594 ret = cpc_write(cpu, epp_set_reg, perf_ctrls->energy_perf); in cppc_set_epp_perf()
1596 ret = -ENOTSUPP; in cppc_set_epp_perf()
1605 * cppc_set_epp() - Write the EPP register.
1612 return -EINVAL; in cppc_set_epp()
1619 * cppc_get_auto_act_window() - Read autonomous activity window register.
1634 return -EINVAL; in cppc_get_auto_act_window()
1649 * cppc_set_auto_act_window() - Write autonomous activity window register.
1665 return -EINVAL; in cppc_set_auto_act_window()
1688 * cppc_get_auto_sel() - Read autonomous selection register.
1698 return -EINVAL; in cppc_get_auto_sel()
1711 * cppc_set_auto_sel - Write autonomous selection register.
1722 * cppc_set_enable - Set to enable CPPC on the processor by writing the
1725 * @enable: 0 - disable, 1 - enable CPPC feature on the processor.
1727 * Return: 0 for success, -ERRNO or -EIO otherwise.
1736 * cppc_set_perf - Set a CPU's performance controls.
1740 * Return: 0 for success, -ERRNO otherwise.
1752 return -ENODEV; in cppc_set_perf()
1755 desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; in cppc_set_perf()
1756 min_perf_reg = &cpc_desc->cpc_regs[MIN_PERF]; in cppc_set_perf()
1757 max_perf_reg = &cpc_desc->cpc_regs[MAX_PERF]; in cppc_set_perf()
1760 * This is Phase-I where we want to write to CPC registers in cppc_set_perf()
1761 * -> We want all CPUs to be able to execute this phase in parallel in cppc_set_perf()
1769 return -ENODEV; in cppc_set_perf()
1772 down_read(&pcc_ss_data->pcc_lock); /* BEGIN Phase-I */ in cppc_set_perf()
1773 if (pcc_ss_data->platform_owns_pcc) { in cppc_set_perf()
1776 up_read(&pcc_ss_data->pcc_lock); in cppc_set_perf()
1784 pcc_ss_data->pending_pcc_write_cmd = true; in cppc_set_perf()
1785 cpc_desc->write_cmd_id = pcc_ss_data->pcc_write_cnt; in cppc_set_perf()
1786 cpc_desc->write_cmd_status = 0; in cppc_set_perf()
1789 cpc_write(cpu, desired_reg, perf_ctrls->desired_perf); in cppc_set_perf()
1796 if (perf_ctrls->min_perf) in cppc_set_perf()
1797 cpc_write(cpu, min_perf_reg, perf_ctrls->min_perf); in cppc_set_perf()
1798 if (perf_ctrls->max_perf) in cppc_set_perf()
1799 cpc_write(cpu, max_perf_reg, perf_ctrls->max_perf); in cppc_set_perf()
1802 up_read(&pcc_ss_data->pcc_lock); /* END Phase-I */ in cppc_set_perf()
1804 * This is Phase-II where we transfer the ownership of PCC to Platform in cppc_set_perf()
1808 * come out of Phase-I will enter Phase-II and ring the doorbell. in cppc_set_perf()
1810 * We have the following requirements for Phase-II: in cppc_set_perf()
1811 * 1. We want to execute Phase-II only when there are no CPUs in cppc_set_perf()
1812 * currently executing in Phase-I in cppc_set_perf()
1813 * 2. Once we start Phase-II we want to avoid all other CPUs from in cppc_set_perf()
1814 * entering Phase-I. in cppc_set_perf()
1815 * 3. We want only one CPU among all those who went through Phase-I in cppc_set_perf()
1816 * to run phase-II in cppc_set_perf()
1820 * 1. There is at-least one CPU in Phase-I which will later execute in cppc_set_perf()
1821 * write_trylock, so the CPUs in Phase-I will be responsible for in cppc_set_perf()
1822 * executing the Phase-II. in cppc_set_perf()
1826 * before this CPU's Phase-I as we held the read_lock. in cppc_set_perf()
1837 * Phase-I and Phase-II. Before it is scheduled back on, another CPU in cppc_set_perf()
1850 if (down_write_trylock(&pcc_ss_data->pcc_lock)) {/* BEGIN Phase-II */ in cppc_set_perf()
1852 if (pcc_ss_data->pending_pcc_write_cmd) in cppc_set_perf()
1854 up_write(&pcc_ss_data->pcc_lock); /* END Phase-II */ in cppc_set_perf()
1857 wait_event(pcc_ss_data->pcc_write_wait_q, in cppc_set_perf()
1858 cpc_desc->write_cmd_id != pcc_ss_data->pcc_write_cnt); in cppc_set_perf()
1861 ret = cpc_desc->write_cmd_status; in cppc_set_perf()
1868 * cppc_get_transition_latency - returns frequency transition latency in ns
1884 * pcc_nominal- Expected latency to process a command, in microseconds in cppc_get_transition_latency()
1885 * pcc_mpar - The maximum number of periodic requests that the subspace in cppc_get_transition_latency()
1888 * pcc_mrtt - The minimum amount of time that OSPM must wait after the in cppc_get_transition_latency()
1900 return -ENODATA; in cppc_get_transition_latency()
1902 desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; in cppc_get_transition_latency()
1907 return -ENODATA; in cppc_get_transition_latency()
1910 if (pcc_ss_data->pcc_mpar) in cppc_get_transition_latency()
1911 latency_ns = 60 * (1000 * 1000 * 1000 / pcc_ss_data->pcc_mpar); in cppc_get_transition_latency()
1913 latency_ns = max_t(int, latency_ns, pcc_ss_data->pcc_nominal * 1000); in cppc_get_transition_latency()
1914 latency_ns = max_t(int, latency_ns, pcc_ss_data->pcc_mrtt * 1000); in cppc_get_transition_latency()
1932 if (dm->type == DMI_ENTRY_PROCESSOR && in cppc_find_dmi_mhz()
1933 dm->length >= DMI_ENTRY_PROCESSOR_MIN_LENGTH) { in cppc_find_dmi_mhz()
1960 * - (Low perf, Low freq)
1961 * - (Nominal perf, Nominal freq)
1969 if (caps->lowest_freq && caps->nominal_freq) { in cppc_perf_to_khz()
1971 if (caps->lowest_freq == caps->nominal_freq) { in cppc_perf_to_khz()
1972 mul = caps->nominal_freq; in cppc_perf_to_khz()
1973 div = caps->nominal_perf; in cppc_perf_to_khz()
1975 mul = caps->nominal_freq - caps->lowest_freq; in cppc_perf_to_khz()
1976 div = caps->nominal_perf - caps->lowest_perf; in cppc_perf_to_khz()
1979 offset = caps->nominal_freq * KHZ_PER_MHZ - in cppc_perf_to_khz()
1980 div64_u64(caps->nominal_perf * mul, div); in cppc_perf_to_khz()
1985 div = caps->highest_perf; in cppc_perf_to_khz()
2001 if (caps->lowest_freq && caps->nominal_freq) { in cppc_khz_to_perf()
2003 if (caps->lowest_freq == caps->nominal_freq) { in cppc_khz_to_perf()
2004 mul = caps->nominal_perf; in cppc_khz_to_perf()
2005 div = caps->nominal_freq; in cppc_khz_to_perf()
2007 mul = caps->nominal_perf - caps->lowest_perf; in cppc_khz_to_perf()
2008 div = caps->nominal_freq - caps->lowest_freq; in cppc_khz_to_perf()
2015 offset = caps->nominal_perf - in cppc_khz_to_perf()
2016 div64_u64(caps->nominal_freq * mul, div); in cppc_khz_to_perf()
2022 mul = caps->highest_perf; in cppc_khz_to_perf()