• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Intel SOC Telemetry Platform Driver: Currently supports APL
3  * Copyright (c) 2015, Intel Corporation.
4  * 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  *
15  * This file provides the platform specific telemetry implementation for APL.
16  * It used the PUNIT and PMC IPC interfaces for configuring the counters.
17  * The accumulated results are fetched from SRAM.
18  */
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/device.h>
22 #include <linux/debugfs.h>
23 #include <linux/seq_file.h>
24 #include <linux/io.h>
25 #include <linux/uaccess.h>
26 #include <linux/pci.h>
27 #include <linux/suspend.h>
28 #include <linux/platform_device.h>
29 
30 #include <asm/cpu_device_id.h>
31 #include <asm/intel-family.h>
32 #include <asm/intel_pmc_ipc.h>
33 #include <asm/intel_punit_ipc.h>
34 #include <asm/intel_telemetry.h>
35 
36 #define DRIVER_NAME	"intel_telemetry"
37 #define DRIVER_VERSION	"1.0.0"
38 
39 #define TELEM_TRC_VERBOSITY_MASK	0x3
40 
41 #define TELEM_MIN_PERIOD(x)		((x) & 0x7F0000)
42 #define TELEM_MAX_PERIOD(x)		((x) & 0x7F000000)
43 #define TELEM_SAMPLE_PERIOD_INVALID(x)	((x) & (BIT(7)))
44 #define TELEM_CLEAR_SAMPLE_PERIOD(x)	((x) &= ~0x7F)
45 
46 #define TELEM_SAMPLING_DEFAULT_PERIOD	0xD
47 
48 #define TELEM_MAX_EVENTS_SRAM		28
49 #define TELEM_MAX_OS_ALLOCATED_EVENTS	20
50 #define TELEM_SSRAM_STARTTIME_OFFSET	8
51 #define TELEM_SSRAM_EVTLOG_OFFSET	16
52 
53 #define IOSS_TELEM_EVENT_READ		0x0
54 #define IOSS_TELEM_EVENT_WRITE		0x1
55 #define IOSS_TELEM_INFO_READ		0x2
56 #define IOSS_TELEM_TRACE_CTL_READ	0x5
57 #define IOSS_TELEM_TRACE_CTL_WRITE	0x6
58 #define IOSS_TELEM_EVENT_CTL_READ	0x7
59 #define IOSS_TELEM_EVENT_CTL_WRITE	0x8
60 #define IOSS_TELEM_EVT_CTRL_WRITE_SIZE	0x4
61 #define IOSS_TELEM_READ_WORD		0x1
62 #define IOSS_TELEM_WRITE_FOURBYTES	0x4
63 #define IOSS_TELEM_EVT_WRITE_SIZE	0x3
64 
65 #define TELEM_INFO_SRAMEVTS_MASK	0xFF00
66 #define TELEM_INFO_SRAMEVTS_SHIFT	0x8
67 #define TELEM_SSRAM_READ_TIMEOUT	10
68 
69 #define TELEM_INFO_NENABLES_MASK	0xFF
70 #define TELEM_EVENT_ENABLE		0x8000
71 
72 #define TELEM_MASK_BIT			1
73 #define TELEM_MASK_BYTE			0xFF
74 #define BYTES_PER_LONG			8
75 #define TELEM_MASK_PCS_STATE		0xF
76 
77 #define TELEM_DISABLE(x)		((x) &= ~(BIT(31)))
78 #define TELEM_CLEAR_EVENTS(x)		((x) |= (BIT(30)))
79 #define TELEM_ENABLE_SRAM_EVT_TRACE(x)	((x) &= ~(BIT(30) | BIT(24)))
80 #define TELEM_ENABLE_PERIODIC(x)	((x) |= (BIT(23) | BIT(31) | BIT(7)))
81 #define TELEM_EXTRACT_VERBOSITY(x, y)	((y) = (((x) >> 27) & 0x3))
82 #define TELEM_CLEAR_VERBOSITY_BITS(x)	((x) &= ~(BIT(27) | BIT(28)))
83 #define TELEM_SET_VERBOSITY_BITS(x, y)	((x) |= ((y) << 27))
84 
85 #define TELEM_CPU(model, data) \
86 	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&data }
87 
88 enum telemetry_action {
89 	TELEM_UPDATE = 0,
90 	TELEM_ADD,
91 	TELEM_RESET,
92 	TELEM_ACTION_NONE
93 };
94 
95 struct telem_ssram_region {
96 	u64 timestamp;
97 	u64 start_time;
98 	u64 events[TELEM_MAX_EVENTS_SRAM];
99 };
100 
101 static struct telemetry_plt_config *telm_conf;
102 
103 /*
104  * The following counters are programmed by default during setup.
105  * Only 20 allocated to kernel driver
106  */
107 static struct telemetry_evtmap
108 	telemetry_apl_ioss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
109 	{"SOC_S0IX_TOTAL_RES",			0x4800},
110 	{"SOC_S0IX_TOTAL_OCC",			0x4000},
111 	{"SOC_S0IX_SHALLOW_RES",		0x4801},
112 	{"SOC_S0IX_SHALLOW_OCC",		0x4001},
113 	{"SOC_S0IX_DEEP_RES",			0x4802},
114 	{"SOC_S0IX_DEEP_OCC",			0x4002},
115 	{"PMC_POWER_GATE",			0x5818},
116 	{"PMC_D3_STATES",			0x5819},
117 	{"PMC_D0I3_STATES",			0x581A},
118 	{"PMC_S0IX_WAKE_REASON_GPIO",		0x6000},
119 	{"PMC_S0IX_WAKE_REASON_TIMER",		0x6001},
120 	{"PMC_S0IX_WAKE_REASON_VNNREQ",         0x6002},
121 	{"PMC_S0IX_WAKE_REASON_LOWPOWER",       0x6003},
122 	{"PMC_S0IX_WAKE_REASON_EXTERNAL",       0x6004},
123 	{"PMC_S0IX_WAKE_REASON_MISC",           0x6005},
124 	{"PMC_S0IX_BLOCKING_IPS_D3_D0I3",       0x6006},
125 	{"PMC_S0IX_BLOCKING_IPS_PG",            0x6007},
126 	{"PMC_S0IX_BLOCKING_MISC_IPS_PG",       0x6008},
127 	{"PMC_S0IX_BLOCK_IPS_VNN_REQ",          0x6009},
128 	{"PMC_S0IX_BLOCK_IPS_CLOCKS",           0x600B},
129 };
130 
131 
132 static struct telemetry_evtmap
133 	telemetry_apl_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
134 	{"IA_CORE0_C6_RES",			0x0400},
135 	{"IA_CORE0_C6_CTR",			0x0000},
136 	{"IA_MODULE0_C7_RES",			0x0410},
137 	{"IA_MODULE0_C7_CTR",			0x000E},
138 	{"IA_C0_RES",				0x0805},
139 	{"PCS_LTR",				0x2801},
140 	{"PSTATES",				0x2802},
141 	{"SOC_S0I3_RES",			0x0409},
142 	{"SOC_S0I3_CTR",			0x000A},
143 	{"PCS_S0I3_CTR",			0x0009},
144 	{"PCS_C1E_RES",				0x041A},
145 	{"PCS_IDLE_STATUS",			0x2806},
146 	{"IA_PERF_LIMITS",			0x280B},
147 	{"GT_PERF_LIMITS",			0x280C},
148 	{"PCS_WAKEUP_S0IX_CTR",			0x0030},
149 	{"PCS_IDLE_BLOCKED",			0x2C00},
150 	{"PCS_S0IX_BLOCKED",			0x2C01},
151 	{"PCS_S0IX_WAKE_REASONS",		0x2C02},
152 	{"PCS_LTR_BLOCKING",			0x2C03},
153 	{"PC2_AND_MEM_SHALLOW_IDLE_RES",	0x1D40},
154 };
155 
156 /* APL specific Data */
157 static struct telemetry_plt_config telem_apl_config = {
158 	.pss_config = {
159 		.telem_evts = telemetry_apl_pss_default_events,
160 	},
161 	.ioss_config = {
162 		.telem_evts = telemetry_apl_ioss_default_events,
163 	},
164 };
165 
166 static const struct x86_cpu_id telemetry_cpu_ids[] = {
167 	TELEM_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_config),
168 	{}
169 };
170 
171 MODULE_DEVICE_TABLE(x86cpu, telemetry_cpu_ids);
172 
telem_get_unitconfig(enum telemetry_unit telem_unit,struct telemetry_unit_config ** unit_config)173 static inline int telem_get_unitconfig(enum telemetry_unit telem_unit,
174 				     struct telemetry_unit_config **unit_config)
175 {
176 	if (telem_unit == TELEM_PSS)
177 		*unit_config = &(telm_conf->pss_config);
178 	else if (telem_unit == TELEM_IOSS)
179 		*unit_config = &(telm_conf->ioss_config);
180 	else
181 		return -EINVAL;
182 
183 	return 0;
184 
185 }
186 
telemetry_check_evtid(enum telemetry_unit telem_unit,u32 * evtmap,u8 len,enum telemetry_action action)187 static int telemetry_check_evtid(enum telemetry_unit telem_unit,
188 				 u32 *evtmap, u8 len,
189 				 enum telemetry_action action)
190 {
191 	struct telemetry_unit_config *unit_config;
192 	int ret;
193 
194 	ret = telem_get_unitconfig(telem_unit, &unit_config);
195 	if (ret < 0)
196 		return ret;
197 
198 	switch (action) {
199 	case TELEM_RESET:
200 		if (len > TELEM_MAX_EVENTS_SRAM)
201 			return -EINVAL;
202 
203 		break;
204 
205 	case TELEM_UPDATE:
206 		if (len > TELEM_MAX_EVENTS_SRAM)
207 			return -EINVAL;
208 
209 		if ((len > 0) && (evtmap == NULL))
210 			return -EINVAL;
211 
212 		break;
213 
214 	case TELEM_ADD:
215 		if ((len + unit_config->ssram_evts_used) >
216 		    TELEM_MAX_EVENTS_SRAM)
217 			return -EINVAL;
218 
219 		if ((len > 0) && (evtmap == NULL))
220 			return -EINVAL;
221 
222 		break;
223 
224 	default:
225 		pr_err("Unknown Telemetry action Specified %d\n", action);
226 		return -EINVAL;
227 	}
228 
229 	return 0;
230 }
231 
232 
telemetry_plt_config_ioss_event(u32 evt_id,int index)233 static inline int telemetry_plt_config_ioss_event(u32 evt_id, int index)
234 {
235 	u32 write_buf;
236 	int ret;
237 
238 	write_buf = evt_id | TELEM_EVENT_ENABLE;
239 	write_buf <<= BITS_PER_BYTE;
240 	write_buf |= index;
241 
242 	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
243 				    IOSS_TELEM_EVENT_WRITE, (u8 *)&write_buf,
244 				    IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0);
245 
246 	return ret;
247 }
248 
telemetry_plt_config_pss_event(u32 evt_id,int index)249 static inline int telemetry_plt_config_pss_event(u32 evt_id, int index)
250 {
251 	u32 write_buf;
252 	int ret;
253 
254 	write_buf = evt_id | TELEM_EVENT_ENABLE;
255 	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT,
256 				      index, 0, &write_buf, NULL);
257 
258 	return ret;
259 }
260 
telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,enum telemetry_action action)261 static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
262 					 enum telemetry_action action)
263 {
264 	u8 num_ioss_evts, ioss_period;
265 	int ret, index, idx;
266 	u32 *ioss_evtmap;
267 	u32 telem_ctrl;
268 
269 	num_ioss_evts = evtconfig.num_evts;
270 	ioss_period = evtconfig.period;
271 	ioss_evtmap = evtconfig.evtmap;
272 
273 	/* Get telemetry EVENT CTL */
274 	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
275 				    IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
276 				    &telem_ctrl, IOSS_TELEM_READ_WORD);
277 	if (ret) {
278 		pr_err("IOSS TELEM_CTRL Read Failed\n");
279 		return ret;
280 	}
281 
282 	/* Disable Telemetry */
283 	TELEM_DISABLE(telem_ctrl);
284 
285 	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
286 				    IOSS_TELEM_EVENT_CTL_WRITE,
287 				    (u8 *)&telem_ctrl,
288 				    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
289 				    NULL, 0);
290 	if (ret) {
291 		pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
292 		return ret;
293 	}
294 
295 
296 	/* Reset Everything */
297 	if (action == TELEM_RESET) {
298 		/* Clear All Events */
299 		TELEM_CLEAR_EVENTS(telem_ctrl);
300 
301 		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
302 					    IOSS_TELEM_EVENT_CTL_WRITE,
303 					    (u8 *)&telem_ctrl,
304 					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
305 					    NULL, 0);
306 		if (ret) {
307 			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
308 			return ret;
309 		}
310 		telm_conf->ioss_config.ssram_evts_used = 0;
311 
312 		/* Configure Events */
313 		for (idx = 0; idx < num_ioss_evts; idx++) {
314 			if (telemetry_plt_config_ioss_event(
315 			    telm_conf->ioss_config.telem_evts[idx].evt_id,
316 			    idx)) {
317 				pr_err("IOSS TELEM_RESET Fail for data: %x\n",
318 				telm_conf->ioss_config.telem_evts[idx].evt_id);
319 				continue;
320 			}
321 			telm_conf->ioss_config.ssram_evts_used++;
322 		}
323 	}
324 
325 	/* Re-Configure Everything */
326 	if (action == TELEM_UPDATE) {
327 		/* Clear All Events */
328 		TELEM_CLEAR_EVENTS(telem_ctrl);
329 
330 		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
331 					    IOSS_TELEM_EVENT_CTL_WRITE,
332 					    (u8 *)&telem_ctrl,
333 					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
334 					    NULL, 0);
335 		if (ret) {
336 			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
337 			return ret;
338 		}
339 		telm_conf->ioss_config.ssram_evts_used = 0;
340 
341 		/* Configure Events */
342 		for (index = 0; index < num_ioss_evts; index++) {
343 			telm_conf->ioss_config.telem_evts[index].evt_id =
344 			ioss_evtmap[index];
345 
346 			if (telemetry_plt_config_ioss_event(
347 			    telm_conf->ioss_config.telem_evts[index].evt_id,
348 			    index)) {
349 				pr_err("IOSS TELEM_UPDATE Fail for Evt%x\n",
350 					ioss_evtmap[index]);
351 				continue;
352 			}
353 			telm_conf->ioss_config.ssram_evts_used++;
354 		}
355 	}
356 
357 	/* Add some Events */
358 	if (action == TELEM_ADD) {
359 		/* Configure Events */
360 		for (index = telm_conf->ioss_config.ssram_evts_used, idx = 0;
361 		     idx < num_ioss_evts; index++, idx++) {
362 			telm_conf->ioss_config.telem_evts[index].evt_id =
363 			ioss_evtmap[idx];
364 
365 			if (telemetry_plt_config_ioss_event(
366 			    telm_conf->ioss_config.telem_evts[index].evt_id,
367 			    index)) {
368 				pr_err("IOSS TELEM_ADD Fail for Event %x\n",
369 					ioss_evtmap[idx]);
370 				continue;
371 			}
372 			telm_conf->ioss_config.ssram_evts_used++;
373 		}
374 	}
375 
376 	/* Enable Periodic Telemetry Events and enable SRAM trace */
377 	TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
378 	TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
379 	TELEM_ENABLE_PERIODIC(telem_ctrl);
380 	telem_ctrl |= ioss_period;
381 
382 	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
383 				    IOSS_TELEM_EVENT_CTL_WRITE,
384 				    (u8 *)&telem_ctrl,
385 				    IOSS_TELEM_EVT_CTRL_WRITE_SIZE, NULL, 0);
386 	if (ret) {
387 		pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
388 		return ret;
389 	}
390 
391 	telm_conf->ioss_config.curr_period = ioss_period;
392 
393 	return 0;
394 }
395 
396 
telemetry_setup_pssevtconfig(struct telemetry_evtconfig evtconfig,enum telemetry_action action)397 static int telemetry_setup_pssevtconfig(struct telemetry_evtconfig evtconfig,
398 					enum telemetry_action action)
399 {
400 	u8 num_pss_evts, pss_period;
401 	int ret, index, idx;
402 	u32 *pss_evtmap;
403 	u32 telem_ctrl;
404 
405 	num_pss_evts = evtconfig.num_evts;
406 	pss_period = evtconfig.period;
407 	pss_evtmap = evtconfig.evtmap;
408 
409 	/* PSS Config */
410 	/* Get telemetry EVENT CTL */
411 	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
412 				      0, 0, NULL, &telem_ctrl);
413 	if (ret) {
414 		pr_err("PSS TELEM_CTRL Read Failed\n");
415 		return ret;
416 	}
417 
418 	/* Disable Telemetry */
419 	TELEM_DISABLE(telem_ctrl);
420 	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
421 				      0, 0, &telem_ctrl, NULL);
422 	if (ret) {
423 		pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
424 		return ret;
425 	}
426 
427 	/* Reset Everything */
428 	if (action == TELEM_RESET) {
429 		/* Clear All Events */
430 		TELEM_CLEAR_EVENTS(telem_ctrl);
431 
432 		ret = intel_punit_ipc_command(
433 				IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
434 				0, 0, &telem_ctrl, NULL);
435 		if (ret) {
436 			pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
437 			return ret;
438 		}
439 		telm_conf->pss_config.ssram_evts_used = 0;
440 		/* Configure Events */
441 		for (idx = 0; idx < num_pss_evts; idx++) {
442 			if (telemetry_plt_config_pss_event(
443 			    telm_conf->pss_config.telem_evts[idx].evt_id,
444 			    idx)) {
445 				pr_err("PSS TELEM_RESET Fail for Event %x\n",
446 				telm_conf->pss_config.telem_evts[idx].evt_id);
447 				continue;
448 			}
449 			telm_conf->pss_config.ssram_evts_used++;
450 		}
451 	}
452 
453 	/* Re-Configure Everything */
454 	if (action == TELEM_UPDATE) {
455 		/* Clear All Events */
456 		TELEM_CLEAR_EVENTS(telem_ctrl);
457 
458 		ret = intel_punit_ipc_command(
459 				IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
460 				0, 0, &telem_ctrl, NULL);
461 		if (ret) {
462 			pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
463 			return ret;
464 		}
465 		telm_conf->pss_config.ssram_evts_used = 0;
466 
467 		/* Configure Events */
468 		for (index = 0; index < num_pss_evts; index++) {
469 			telm_conf->pss_config.telem_evts[index].evt_id =
470 			pss_evtmap[index];
471 
472 			if (telemetry_plt_config_pss_event(
473 			    telm_conf->pss_config.telem_evts[index].evt_id,
474 			    index)) {
475 				pr_err("PSS TELEM_UPDATE Fail for Event %x\n",
476 					pss_evtmap[index]);
477 				continue;
478 			}
479 			telm_conf->pss_config.ssram_evts_used++;
480 		}
481 	}
482 
483 	/* Add some Events */
484 	if (action == TELEM_ADD) {
485 		/* Configure Events */
486 		for (index = telm_conf->pss_config.ssram_evts_used, idx = 0;
487 		     idx < num_pss_evts; index++, idx++) {
488 
489 			telm_conf->pss_config.telem_evts[index].evt_id =
490 			pss_evtmap[idx];
491 
492 			if (telemetry_plt_config_pss_event(
493 			    telm_conf->pss_config.telem_evts[index].evt_id,
494 			    index)) {
495 				pr_err("PSS TELEM_ADD Fail for Event %x\n",
496 					pss_evtmap[idx]);
497 				continue;
498 			}
499 			telm_conf->pss_config.ssram_evts_used++;
500 		}
501 	}
502 
503 	/* Enable Periodic Telemetry Events and enable SRAM trace */
504 	TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
505 	TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
506 	TELEM_ENABLE_PERIODIC(telem_ctrl);
507 	telem_ctrl |= pss_period;
508 
509 	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
510 				      0, 0, &telem_ctrl, NULL);
511 	if (ret) {
512 		pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
513 		return ret;
514 	}
515 
516 	telm_conf->pss_config.curr_period = pss_period;
517 
518 	return 0;
519 }
520 
telemetry_setup_evtconfig(struct telemetry_evtconfig pss_evtconfig,struct telemetry_evtconfig ioss_evtconfig,enum telemetry_action action)521 static int telemetry_setup_evtconfig(struct telemetry_evtconfig pss_evtconfig,
522 				     struct telemetry_evtconfig ioss_evtconfig,
523 				     enum telemetry_action action)
524 {
525 	int ret;
526 
527 	mutex_lock(&(telm_conf->telem_lock));
528 
529 	if ((action == TELEM_UPDATE) && (telm_conf->telem_in_use)) {
530 		ret = -EBUSY;
531 		goto out;
532 	}
533 
534 	ret = telemetry_check_evtid(TELEM_PSS, pss_evtconfig.evtmap,
535 				    pss_evtconfig.num_evts, action);
536 	if (ret)
537 		goto out;
538 
539 	ret = telemetry_check_evtid(TELEM_IOSS, ioss_evtconfig.evtmap,
540 				    ioss_evtconfig.num_evts, action);
541 	if (ret)
542 		goto out;
543 
544 	if (ioss_evtconfig.num_evts) {
545 		ret = telemetry_setup_iossevtconfig(ioss_evtconfig, action);
546 		if (ret)
547 			goto out;
548 	}
549 
550 	if (pss_evtconfig.num_evts) {
551 		ret = telemetry_setup_pssevtconfig(pss_evtconfig, action);
552 		if (ret)
553 			goto out;
554 	}
555 
556 	if ((action == TELEM_UPDATE) || (action == TELEM_ADD))
557 		telm_conf->telem_in_use = true;
558 	else
559 		telm_conf->telem_in_use = false;
560 
561 out:
562 	mutex_unlock(&(telm_conf->telem_lock));
563 	return ret;
564 }
565 
telemetry_setup(struct platform_device * pdev)566 static int telemetry_setup(struct platform_device *pdev)
567 {
568 	struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
569 	u32 read_buf, events, event_regs;
570 	int ret;
571 
572 	ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, IOSS_TELEM_INFO_READ,
573 				    NULL, 0, &read_buf, IOSS_TELEM_READ_WORD);
574 	if (ret) {
575 		dev_err(&pdev->dev, "IOSS TELEM_INFO Read Failed\n");
576 		return ret;
577 	}
578 
579 	/* Get telemetry Info */
580 	events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
581 		  TELEM_INFO_SRAMEVTS_SHIFT;
582 	event_regs = read_buf & TELEM_INFO_NENABLES_MASK;
583 	if ((events < TELEM_MAX_EVENTS_SRAM) ||
584 	    (event_regs < TELEM_MAX_EVENTS_SRAM)) {
585 		dev_err(&pdev->dev, "IOSS:Insufficient Space for SRAM Trace\n");
586 		dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
587 			events, event_regs);
588 		return -ENOMEM;
589 	}
590 
591 	telm_conf->ioss_config.min_period = TELEM_MIN_PERIOD(read_buf);
592 	telm_conf->ioss_config.max_period = TELEM_MAX_PERIOD(read_buf);
593 
594 	/* PUNIT Mailbox Setup */
595 	ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_INFO, 0, 0,
596 				      NULL, &read_buf);
597 	if (ret) {
598 		dev_err(&pdev->dev, "PSS TELEM_INFO Read Failed\n");
599 		return ret;
600 	}
601 
602 	/* Get telemetry Info */
603 	events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
604 		  TELEM_INFO_SRAMEVTS_SHIFT;
605 	event_regs = read_buf & TELEM_INFO_SRAMEVTS_MASK;
606 	if ((events < TELEM_MAX_EVENTS_SRAM) ||
607 	    (event_regs < TELEM_MAX_EVENTS_SRAM)) {
608 		dev_err(&pdev->dev, "PSS:Insufficient Space for SRAM Trace\n");
609 		dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
610 			events, event_regs);
611 		return -ENOMEM;
612 	}
613 
614 	telm_conf->pss_config.min_period = TELEM_MIN_PERIOD(read_buf);
615 	telm_conf->pss_config.max_period = TELEM_MAX_PERIOD(read_buf);
616 
617 	pss_evtconfig.evtmap = NULL;
618 	pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
619 	pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
620 
621 	ioss_evtconfig.evtmap = NULL;
622 	ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
623 	ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
624 
625 	ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
626 					TELEM_RESET);
627 	if (ret) {
628 		dev_err(&pdev->dev, "TELEMTRY Setup Failed\n");
629 		return ret;
630 	}
631 	return 0;
632 }
633 
telemetry_plt_update_events(struct telemetry_evtconfig pss_evtconfig,struct telemetry_evtconfig ioss_evtconfig)634 static int telemetry_plt_update_events(struct telemetry_evtconfig pss_evtconfig,
635 				struct telemetry_evtconfig ioss_evtconfig)
636 {
637 	int ret;
638 
639 	if ((pss_evtconfig.num_evts > 0) &&
640 	    (TELEM_SAMPLE_PERIOD_INVALID(pss_evtconfig.period))) {
641 		pr_err("PSS Sampling Period Out of Range\n");
642 		return -EINVAL;
643 	}
644 
645 	if ((ioss_evtconfig.num_evts > 0) &&
646 	    (TELEM_SAMPLE_PERIOD_INVALID(ioss_evtconfig.period))) {
647 		pr_err("IOSS Sampling Period Out of Range\n");
648 		return -EINVAL;
649 	}
650 
651 	ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
652 					TELEM_UPDATE);
653 	if (ret)
654 		pr_err("TELEMTRY Config Failed\n");
655 
656 	return ret;
657 }
658 
659 
telemetry_plt_set_sampling_period(u8 pss_period,u8 ioss_period)660 static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
661 {
662 	u32 telem_ctrl = 0;
663 	int ret = 0;
664 
665 	mutex_lock(&(telm_conf->telem_lock));
666 	if (ioss_period) {
667 		if (TELEM_SAMPLE_PERIOD_INVALID(ioss_period)) {
668 			pr_err("IOSS Sampling Period Out of Range\n");
669 			ret = -EINVAL;
670 			goto out;
671 		}
672 
673 		/* Get telemetry EVENT CTL */
674 		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
675 					    IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
676 					    &telem_ctrl, IOSS_TELEM_READ_WORD);
677 		if (ret) {
678 			pr_err("IOSS TELEM_CTRL Read Failed\n");
679 			goto out;
680 		}
681 
682 		/* Disable Telemetry */
683 		TELEM_DISABLE(telem_ctrl);
684 
685 		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
686 					    IOSS_TELEM_EVENT_CTL_WRITE,
687 					    (u8 *)&telem_ctrl,
688 					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
689 					    NULL, 0);
690 		if (ret) {
691 			pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
692 			goto out;
693 		}
694 
695 		/* Enable Periodic Telemetry Events and enable SRAM trace */
696 		TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
697 		TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
698 		TELEM_ENABLE_PERIODIC(telem_ctrl);
699 		telem_ctrl |= ioss_period;
700 
701 		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
702 					    IOSS_TELEM_EVENT_CTL_WRITE,
703 					    (u8 *)&telem_ctrl,
704 					    IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
705 					    NULL, 0);
706 		if (ret) {
707 			pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
708 			goto out;
709 		}
710 		telm_conf->ioss_config.curr_period = ioss_period;
711 	}
712 
713 	if (pss_period) {
714 		if (TELEM_SAMPLE_PERIOD_INVALID(pss_period)) {
715 			pr_err("PSS Sampling Period Out of Range\n");
716 			ret = -EINVAL;
717 			goto out;
718 		}
719 
720 		/* Get telemetry EVENT CTL */
721 		ret = intel_punit_ipc_command(
722 				IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
723 				0, 0, NULL, &telem_ctrl);
724 		if (ret) {
725 			pr_err("PSS TELEM_CTRL Read Failed\n");
726 			goto out;
727 		}
728 
729 		/* Disable Telemetry */
730 		TELEM_DISABLE(telem_ctrl);
731 		ret = intel_punit_ipc_command(
732 				IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
733 				0, 0, &telem_ctrl, NULL);
734 		if (ret) {
735 			pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
736 			goto out;
737 		}
738 
739 		/* Enable Periodic Telemetry Events and enable SRAM trace */
740 		TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
741 		TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
742 		TELEM_ENABLE_PERIODIC(telem_ctrl);
743 		telem_ctrl |= pss_period;
744 
745 		ret = intel_punit_ipc_command(
746 				IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
747 				0, 0, &telem_ctrl, NULL);
748 		if (ret) {
749 			pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
750 			goto out;
751 		}
752 		telm_conf->pss_config.curr_period = pss_period;
753 	}
754 
755 out:
756 	mutex_unlock(&(telm_conf->telem_lock));
757 	return ret;
758 }
759 
760 
telemetry_plt_get_sampling_period(u8 * pss_min_period,u8 * pss_max_period,u8 * ioss_min_period,u8 * ioss_max_period)761 static int telemetry_plt_get_sampling_period(u8 *pss_min_period,
762 					     u8 *pss_max_period,
763 					     u8 *ioss_min_period,
764 					     u8 *ioss_max_period)
765 {
766 	*pss_min_period = telm_conf->pss_config.min_period;
767 	*pss_max_period = telm_conf->pss_config.max_period;
768 	*ioss_min_period = telm_conf->ioss_config.min_period;
769 	*ioss_max_period = telm_conf->ioss_config.max_period;
770 
771 	return 0;
772 }
773 
774 
telemetry_plt_reset_events(void)775 static int telemetry_plt_reset_events(void)
776 {
777 	struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
778 	int ret;
779 
780 	pss_evtconfig.evtmap = NULL;
781 	pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
782 	pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
783 
784 	ioss_evtconfig.evtmap = NULL;
785 	ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
786 	ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
787 
788 	ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
789 					TELEM_RESET);
790 	if (ret)
791 		pr_err("TELEMTRY Reset Failed\n");
792 
793 	return ret;
794 }
795 
796 
telemetry_plt_get_eventconfig(struct telemetry_evtconfig * pss_config,struct telemetry_evtconfig * ioss_config,int pss_len,int ioss_len)797 static int telemetry_plt_get_eventconfig(struct telemetry_evtconfig *pss_config,
798 					struct telemetry_evtconfig *ioss_config,
799 					int pss_len, int ioss_len)
800 {
801 	u32 *pss_evtmap, *ioss_evtmap;
802 	u32 index;
803 
804 	pss_evtmap = pss_config->evtmap;
805 	ioss_evtmap = ioss_config->evtmap;
806 
807 	mutex_lock(&(telm_conf->telem_lock));
808 	pss_config->num_evts = telm_conf->pss_config.ssram_evts_used;
809 	ioss_config->num_evts = telm_conf->ioss_config.ssram_evts_used;
810 
811 	pss_config->period = telm_conf->pss_config.curr_period;
812 	ioss_config->period = telm_conf->ioss_config.curr_period;
813 
814 	if ((pss_len < telm_conf->pss_config.ssram_evts_used) ||
815 	    (ioss_len < telm_conf->ioss_config.ssram_evts_used)) {
816 		mutex_unlock(&(telm_conf->telem_lock));
817 		return -EINVAL;
818 	}
819 
820 	for (index = 0; index < telm_conf->pss_config.ssram_evts_used;
821 	     index++) {
822 		pss_evtmap[index] =
823 		telm_conf->pss_config.telem_evts[index].evt_id;
824 	}
825 
826 	for (index = 0; index < telm_conf->ioss_config.ssram_evts_used;
827 	     index++) {
828 		ioss_evtmap[index] =
829 		telm_conf->ioss_config.telem_evts[index].evt_id;
830 	}
831 
832 	mutex_unlock(&(telm_conf->telem_lock));
833 	return 0;
834 }
835 
836 
telemetry_plt_add_events(u8 num_pss_evts,u8 num_ioss_evts,u32 * pss_evtmap,u32 * ioss_evtmap)837 static int telemetry_plt_add_events(u8 num_pss_evts, u8 num_ioss_evts,
838 				    u32 *pss_evtmap, u32 *ioss_evtmap)
839 {
840 	struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
841 	int ret;
842 
843 	pss_evtconfig.evtmap = pss_evtmap;
844 	pss_evtconfig.num_evts = num_pss_evts;
845 	pss_evtconfig.period = telm_conf->pss_config.curr_period;
846 
847 	ioss_evtconfig.evtmap = ioss_evtmap;
848 	ioss_evtconfig.num_evts = num_ioss_evts;
849 	ioss_evtconfig.period = telm_conf->ioss_config.curr_period;
850 
851 	ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
852 					TELEM_ADD);
853 	if (ret)
854 		pr_err("TELEMTRY ADD Failed\n");
855 
856 	return ret;
857 }
858 
telem_evtlog_read(enum telemetry_unit telem_unit,struct telem_ssram_region * ssram_region,u8 len)859 static int telem_evtlog_read(enum telemetry_unit telem_unit,
860 			     struct telem_ssram_region *ssram_region, u8 len)
861 {
862 	struct telemetry_unit_config *unit_config;
863 	u64 timestamp_prev, timestamp_next;
864 	int ret, index, timeout = 0;
865 
866 	ret = telem_get_unitconfig(telem_unit, &unit_config);
867 	if (ret < 0)
868 		return ret;
869 
870 	if (len > unit_config->ssram_evts_used)
871 		len = unit_config->ssram_evts_used;
872 
873 	do {
874 		timestamp_prev = readq(unit_config->regmap);
875 		if (!timestamp_prev) {
876 			pr_err("Ssram under update. Please Try Later\n");
877 			return -EBUSY;
878 		}
879 
880 		ssram_region->start_time = readq(unit_config->regmap +
881 						 TELEM_SSRAM_STARTTIME_OFFSET);
882 
883 		for (index = 0; index < len; index++) {
884 			ssram_region->events[index] =
885 			readq(unit_config->regmap + TELEM_SSRAM_EVTLOG_OFFSET +
886 			      BYTES_PER_LONG*index);
887 		}
888 
889 		timestamp_next = readq(unit_config->regmap);
890 		if (!timestamp_next) {
891 			pr_err("Ssram under update. Please Try Later\n");
892 			return -EBUSY;
893 		}
894 
895 		if (timeout++ > TELEM_SSRAM_READ_TIMEOUT) {
896 			pr_err("Timeout while reading Events\n");
897 			return -EBUSY;
898 		}
899 
900 	} while (timestamp_prev != timestamp_next);
901 
902 	ssram_region->timestamp = timestamp_next;
903 
904 	return len;
905 }
906 
telemetry_plt_raw_read_eventlog(enum telemetry_unit telem_unit,struct telemetry_evtlog * evtlog,int len,int log_all_evts)907 static int telemetry_plt_raw_read_eventlog(enum telemetry_unit telem_unit,
908 					   struct telemetry_evtlog *evtlog,
909 					   int len, int log_all_evts)
910 {
911 	int index, idx1, ret, readlen = len;
912 	struct telem_ssram_region ssram_region;
913 	struct telemetry_evtmap *evtmap;
914 
915 	switch (telem_unit)	{
916 	case TELEM_PSS:
917 		evtmap = telm_conf->pss_config.telem_evts;
918 		break;
919 
920 	case TELEM_IOSS:
921 		evtmap = telm_conf->ioss_config.telem_evts;
922 		break;
923 
924 	default:
925 		pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
926 		return -EINVAL;
927 	}
928 
929 	if (!log_all_evts)
930 		readlen = TELEM_MAX_EVENTS_SRAM;
931 
932 	ret = telem_evtlog_read(telem_unit, &ssram_region, readlen);
933 	if (ret < 0)
934 		return ret;
935 
936 	/* Invalid evt-id array specified via length mismatch */
937 	if ((!log_all_evts) && (len > ret))
938 		return -EINVAL;
939 
940 	if (log_all_evts)
941 		for (index = 0; index < ret; index++) {
942 			evtlog[index].telem_evtlog = ssram_region.events[index];
943 			evtlog[index].telem_evtid = evtmap[index].evt_id;
944 		}
945 	else
946 		for (index = 0, readlen = 0; (index < ret) && (readlen < len);
947 		     index++) {
948 			for (idx1 = 0; idx1 < len; idx1++) {
949 				/* Elements matched */
950 				if (evtmap[index].evt_id ==
951 				    evtlog[idx1].telem_evtid) {
952 					evtlog[idx1].telem_evtlog =
953 					ssram_region.events[index];
954 					readlen++;
955 
956 					break;
957 				}
958 			}
959 		}
960 
961 	return readlen;
962 }
963 
telemetry_plt_read_eventlog(enum telemetry_unit telem_unit,struct telemetry_evtlog * evtlog,int len,int log_all_evts)964 static int telemetry_plt_read_eventlog(enum telemetry_unit telem_unit,
965 		struct telemetry_evtlog *evtlog, int len, int log_all_evts)
966 {
967 	int ret;
968 
969 	mutex_lock(&(telm_conf->telem_lock));
970 	ret = telemetry_plt_raw_read_eventlog(telem_unit, evtlog,
971 					      len, log_all_evts);
972 	mutex_unlock(&(telm_conf->telem_lock));
973 
974 	return ret;
975 }
976 
telemetry_plt_get_trace_verbosity(enum telemetry_unit telem_unit,u32 * verbosity)977 static int telemetry_plt_get_trace_verbosity(enum telemetry_unit telem_unit,
978 					     u32 *verbosity)
979 {
980 	u32 temp = 0;
981 	int ret;
982 
983 	if (verbosity == NULL)
984 		return -EINVAL;
985 
986 	mutex_lock(&(telm_conf->telem_trace_lock));
987 	switch (telem_unit) {
988 	case TELEM_PSS:
989 		ret = intel_punit_ipc_command(
990 				IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
991 				0, 0, NULL, &temp);
992 		if (ret) {
993 			pr_err("PSS TRACE_CTRL Read Failed\n");
994 			goto out;
995 		}
996 
997 		break;
998 
999 	case TELEM_IOSS:
1000 		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
1001 				IOSS_TELEM_TRACE_CTL_READ, NULL, 0, &temp,
1002 				IOSS_TELEM_READ_WORD);
1003 		if (ret) {
1004 			pr_err("IOSS TRACE_CTL Read Failed\n");
1005 			goto out;
1006 		}
1007 
1008 		break;
1009 
1010 	default:
1011 		pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
1012 		ret = -EINVAL;
1013 		break;
1014 	}
1015 	TELEM_EXTRACT_VERBOSITY(temp, *verbosity);
1016 
1017 out:
1018 	mutex_unlock(&(telm_conf->telem_trace_lock));
1019 	return ret;
1020 }
1021 
telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit,u32 verbosity)1022 static int telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit,
1023 					     u32 verbosity)
1024 {
1025 	u32 temp = 0;
1026 	int ret;
1027 
1028 	verbosity &= TELEM_TRC_VERBOSITY_MASK;
1029 
1030 	mutex_lock(&(telm_conf->telem_trace_lock));
1031 	switch (telem_unit) {
1032 	case TELEM_PSS:
1033 		ret = intel_punit_ipc_command(
1034 				IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
1035 				0, 0, NULL, &temp);
1036 		if (ret) {
1037 			pr_err("PSS TRACE_CTRL Read Failed\n");
1038 			goto out;
1039 		}
1040 
1041 		TELEM_CLEAR_VERBOSITY_BITS(temp);
1042 		TELEM_SET_VERBOSITY_BITS(temp, verbosity);
1043 
1044 		ret = intel_punit_ipc_command(
1045 				IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL,
1046 				0, 0, &temp, NULL);
1047 		if (ret) {
1048 			pr_err("PSS TRACE_CTRL Verbosity Set Failed\n");
1049 			goto out;
1050 		}
1051 		break;
1052 
1053 	case TELEM_IOSS:
1054 		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
1055 				IOSS_TELEM_TRACE_CTL_READ, NULL, 0, &temp,
1056 				IOSS_TELEM_READ_WORD);
1057 		if (ret) {
1058 			pr_err("IOSS TRACE_CTL Read Failed\n");
1059 			goto out;
1060 		}
1061 
1062 		TELEM_CLEAR_VERBOSITY_BITS(temp);
1063 		TELEM_SET_VERBOSITY_BITS(temp, verbosity);
1064 
1065 		ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
1066 				IOSS_TELEM_TRACE_CTL_WRITE, (u8 *)&temp,
1067 				IOSS_TELEM_WRITE_FOURBYTES, NULL, 0);
1068 		if (ret) {
1069 			pr_err("IOSS TRACE_CTL Verbosity Set Failed\n");
1070 			goto out;
1071 		}
1072 		break;
1073 
1074 	default:
1075 		pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
1076 		ret = -EINVAL;
1077 		break;
1078 	}
1079 
1080 out:
1081 	mutex_unlock(&(telm_conf->telem_trace_lock));
1082 	return ret;
1083 }
1084 
1085 static const struct telemetry_core_ops telm_pltops = {
1086 	.get_trace_verbosity = telemetry_plt_get_trace_verbosity,
1087 	.set_trace_verbosity = telemetry_plt_set_trace_verbosity,
1088 	.set_sampling_period = telemetry_plt_set_sampling_period,
1089 	.get_sampling_period = telemetry_plt_get_sampling_period,
1090 	.raw_read_eventlog = telemetry_plt_raw_read_eventlog,
1091 	.get_eventconfig = telemetry_plt_get_eventconfig,
1092 	.update_events = telemetry_plt_update_events,
1093 	.read_eventlog = telemetry_plt_read_eventlog,
1094 	.reset_events = telemetry_plt_reset_events,
1095 	.add_events = telemetry_plt_add_events,
1096 };
1097 
telemetry_pltdrv_probe(struct platform_device * pdev)1098 static int telemetry_pltdrv_probe(struct platform_device *pdev)
1099 {
1100 	struct resource *res0 = NULL, *res1 = NULL;
1101 	const struct x86_cpu_id *id;
1102 	int size, ret = -ENOMEM;
1103 
1104 	id = x86_match_cpu(telemetry_cpu_ids);
1105 	if (!id)
1106 		return -ENODEV;
1107 
1108 	telm_conf = (struct telemetry_plt_config *)id->driver_data;
1109 
1110 	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1111 	if (!res0) {
1112 		ret = -EINVAL;
1113 		goto out;
1114 	}
1115 	size = resource_size(res0);
1116 	if (!devm_request_mem_region(&pdev->dev, res0->start, size,
1117 				     pdev->name)) {
1118 		ret = -EBUSY;
1119 		goto out;
1120 	}
1121 	telm_conf->pss_config.ssram_base_addr = res0->start;
1122 	telm_conf->pss_config.ssram_size = size;
1123 
1124 	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1125 	if (!res1) {
1126 		ret = -EINVAL;
1127 		goto out;
1128 	}
1129 	size = resource_size(res1);
1130 	if (!devm_request_mem_region(&pdev->dev, res1->start, size,
1131 				     pdev->name)) {
1132 		ret = -EBUSY;
1133 		goto out;
1134 	}
1135 
1136 	telm_conf->ioss_config.ssram_base_addr = res1->start;
1137 	telm_conf->ioss_config.ssram_size = size;
1138 
1139 	telm_conf->pss_config.regmap = ioremap_nocache(
1140 					telm_conf->pss_config.ssram_base_addr,
1141 					telm_conf->pss_config.ssram_size);
1142 	if (!telm_conf->pss_config.regmap) {
1143 		ret = -ENOMEM;
1144 		goto out;
1145 	}
1146 
1147 	telm_conf->ioss_config.regmap = ioremap_nocache(
1148 				telm_conf->ioss_config.ssram_base_addr,
1149 				telm_conf->ioss_config.ssram_size);
1150 	if (!telm_conf->ioss_config.regmap) {
1151 		ret = -ENOMEM;
1152 		goto out;
1153 	}
1154 
1155 	mutex_init(&telm_conf->telem_lock);
1156 	mutex_init(&telm_conf->telem_trace_lock);
1157 
1158 	ret = telemetry_setup(pdev);
1159 	if (ret)
1160 		goto out;
1161 
1162 	ret = telemetry_set_pltdata(&telm_pltops, telm_conf);
1163 	if (ret) {
1164 		dev_err(&pdev->dev, "TELEMTRY Set Pltops Failed.\n");
1165 		goto out;
1166 	}
1167 
1168 	return 0;
1169 
1170 out:
1171 	if (res0)
1172 		release_mem_region(res0->start, resource_size(res0));
1173 	if (res1)
1174 		release_mem_region(res1->start, resource_size(res1));
1175 	if (telm_conf->pss_config.regmap)
1176 		iounmap(telm_conf->pss_config.regmap);
1177 	if (telm_conf->ioss_config.regmap)
1178 		iounmap(telm_conf->ioss_config.regmap);
1179 	dev_err(&pdev->dev, "TELEMTRY Setup Failed.\n");
1180 
1181 	return ret;
1182 }
1183 
telemetry_pltdrv_remove(struct platform_device * pdev)1184 static int telemetry_pltdrv_remove(struct platform_device *pdev)
1185 {
1186 	telemetry_clear_pltdata();
1187 	iounmap(telm_conf->pss_config.regmap);
1188 	iounmap(telm_conf->ioss_config.regmap);
1189 
1190 	return 0;
1191 }
1192 
1193 static struct platform_driver telemetry_soc_driver = {
1194 	.probe		= telemetry_pltdrv_probe,
1195 	.remove		= telemetry_pltdrv_remove,
1196 	.driver		= {
1197 		.name	= DRIVER_NAME,
1198 	},
1199 };
1200 
telemetry_module_init(void)1201 static int __init telemetry_module_init(void)
1202 {
1203 	pr_info(DRIVER_NAME ": version %s loaded\n", DRIVER_VERSION);
1204 	return platform_driver_register(&telemetry_soc_driver);
1205 }
1206 
telemetry_module_exit(void)1207 static void __exit telemetry_module_exit(void)
1208 {
1209 	platform_driver_unregister(&telemetry_soc_driver);
1210 }
1211 
1212 device_initcall(telemetry_module_init);
1213 module_exit(telemetry_module_exit);
1214 
1215 MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
1216 MODULE_DESCRIPTION("Intel SoC Telemetry Platform Driver");
1217 MODULE_VERSION(DRIVER_VERSION);
1218 MODULE_LICENSE("GPL");
1219