.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * Intel SOC Telemetry Platform Driver: Currently supports APL |
---|
3 | 4 | * Copyright (c) 2015, Intel Corporation. |
---|
4 | 5 | * All Rights Reserved. |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify it |
---|
7 | | - * under the terms and conditions of the GNU General Public License, |
---|
8 | | - * version 2, as published by the Free Software Foundation. |
---|
9 | | - * |
---|
10 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
13 | | - * more details. |
---|
14 | 6 | * |
---|
15 | 7 | * This file provides the platform specific telemetry implementation for APL. |
---|
16 | 8 | * It used the PUNIT and PMC IPC interfaces for configuring the counters. |
---|
.. | .. |
---|
23 | 15 | |
---|
24 | 16 | #include <asm/cpu_device_id.h> |
---|
25 | 17 | #include <asm/intel-family.h> |
---|
26 | | -#include <asm/intel_pmc_ipc.h> |
---|
27 | 18 | #include <asm/intel_punit_ipc.h> |
---|
28 | 19 | #include <asm/intel_telemetry.h> |
---|
29 | 20 | |
---|
.. | .. |
---|
43 | 34 | #define TELEM_SSRAM_STARTTIME_OFFSET 8 |
---|
44 | 35 | #define TELEM_SSRAM_EVTLOG_OFFSET 16 |
---|
45 | 36 | |
---|
| 37 | +#define IOSS_TELEM 0xeb |
---|
46 | 38 | #define IOSS_TELEM_EVENT_READ 0x0 |
---|
47 | 39 | #define IOSS_TELEM_EVENT_WRITE 0x1 |
---|
48 | 40 | #define IOSS_TELEM_INFO_READ 0x2 |
---|
.. | .. |
---|
50 | 42 | #define IOSS_TELEM_TRACE_CTL_WRITE 0x6 |
---|
51 | 43 | #define IOSS_TELEM_EVENT_CTL_READ 0x7 |
---|
52 | 44 | #define IOSS_TELEM_EVENT_CTL_WRITE 0x8 |
---|
53 | | -#define IOSS_TELEM_EVT_CTRL_WRITE_SIZE 0x4 |
---|
54 | | -#define IOSS_TELEM_READ_WORD 0x1 |
---|
55 | | -#define IOSS_TELEM_WRITE_FOURBYTES 0x4 |
---|
56 | 45 | #define IOSS_TELEM_EVT_WRITE_SIZE 0x3 |
---|
57 | 46 | |
---|
58 | 47 | #define TELEM_INFO_SRAMEVTS_MASK 0xFF00 |
---|
.. | .. |
---|
74 | 63 | #define TELEM_EXTRACT_VERBOSITY(x, y) ((y) = (((x) >> 27) & 0x3)) |
---|
75 | 64 | #define TELEM_CLEAR_VERBOSITY_BITS(x) ((x) &= ~(BIT(27) | BIT(28))) |
---|
76 | 65 | #define TELEM_SET_VERBOSITY_BITS(x, y) ((x) |= ((y) << 27)) |
---|
77 | | - |
---|
78 | | -#define TELEM_CPU(model, data) \ |
---|
79 | | - { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&data } |
---|
80 | 66 | |
---|
81 | 67 | enum telemetry_action { |
---|
82 | 68 | TELEM_UPDATE = 0, |
---|
.. | .. |
---|
191 | 177 | }; |
---|
192 | 178 | |
---|
193 | 179 | static const struct x86_cpu_id telemetry_cpu_ids[] = { |
---|
194 | | - TELEM_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_config), |
---|
195 | | - TELEM_CPU(INTEL_FAM6_ATOM_GOLDMONT_PLUS, telem_glk_config), |
---|
| 180 | + X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &telem_apl_config), |
---|
| 181 | + X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS, &telem_glk_config), |
---|
196 | 182 | {} |
---|
197 | 183 | }; |
---|
198 | 184 | |
---|
.. | .. |
---|
261 | 247 | static inline int telemetry_plt_config_ioss_event(u32 evt_id, int index) |
---|
262 | 248 | { |
---|
263 | 249 | u32 write_buf; |
---|
264 | | - int ret; |
---|
265 | 250 | |
---|
266 | 251 | write_buf = evt_id | TELEM_EVENT_ENABLE; |
---|
267 | 252 | write_buf <<= BITS_PER_BYTE; |
---|
268 | 253 | write_buf |= index; |
---|
269 | 254 | |
---|
270 | | - ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, |
---|
271 | | - IOSS_TELEM_EVENT_WRITE, (u8 *)&write_buf, |
---|
272 | | - IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0); |
---|
273 | | - |
---|
274 | | - return ret; |
---|
| 255 | + return intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM, |
---|
| 256 | + IOSS_TELEM_EVENT_WRITE, &write_buf, |
---|
| 257 | + IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0); |
---|
275 | 258 | } |
---|
276 | 259 | |
---|
277 | 260 | static inline int telemetry_plt_config_pss_event(u32 evt_id, int index) |
---|
.. | .. |
---|
289 | 272 | static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig, |
---|
290 | 273 | enum telemetry_action action) |
---|
291 | 274 | { |
---|
| 275 | + struct intel_scu_ipc_dev *scu = telm_conf->scu; |
---|
292 | 276 | u8 num_ioss_evts, ioss_period; |
---|
293 | 277 | int ret, index, idx; |
---|
294 | 278 | u32 *ioss_evtmap; |
---|
.. | .. |
---|
299 | 283 | ioss_evtmap = evtconfig.evtmap; |
---|
300 | 284 | |
---|
301 | 285 | /* Get telemetry EVENT CTL */ |
---|
302 | | - ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, |
---|
| 286 | + ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, |
---|
303 | 287 | IOSS_TELEM_EVENT_CTL_READ, NULL, 0, |
---|
304 | | - &telem_ctrl, IOSS_TELEM_READ_WORD); |
---|
| 288 | + &telem_ctrl, sizeof(telem_ctrl)); |
---|
305 | 289 | if (ret) { |
---|
306 | 290 | pr_err("IOSS TELEM_CTRL Read Failed\n"); |
---|
307 | 291 | return ret; |
---|
.. | .. |
---|
310 | 294 | /* Disable Telemetry */ |
---|
311 | 295 | TELEM_DISABLE(telem_ctrl); |
---|
312 | 296 | |
---|
313 | | - ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, |
---|
314 | | - IOSS_TELEM_EVENT_CTL_WRITE, |
---|
315 | | - (u8 *)&telem_ctrl, |
---|
316 | | - IOSS_TELEM_EVT_CTRL_WRITE_SIZE, |
---|
317 | | - NULL, 0); |
---|
| 297 | + ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, |
---|
| 298 | + IOSS_TELEM_EVENT_CTL_WRITE, &telem_ctrl, |
---|
| 299 | + sizeof(telem_ctrl), NULL, 0); |
---|
318 | 300 | if (ret) { |
---|
319 | 301 | pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n"); |
---|
320 | 302 | return ret; |
---|
.. | .. |
---|
326 | 308 | /* Clear All Events */ |
---|
327 | 309 | TELEM_CLEAR_EVENTS(telem_ctrl); |
---|
328 | 310 | |
---|
329 | | - ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, |
---|
| 311 | + ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, |
---|
330 | 312 | IOSS_TELEM_EVENT_CTL_WRITE, |
---|
331 | | - (u8 *)&telem_ctrl, |
---|
332 | | - IOSS_TELEM_EVT_CTRL_WRITE_SIZE, |
---|
| 313 | + &telem_ctrl, sizeof(telem_ctrl), |
---|
333 | 314 | NULL, 0); |
---|
334 | 315 | if (ret) { |
---|
335 | 316 | pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n"); |
---|
.. | .. |
---|
355 | 336 | /* Clear All Events */ |
---|
356 | 337 | TELEM_CLEAR_EVENTS(telem_ctrl); |
---|
357 | 338 | |
---|
358 | | - ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, |
---|
| 339 | + ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, |
---|
359 | 340 | IOSS_TELEM_EVENT_CTL_WRITE, |
---|
360 | | - (u8 *)&telem_ctrl, |
---|
361 | | - IOSS_TELEM_EVT_CTRL_WRITE_SIZE, |
---|
| 341 | + &telem_ctrl, sizeof(telem_ctrl), |
---|
362 | 342 | NULL, 0); |
---|
363 | 343 | if (ret) { |
---|
364 | 344 | pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n"); |
---|
.. | .. |
---|
407 | 387 | TELEM_ENABLE_PERIODIC(telem_ctrl); |
---|
408 | 388 | telem_ctrl |= ioss_period; |
---|
409 | 389 | |
---|
410 | | - ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, |
---|
| 390 | + ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, |
---|
411 | 391 | IOSS_TELEM_EVENT_CTL_WRITE, |
---|
412 | | - (u8 *)&telem_ctrl, |
---|
413 | | - IOSS_TELEM_EVT_CTRL_WRITE_SIZE, NULL, 0); |
---|
| 392 | + &telem_ctrl, sizeof(telem_ctrl), NULL, 0); |
---|
414 | 393 | if (ret) { |
---|
415 | 394 | pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n"); |
---|
416 | 395 | return ret; |
---|
.. | .. |
---|
597 | 576 | u32 read_buf, events, event_regs; |
---|
598 | 577 | int ret; |
---|
599 | 578 | |
---|
600 | | - ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, IOSS_TELEM_INFO_READ, |
---|
601 | | - NULL, 0, &read_buf, IOSS_TELEM_READ_WORD); |
---|
| 579 | + ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM, |
---|
| 580 | + IOSS_TELEM_INFO_READ, NULL, 0, |
---|
| 581 | + &read_buf, sizeof(read_buf)); |
---|
602 | 582 | if (ret) { |
---|
603 | 583 | dev_err(&pdev->dev, "IOSS TELEM_INFO Read Failed\n"); |
---|
604 | 584 | return ret; |
---|
.. | .. |
---|
692 | 672 | |
---|
693 | 673 | mutex_lock(&(telm_conf->telem_lock)); |
---|
694 | 674 | if (ioss_period) { |
---|
| 675 | + struct intel_scu_ipc_dev *scu = telm_conf->scu; |
---|
| 676 | + |
---|
695 | 677 | if (TELEM_SAMPLE_PERIOD_INVALID(ioss_period)) { |
---|
696 | 678 | pr_err("IOSS Sampling Period Out of Range\n"); |
---|
697 | 679 | ret = -EINVAL; |
---|
.. | .. |
---|
699 | 681 | } |
---|
700 | 682 | |
---|
701 | 683 | /* Get telemetry EVENT CTL */ |
---|
702 | | - ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, |
---|
| 684 | + ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, |
---|
703 | 685 | IOSS_TELEM_EVENT_CTL_READ, NULL, 0, |
---|
704 | | - &telem_ctrl, IOSS_TELEM_READ_WORD); |
---|
| 686 | + &telem_ctrl, sizeof(telem_ctrl)); |
---|
705 | 687 | if (ret) { |
---|
706 | 688 | pr_err("IOSS TELEM_CTRL Read Failed\n"); |
---|
707 | 689 | goto out; |
---|
.. | .. |
---|
710 | 692 | /* Disable Telemetry */ |
---|
711 | 693 | TELEM_DISABLE(telem_ctrl); |
---|
712 | 694 | |
---|
713 | | - ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, |
---|
714 | | - IOSS_TELEM_EVENT_CTL_WRITE, |
---|
715 | | - (u8 *)&telem_ctrl, |
---|
716 | | - IOSS_TELEM_EVT_CTRL_WRITE_SIZE, |
---|
717 | | - NULL, 0); |
---|
| 695 | + ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, |
---|
| 696 | + IOSS_TELEM_EVENT_CTL_WRITE, |
---|
| 697 | + &telem_ctrl, sizeof(telem_ctrl), |
---|
| 698 | + NULL, 0); |
---|
718 | 699 | if (ret) { |
---|
719 | 700 | pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n"); |
---|
720 | 701 | goto out; |
---|
.. | .. |
---|
726 | 707 | TELEM_ENABLE_PERIODIC(telem_ctrl); |
---|
727 | 708 | telem_ctrl |= ioss_period; |
---|
728 | 709 | |
---|
729 | | - ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, |
---|
730 | | - IOSS_TELEM_EVENT_CTL_WRITE, |
---|
731 | | - (u8 *)&telem_ctrl, |
---|
732 | | - IOSS_TELEM_EVT_CTRL_WRITE_SIZE, |
---|
733 | | - NULL, 0); |
---|
| 710 | + ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, |
---|
| 711 | + IOSS_TELEM_EVENT_CTL_WRITE, |
---|
| 712 | + &telem_ctrl, sizeof(telem_ctrl), |
---|
| 713 | + NULL, 0); |
---|
734 | 714 | if (ret) { |
---|
735 | 715 | pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n"); |
---|
736 | 716 | goto out; |
---|
.. | .. |
---|
1025 | 1005 | break; |
---|
1026 | 1006 | |
---|
1027 | 1007 | case TELEM_IOSS: |
---|
1028 | | - ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, |
---|
1029 | | - IOSS_TELEM_TRACE_CTL_READ, NULL, 0, &temp, |
---|
1030 | | - IOSS_TELEM_READ_WORD); |
---|
| 1008 | + ret = intel_scu_ipc_dev_command(telm_conf->scu, |
---|
| 1009 | + IOSS_TELEM, IOSS_TELEM_TRACE_CTL_READ, |
---|
| 1010 | + NULL, 0, &temp, sizeof(temp)); |
---|
1031 | 1011 | if (ret) { |
---|
1032 | 1012 | pr_err("IOSS TRACE_CTL Read Failed\n"); |
---|
1033 | 1013 | goto out; |
---|
.. | .. |
---|
1079 | 1059 | break; |
---|
1080 | 1060 | |
---|
1081 | 1061 | case TELEM_IOSS: |
---|
1082 | | - ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, |
---|
1083 | | - IOSS_TELEM_TRACE_CTL_READ, NULL, 0, &temp, |
---|
1084 | | - IOSS_TELEM_READ_WORD); |
---|
| 1062 | + ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM, |
---|
| 1063 | + IOSS_TELEM_TRACE_CTL_READ, |
---|
| 1064 | + NULL, 0, &temp, sizeof(temp)); |
---|
1085 | 1065 | if (ret) { |
---|
1086 | 1066 | pr_err("IOSS TRACE_CTL Read Failed\n"); |
---|
1087 | 1067 | goto out; |
---|
.. | .. |
---|
1090 | 1070 | TELEM_CLEAR_VERBOSITY_BITS(temp); |
---|
1091 | 1071 | TELEM_SET_VERBOSITY_BITS(temp, verbosity); |
---|
1092 | 1072 | |
---|
1093 | | - ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, |
---|
1094 | | - IOSS_TELEM_TRACE_CTL_WRITE, (u8 *)&temp, |
---|
1095 | | - IOSS_TELEM_WRITE_FOURBYTES, NULL, 0); |
---|
| 1073 | + ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM, |
---|
| 1074 | + IOSS_TELEM_TRACE_CTL_WRITE, |
---|
| 1075 | + &temp, sizeof(temp), NULL, 0); |
---|
1096 | 1076 | if (ret) { |
---|
1097 | 1077 | pr_err("IOSS TRACE_CTL Verbosity Set Failed\n"); |
---|
1098 | 1078 | goto out; |
---|
.. | .. |
---|
1125 | 1105 | |
---|
1126 | 1106 | static int telemetry_pltdrv_probe(struct platform_device *pdev) |
---|
1127 | 1107 | { |
---|
1128 | | - struct resource *res0 = NULL, *res1 = NULL; |
---|
1129 | 1108 | const struct x86_cpu_id *id; |
---|
1130 | | - int size, ret = -ENOMEM; |
---|
| 1109 | + void __iomem *mem; |
---|
| 1110 | + int ret; |
---|
1131 | 1111 | |
---|
1132 | 1112 | id = x86_match_cpu(telemetry_cpu_ids); |
---|
1133 | 1113 | if (!id) |
---|
.. | .. |
---|
1135 | 1115 | |
---|
1136 | 1116 | telm_conf = (struct telemetry_plt_config *)id->driver_data; |
---|
1137 | 1117 | |
---|
1138 | | - res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
1139 | | - if (!res0) { |
---|
1140 | | - ret = -EINVAL; |
---|
1141 | | - goto out; |
---|
1142 | | - } |
---|
1143 | | - size = resource_size(res0); |
---|
1144 | | - if (!devm_request_mem_region(&pdev->dev, res0->start, size, |
---|
1145 | | - pdev->name)) { |
---|
1146 | | - ret = -EBUSY; |
---|
1147 | | - goto out; |
---|
1148 | | - } |
---|
1149 | | - telm_conf->pss_config.ssram_base_addr = res0->start; |
---|
1150 | | - telm_conf->pss_config.ssram_size = size; |
---|
| 1118 | + telm_conf->pmc = dev_get_drvdata(pdev->dev.parent); |
---|
1151 | 1119 | |
---|
1152 | | - res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
---|
1153 | | - if (!res1) { |
---|
1154 | | - ret = -EINVAL; |
---|
1155 | | - goto out; |
---|
1156 | | - } |
---|
1157 | | - size = resource_size(res1); |
---|
1158 | | - if (!devm_request_mem_region(&pdev->dev, res1->start, size, |
---|
1159 | | - pdev->name)) { |
---|
1160 | | - ret = -EBUSY; |
---|
1161 | | - goto out; |
---|
1162 | | - } |
---|
| 1120 | + mem = devm_platform_ioremap_resource(pdev, 0); |
---|
| 1121 | + if (IS_ERR(mem)) |
---|
| 1122 | + return PTR_ERR(mem); |
---|
1163 | 1123 | |
---|
1164 | | - telm_conf->ioss_config.ssram_base_addr = res1->start; |
---|
1165 | | - telm_conf->ioss_config.ssram_size = size; |
---|
| 1124 | + telm_conf->pss_config.regmap = mem; |
---|
1166 | 1125 | |
---|
1167 | | - telm_conf->pss_config.regmap = ioremap_nocache( |
---|
1168 | | - telm_conf->pss_config.ssram_base_addr, |
---|
1169 | | - telm_conf->pss_config.ssram_size); |
---|
1170 | | - if (!telm_conf->pss_config.regmap) { |
---|
1171 | | - ret = -ENOMEM; |
---|
1172 | | - goto out; |
---|
1173 | | - } |
---|
| 1126 | + mem = devm_platform_ioremap_resource(pdev, 1); |
---|
| 1127 | + if (IS_ERR(mem)) |
---|
| 1128 | + return PTR_ERR(mem); |
---|
1174 | 1129 | |
---|
1175 | | - telm_conf->ioss_config.regmap = ioremap_nocache( |
---|
1176 | | - telm_conf->ioss_config.ssram_base_addr, |
---|
1177 | | - telm_conf->ioss_config.ssram_size); |
---|
1178 | | - if (!telm_conf->ioss_config.regmap) { |
---|
1179 | | - ret = -ENOMEM; |
---|
| 1130 | + telm_conf->ioss_config.regmap = mem; |
---|
| 1131 | + |
---|
| 1132 | + telm_conf->scu = devm_intel_scu_ipc_dev_get(&pdev->dev); |
---|
| 1133 | + if (!telm_conf->scu) { |
---|
| 1134 | + ret = -EPROBE_DEFER; |
---|
1180 | 1135 | goto out; |
---|
1181 | 1136 | } |
---|
1182 | 1137 | |
---|
.. | .. |
---|
1196 | 1151 | return 0; |
---|
1197 | 1152 | |
---|
1198 | 1153 | out: |
---|
1199 | | - if (res0) |
---|
1200 | | - release_mem_region(res0->start, resource_size(res0)); |
---|
1201 | | - if (res1) |
---|
1202 | | - release_mem_region(res1->start, resource_size(res1)); |
---|
1203 | | - if (telm_conf->pss_config.regmap) |
---|
1204 | | - iounmap(telm_conf->pss_config.regmap); |
---|
1205 | | - if (telm_conf->ioss_config.regmap) |
---|
1206 | | - iounmap(telm_conf->ioss_config.regmap); |
---|
1207 | 1154 | dev_err(&pdev->dev, "TELEMETRY Setup Failed.\n"); |
---|
1208 | 1155 | |
---|
1209 | 1156 | return ret; |
---|
.. | .. |
---|
1212 | 1159 | static int telemetry_pltdrv_remove(struct platform_device *pdev) |
---|
1213 | 1160 | { |
---|
1214 | 1161 | telemetry_clear_pltdata(); |
---|
1215 | | - iounmap(telm_conf->pss_config.regmap); |
---|
1216 | | - iounmap(telm_conf->ioss_config.regmap); |
---|
1217 | | - |
---|
1218 | 1162 | return 0; |
---|
1219 | 1163 | } |
---|
1220 | 1164 | |
---|
.. | .. |
---|
1242 | 1186 | MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>"); |
---|
1243 | 1187 | MODULE_DESCRIPTION("Intel SoC Telemetry Platform Driver"); |
---|
1244 | 1188 | MODULE_VERSION(DRIVER_VERSION); |
---|
1245 | | -MODULE_LICENSE("GPL"); |
---|
| 1189 | +MODULE_LICENSE("GPL v2"); |
---|