33ee086458e986c06c112837a1cbd51ed69ad2f6
[platform/kernel/linux-starfive.git] / tools / power / x86 / intel-speed-select / isst-core.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Intel Speed Select -- Enumerate and control features
4  * Copyright (c) 2019 Intel Corporation.
5  */
6
7 #include "isst.h"
8
9 static int mbox_delay;
10 static int mbox_retries = 3;
11
12 static struct isst_platform_ops         *isst_ops;
13
14 #define CHECK_CB(_name) \
15         do {    \
16                 if (!isst_ops || !isst_ops->_name) {    \
17                         fprintf(stderr, "Invalid ops\n");       \
18                         exit(0);        \
19                 }       \
20         } while (0)
21
22 int isst_set_platform_ops(void)
23 {
24         isst_ops = mbox_get_platform_ops();
25
26         if (!isst_ops)
27                 return -1;
28         return 0;
29 }
30
31 void isst_update_platform_param(enum isst_platform_param param, int value)
32 {
33         switch (param) {
34         case ISST_PARAM_MBOX_DELAY:
35                 mbox_delay = value;
36                 break;
37         case ISST_PARAM_MBOX_RETRIES:
38                 mbox_retries = value;
39                 break;
40         default:
41                 break;
42         }
43 }
44
45 int isst_get_disp_freq_multiplier(void)
46 {
47         CHECK_CB(get_disp_freq_multiplier);
48         return isst_ops->get_disp_freq_multiplier();
49 }
50
51 int isst_get_trl_max_levels(void)
52 {
53         CHECK_CB(get_trl_max_levels);
54         return isst_ops->get_trl_max_levels();
55 }
56
57 char *isst_get_trl_level_name(int level)
58 {
59         CHECK_CB(get_trl_level_name);
60         return isst_ops->get_trl_level_name(level);
61 }
62
63 int isst_is_punit_valid(struct isst_id *id)
64 {
65         CHECK_CB(is_punit_valid);
66         return isst_ops->is_punit_valid(id);
67 }
68
69 static int isst_send_mmio_command(unsigned int cpu, unsigned int reg, int write,
70                                   unsigned int *value)
71 {
72         struct isst_if_io_regs io_regs;
73         const char *pathname = "/dev/isst_interface";
74         int cmd;
75         FILE *outf = get_output_file();
76         int fd;
77
78         debug_printf("mmio_cmd cpu:%d reg:%d write:%d\n", cpu, reg, write);
79
80         fd = open(pathname, O_RDWR);
81         if (fd < 0)
82                 err(-1, "%s open failed", pathname);
83
84         io_regs.req_count = 1;
85         io_regs.io_reg[0].logical_cpu = cpu;
86         io_regs.io_reg[0].reg = reg;
87         cmd = ISST_IF_IO_CMD;
88         if (write) {
89                 io_regs.io_reg[0].read_write = 1;
90                 io_regs.io_reg[0].value = *value;
91         } else {
92                 io_regs.io_reg[0].read_write = 0;
93         }
94
95         if (ioctl(fd, cmd, &io_regs) == -1) {
96                 if (errno == ENOTTY) {
97                         perror("ISST_IF_IO_COMMAND\n");
98                         fprintf(stderr, "Check presence of kernel modules: isst_if_mmio\n");
99                         exit(0);
100                 }
101                 fprintf(outf, "Error: mmio_cmd cpu:%d reg:%x read_write:%x\n",
102                         cpu, reg, write);
103         } else {
104                 if (!write)
105                         *value = io_regs.io_reg[0].value;
106
107                 debug_printf(
108                         "mmio_cmd response: cpu:%d reg:%x rd_write:%x resp:%x\n",
109                         cpu, reg, write, *value);
110         }
111
112         close(fd);
113
114         return 0;
115 }
116
117 int isst_send_mbox_command(unsigned int cpu, unsigned char command,
118                            unsigned char sub_command, unsigned int parameter,
119                            unsigned int req_data, unsigned int *resp)
120 {
121         const char *pathname = "/dev/isst_interface";
122         int fd, retry;
123         struct isst_if_mbox_cmds mbox_cmds = { 0 };
124
125         debug_printf(
126                 "mbox_send: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n",
127                 cpu, command, sub_command, parameter, req_data);
128
129         if (!is_skx_based_platform() && command == CONFIG_CLOS &&
130             sub_command != CLOS_PM_QOS_CONFIG) {
131                 unsigned int value;
132                 int write = 0;
133                 int clos_id, core_id, ret = 0;
134
135                 debug_printf("CPU %d\n", cpu);
136
137                 if (parameter & BIT(MBOX_CMD_WRITE_BIT)) {
138                         value = req_data;
139                         write = 1;
140                 }
141
142                 switch (sub_command) {
143                 case CLOS_PQR_ASSOC:
144                         core_id = parameter & 0xff;
145                         ret = isst_send_mmio_command(
146                                 cpu, PQR_ASSOC_OFFSET + core_id * 4, write,
147                                 &value);
148                         if (!ret && !write)
149                                 *resp = value;
150                         break;
151                 case CLOS_PM_CLOS:
152                         clos_id = parameter & 0x03;
153                         ret = isst_send_mmio_command(
154                                 cpu, PM_CLOS_OFFSET + clos_id * 4, write,
155                                 &value);
156                         if (!ret && !write)
157                                 *resp = value;
158                         break;
159                 case CLOS_STATUS:
160                         break;
161                 default:
162                         break;
163                 }
164                 return ret;
165         }
166
167         mbox_cmds.cmd_count = 1;
168         mbox_cmds.mbox_cmd[0].logical_cpu = cpu;
169         mbox_cmds.mbox_cmd[0].command = command;
170         mbox_cmds.mbox_cmd[0].sub_command = sub_command;
171         mbox_cmds.mbox_cmd[0].parameter = parameter;
172         mbox_cmds.mbox_cmd[0].req_data = req_data;
173
174         if (mbox_delay)
175                 usleep(mbox_delay * 1000);
176
177         fd = open(pathname, O_RDWR);
178         if (fd < 0)
179                 err(-1, "%s open failed", pathname);
180
181         retry = mbox_retries;
182
183         do {
184                 if (ioctl(fd, ISST_IF_MBOX_COMMAND, &mbox_cmds) == -1) {
185                         if (errno == ENOTTY) {
186                                 perror("ISST_IF_MBOX_COMMAND\n");
187                                 fprintf(stderr, "Check presence of kernel modules: isst_if_mbox_pci or isst_if_mbox_msr\n");
188                                 exit(0);
189                         }
190                         debug_printf(
191                                 "Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x errorno:%d\n",
192                                 cpu, command, sub_command, parameter, req_data, errno);
193                         --retry;
194                 } else {
195                         *resp = mbox_cmds.mbox_cmd[0].resp_data;
196                         debug_printf(
197                                 "mbox_cmd response: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x resp:%x\n",
198                                 cpu, command, sub_command, parameter, req_data, *resp);
199                         break;
200                 }
201         } while (retry);
202
203         close(fd);
204
205         if (!retry) {
206                 debug_printf("Failed mbox command even after retries\n");
207                 return -1;
208
209         }
210         return 0;
211 }
212
213 int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write,
214                           unsigned long long *req_resp)
215 {
216         struct isst_if_msr_cmds msr_cmds;
217         const char *pathname = "/dev/isst_interface";
218         FILE *outf = get_output_file();
219         int fd;
220
221         fd = open(pathname, O_RDWR);
222         if (fd < 0)
223                 err(-1, "%s open failed", pathname);
224
225         msr_cmds.cmd_count = 1;
226         msr_cmds.msr_cmd[0].logical_cpu = cpu;
227         msr_cmds.msr_cmd[0].msr = msr;
228         msr_cmds.msr_cmd[0].read_write = write;
229         if (write)
230                 msr_cmds.msr_cmd[0].data = *req_resp;
231
232         if (ioctl(fd, ISST_IF_MSR_COMMAND, &msr_cmds) == -1) {
233                 perror("ISST_IF_MSR_COMMAND");
234                 fprintf(outf, "Error: msr_cmd cpu:%d msr:%x read_write:%d\n",
235                         cpu, msr, write);
236         } else {
237                 if (!write)
238                         *req_resp = msr_cmds.msr_cmd[0].data;
239
240                 debug_printf(
241                         "msr_cmd response: cpu:%d msr:%x rd_write:%x resp:%llx %llx\n",
242                         cpu, msr, write, *req_resp, msr_cmds.msr_cmd[0].data);
243         }
244
245         close(fd);
246
247         return 0;
248 }
249
250 int isst_write_pm_config(struct isst_id *id, int cp_state)
251 {
252         unsigned int req, resp;
253         int ret;
254
255         if (cp_state)
256                 req = BIT(16);
257         else
258                 req = 0;
259
260         ret = isst_send_mbox_command(id->cpu, WRITE_PM_CONFIG, PM_FEATURE, 0, req,
261                                      &resp);
262         if (ret)
263                 return ret;
264
265         debug_printf("cpu:%d WRITE_PM_CONFIG resp:%x\n", id->cpu, resp);
266
267         return 0;
268 }
269
270 int isst_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap)
271 {
272         unsigned int resp;
273         int ret;
274
275         ret = isst_send_mbox_command(id->cpu, READ_PM_CONFIG, PM_FEATURE, 0, 0,
276                                      &resp);
277         if (ret)
278                 return ret;
279
280         debug_printf("cpu:%d READ_PM_CONFIG resp:%x\n", id->cpu, resp);
281
282         *cp_state = resp & BIT(16);
283         *cp_cap = resp & BIT(0) ? 1 : 0;
284
285         return 0;
286 }
287
288 int isst_get_ctdp_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev)
289 {
290         CHECK_CB(get_config_levels);
291         return isst_ops->get_config_levels(id, pkg_dev);
292 }
293
294 int isst_get_ctdp_control(struct isst_id *id, int config_index,
295                           struct isst_pkg_ctdp_level_info *ctdp_level)
296 {
297         CHECK_CB(get_ctdp_control);
298         return isst_ops->get_ctdp_control(id, config_index, ctdp_level);
299 }
300
301 int isst_get_tdp_info(struct isst_id *id, int config_index,
302                       struct isst_pkg_ctdp_level_info *ctdp_level)
303 {
304         CHECK_CB(get_tdp_info);
305         return isst_ops->get_tdp_info(id, config_index, ctdp_level);
306 }
307
308 int isst_get_pwr_info(struct isst_id *id, int config_index,
309                       struct isst_pkg_ctdp_level_info *ctdp_level)
310 {
311         CHECK_CB(get_pwr_info);
312         return isst_ops->get_pwr_info(id, config_index, ctdp_level);
313 }
314
315 int isst_get_coremask_info(struct isst_id *id, int config_index,
316                            struct isst_pkg_ctdp_level_info *ctdp_level)
317 {
318         CHECK_CB(get_coremask_info);
319         return isst_ops->get_coremask_info(id, config_index, ctdp_level);
320 }
321
322 int isst_get_get_trl_from_msr(struct isst_id *id, int *trl)
323 {
324         unsigned long long msr_trl;
325         int ret;
326
327         ret = isst_send_msr_command(id->cpu, 0x1AD, 0, &msr_trl);
328         if (ret)
329                 return ret;
330
331         trl[0] = msr_trl & GENMASK(7, 0);
332         trl[1] = (msr_trl & GENMASK(15, 8)) >> 8;
333         trl[2] = (msr_trl & GENMASK(23, 16)) >> 16;
334         trl[3] = (msr_trl & GENMASK(31, 24)) >> 24;
335         trl[4] = (msr_trl & GENMASK(39, 32)) >> 32;
336         trl[5] = (msr_trl & GENMASK(47, 40)) >> 40;
337         trl[6] = (msr_trl & GENMASK(55, 48)) >> 48;
338         trl[7] = (msr_trl & GENMASK(63, 56)) >> 56;
339
340         return 0;
341 }
342
343 int isst_get_get_trl(struct isst_id *id, int level, int avx_level, int *trl)
344 {
345         CHECK_CB(get_get_trl);
346         return isst_ops->get_get_trl(id, level, avx_level, trl);
347 }
348
349 int isst_get_get_trls(struct isst_id *id, int level, struct isst_pkg_ctdp_level_info *ctdp_level)
350 {
351         CHECK_CB(get_get_trls);
352         return isst_ops->get_get_trls(id, level, ctdp_level);
353 }
354
355 int isst_get_trl_bucket_info(struct isst_id *id, int level, unsigned long long *buckets_info)
356 {
357         CHECK_CB(get_trl_bucket_info);
358         return isst_ops->get_trl_bucket_info(id, level, buckets_info);
359 }
360
361 int isst_set_tdp_level(struct isst_id *id, int tdp_level)
362 {
363         CHECK_CB(set_tdp_level);
364         return isst_ops->set_tdp_level(id, tdp_level);
365 }
366
367 int isst_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info *pbf_info)
368 {
369         struct isst_pkg_ctdp_level_info ctdp_level;
370         struct isst_pkg_ctdp pkg_dev;
371         int ret;
372
373         ret = isst_get_ctdp_levels(id, &pkg_dev);
374         if (ret) {
375                 isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
376                 return ret;
377         }
378
379         if (level > pkg_dev.levels) {
380                 isst_display_error_info_message(1, "Invalid level", 1, level);
381                 return -1;
382         }
383
384         ret = isst_get_ctdp_control(id, level, &ctdp_level);
385         if (ret)
386                 return ret;
387
388         if (!ctdp_level.pbf_support) {
389                 isst_display_error_info_message(1, "base-freq feature is not present at this level", 1, level);
390                 return -1;
391         }
392
393         pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask);
394
395         CHECK_CB(get_pbf_info);
396         return isst_ops->get_pbf_info(id, level, pbf_info);
397 }
398
399 int isst_set_pbf_fact_status(struct isst_id *id, int pbf, int enable)
400 {
401         CHECK_CB(set_pbf_fact_status);
402         return isst_ops->set_pbf_fact_status(id, pbf, enable);
403 }
404
405
406
407 int isst_get_fact_info(struct isst_id *id, int level, int fact_bucket, struct isst_fact_info *fact_info)
408 {
409         struct isst_pkg_ctdp_level_info ctdp_level;
410         struct isst_pkg_ctdp pkg_dev;
411         int ret;
412
413         ret = isst_get_ctdp_levels(id, &pkg_dev);
414         if (ret) {
415                 isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
416                 return ret;
417         }
418
419         if (level > pkg_dev.levels) {
420                 isst_display_error_info_message(1, "Invalid level", 1, level);
421                 return -1;
422         }
423
424         ret = isst_get_ctdp_control(id, level, &ctdp_level);
425         if (ret)
426                 return ret;
427
428         if (!ctdp_level.fact_support) {
429                 isst_display_error_info_message(1, "turbo-freq feature is not present at this level", 1, level);
430                 return -1;
431         }
432         CHECK_CB(get_fact_info);
433         return isst_ops->get_fact_info(id, level, fact_bucket, fact_info);
434 }
435
436 int isst_get_trl(struct isst_id *id, unsigned long long *trl)
437 {
438         int ret;
439
440         ret = isst_send_msr_command(id->cpu, 0x1AD, 0, trl);
441         if (ret)
442                 return ret;
443
444         return 0;
445 }
446
447 int isst_set_trl(struct isst_id *id, unsigned long long trl)
448 {
449         int ret;
450
451         if (!trl)
452                 trl = 0xFFFFFFFFFFFFFFFFULL;
453
454         ret = isst_send_msr_command(id->cpu, 0x1AD, 1, &trl);
455         if (ret)
456                 return ret;
457
458         return 0;
459 }
460
461 int isst_set_trl_from_current_tdp(struct isst_id *id, unsigned long long trl)
462 {
463         unsigned long long msr_trl;
464         int ret;
465
466         if (trl) {
467                 msr_trl = trl;
468         } else {
469                 struct isst_pkg_ctdp pkg_dev;
470                 int trl[8];
471                 int i;
472
473                 ret = isst_get_ctdp_levels(id, &pkg_dev);
474                 if (ret)
475                         return ret;
476
477                 ret = isst_get_get_trl(id, pkg_dev.current_level, 0, trl);
478                 if (ret)
479                         return ret;
480
481                 msr_trl = 0;
482                 for (i = 0; i < 8; ++i) {
483                         unsigned long long _trl = trl[i];
484
485                         msr_trl |= (_trl << (i * 8));
486                 }
487         }
488         ret = isst_send_msr_command(id->cpu, 0x1AD, 1, &msr_trl);
489         if (ret)
490                 return ret;
491
492         return 0;
493 }
494
495 /* Return 1 if locked */
496 int isst_get_config_tdp_lock_status(struct isst_id *id)
497 {
498         unsigned long long tdp_control = 0;
499         int ret;
500
501         ret = isst_send_msr_command(id->cpu, 0x64b, 0, &tdp_control);
502         if (ret)
503                 return ret;
504
505         ret = !!(tdp_control & BIT(31));
506
507         return ret;
508 }
509
510 void isst_get_process_ctdp_complete(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev)
511 {
512         int i;
513
514         if (!pkg_dev->processed)
515                 return;
516
517         for (i = 0; i < pkg_dev->levels; ++i) {
518                 struct isst_pkg_ctdp_level_info *ctdp_level;
519
520                 ctdp_level = &pkg_dev->ctdp_level[i];
521                 if (ctdp_level->pbf_support)
522                         free_cpu_set(ctdp_level->pbf_info.core_cpumask);
523                 free_cpu_set(ctdp_level->core_cpumask);
524         }
525 }
526
527 void isst_get_uncore_p0_p1_info(struct isst_id *id, int config_index,
528                                 struct isst_pkg_ctdp_level_info *ctdp_level)
529 {
530         CHECK_CB(get_uncore_p0_p1_info);
531         return isst_ops->get_uncore_p0_p1_info(id, config_index, ctdp_level);
532 }
533
534 int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
535 {
536         int i, ret, valid = 0;
537
538         if (pkg_dev->processed)
539                 return 0;
540
541         ret = isst_get_ctdp_levels(id, pkg_dev);
542         if (ret)
543                 return ret;
544
545         debug_printf("cpu: %d ctdp enable:%d current level: %d levels:%d\n",
546                      id->cpu, pkg_dev->enabled, pkg_dev->current_level,
547                      pkg_dev->levels);
548
549         if (tdp_level != 0xff && tdp_level > pkg_dev->levels) {
550                 isst_display_error_info_message(1, "Invalid level", 0, 0);
551                 return -1;
552         }
553
554         if (!pkg_dev->enabled)
555                 isst_display_error_info_message(0, "perf-profile feature is not supported, just base-config level 0 is valid", 0, 0);
556
557         for (i = 0; i <= pkg_dev->levels; ++i) {
558                 struct isst_pkg_ctdp_level_info *ctdp_level;
559
560                 if (tdp_level != 0xff && i != tdp_level)
561                         continue;
562
563                 debug_printf("cpu:%d Get Information for TDP level:%d\n", id->cpu,
564                              i);
565                 ctdp_level = &pkg_dev->ctdp_level[i];
566
567                 ctdp_level->level = i;
568                 ctdp_level->control_cpu = id->cpu;
569                 ctdp_level->pkg_id = id->pkg;
570                 ctdp_level->die_id = id->die;
571
572                 ret = isst_get_ctdp_control(id, i, ctdp_level);
573                 if (ret)
574                         continue;
575
576                 valid = 1;
577                 pkg_dev->processed = 1;
578                 ctdp_level->processed = 1;
579
580                 if (ctdp_level->pbf_support) {
581                         ret = isst_get_pbf_info(id, i, &ctdp_level->pbf_info);
582                         if (!ret)
583                                 ctdp_level->pbf_found = 1;
584                 }
585
586                 if (ctdp_level->fact_support) {
587                         ret = isst_get_fact_info(id, i, 0xff,
588                                                  &ctdp_level->fact_info);
589                         if (ret)
590                                 return ret;
591                 }
592
593                 if (!pkg_dev->enabled && is_skx_based_platform()) {
594                         int freq;
595
596                         freq = get_cpufreq_base_freq(id->cpu);
597                         if (freq > 0) {
598                                 ctdp_level->sse_p1 = freq / 100000;
599                                 ctdp_level->tdp_ratio = ctdp_level->sse_p1;
600                         }
601
602                         isst_get_get_trl_from_msr(id, ctdp_level->trl_ratios[0]);
603                         isst_get_trl_bucket_info(id, i, &ctdp_level->trl_cores);
604                         continue;
605                 }
606
607                 ret = isst_get_tdp_info(id, i, ctdp_level);
608                 if (ret)
609                         return ret;
610
611                 ret = isst_get_pwr_info(id, i, ctdp_level);
612                 if (ret)
613                         return ret;
614
615                 ctdp_level->core_cpumask_size =
616                         alloc_cpu_set(&ctdp_level->core_cpumask);
617                 ret = isst_get_coremask_info(id, i, ctdp_level);
618                 if (ret)
619                         return ret;
620
621                 ret = isst_get_trl_bucket_info(id, i, &ctdp_level->trl_cores);
622                 if (ret)
623                         return ret;
624
625                 ret = isst_get_get_trls(id, i, ctdp_level);
626                 if (ret)
627                         return ret;
628         }
629
630         if (!valid)
631                 isst_display_error_info_message(0, "Invalid level, Can't get TDP control information at specified levels on cpu", 1, id->cpu);
632
633         return 0;
634 }
635
636 int isst_clos_get_clos_information(struct isst_id *id, int *enable, int *type)
637 {
638         CHECK_CB(get_clos_information);
639         return isst_ops->get_clos_information(id, enable, type);
640 }
641
642 int isst_pm_qos_config(struct isst_id *id, int enable_clos, int priority_type)
643 {
644         unsigned int req, resp;
645         int ret;
646
647         if (!enable_clos) {
648                 struct isst_pkg_ctdp pkg_dev;
649                 struct isst_pkg_ctdp_level_info ctdp_level;
650
651                 ret = isst_get_ctdp_levels(id, &pkg_dev);
652                 if (ret) {
653                         debug_printf("isst_get_ctdp_levels\n");
654                         return ret;
655                 }
656
657                 ret = isst_get_ctdp_control(id, pkg_dev.current_level,
658                                             &ctdp_level);
659                 if (ret)
660                         return ret;
661
662                 if (ctdp_level.fact_enabled) {
663                         isst_display_error_info_message(1, "Ignoring request, turbo-freq feature is still enabled", 0, 0);
664                         return -EINVAL;
665                 }
666                 ret = isst_write_pm_config(id, 0);
667                 if (ret)
668                         isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0);
669         } else {
670                 ret = isst_write_pm_config(id, 1);
671                 if (ret)
672                         isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0);
673         }
674
675         ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
676                                      &resp);
677         if (ret) {
678                 isst_display_error_info_message(1, "CLOS_PM_QOS_CONFIG command failed", 0, 0);
679                 return ret;
680         }
681
682         debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", id->cpu, resp);
683
684         req = resp;
685
686         if (enable_clos)
687                 req = req | BIT(1);
688         else
689                 req = req & ~BIT(1);
690
691         if (priority_type > 1)
692                 isst_display_error_info_message(1, "Invalid priority type: Changing type to ordered", 0, 0);
693
694         if (priority_type)
695                 req = req | BIT(2);
696         else
697                 req = req & ~BIT(2);
698
699         ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG,
700                                      BIT(MBOX_CMD_WRITE_BIT), req, &resp);
701         if (ret)
702                 return ret;
703
704         debug_printf("cpu:%d CLOS_PM_QOS_CONFIG priority type:%d req:%x\n", id->cpu,
705                      priority_type, req);
706
707         return 0;
708 }
709
710 int isst_pm_get_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_config)
711 {
712         unsigned int resp;
713         int ret;
714
715         ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0,
716                                      &resp);
717         if (ret)
718                 return ret;
719
720         clos_config->epp = resp & 0x0f;
721         clos_config->clos_prop_prio = (resp >> 4) & 0x0f;
722         clos_config->clos_min = (resp >> 8) & 0xff;
723         clos_config->clos_max = (resp >> 16) & 0xff;
724         clos_config->clos_desired = (resp >> 24) & 0xff;
725
726         return 0;
727 }
728
729 int isst_set_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_config)
730 {
731         unsigned int req, resp;
732         unsigned int param;
733         int ret;
734
735         req = clos_config->epp & 0x0f;
736         req |= (clos_config->clos_prop_prio & 0x0f) << 4;
737         req |= (clos_config->clos_min & 0xff) << 8;
738         req |= (clos_config->clos_max & 0xff) << 16;
739         req |= (clos_config->clos_desired & 0xff) << 24;
740
741         param = BIT(MBOX_CMD_WRITE_BIT) | clos;
742
743         ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req,
744                                      &resp);
745         if (ret)
746                 return ret;
747
748         debug_printf("cpu:%d CLOS_PM_CLOS param:%x req:%x\n", id->cpu, param, req);
749
750         return 0;
751 }
752
753 int isst_clos_get_assoc_status(struct isst_id *id, int *clos_id)
754 {
755         unsigned int resp;
756         unsigned int param;
757         int core_id, ret;
758
759         core_id = find_phy_core_num(id->cpu);
760         param = core_id;
761
762         ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0,
763                                      &resp);
764         if (ret)
765                 return ret;
766
767         debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x resp:%x\n", id->cpu, param,
768                      resp);
769         *clos_id = (resp >> 16) & 0x03;
770
771         return 0;
772 }
773
774 int isst_clos_associate(struct isst_id *id, int clos_id)
775 {
776         unsigned int req, resp;
777         unsigned int param;
778         int core_id, ret;
779
780         req = (clos_id & 0x03) << 16;
781         core_id = find_phy_core_num(id->cpu);
782         param = BIT(MBOX_CMD_WRITE_BIT) | core_id;
783
784         ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param,
785                                      req, &resp);
786         if (ret)
787                 return ret;
788
789         debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x req:%x\n", id->cpu, param,
790                      req);
791
792         return 0;
793 }