1 /*
2  * APM X-Gene SoC Hardware Monitoring Driver
3  *
4  * Copyright (c) 2016, Applied Micro Circuits Corporation
5  * Author: Loc Ho <lho@apm.com>
6  *         Hoan Tran <hotran@apm.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, see <http://www.gnu.org/licenses/>.
20  *
21  * This driver provides the following features:
22  *  - Retrieve CPU total power (uW)
23  *  - Retrieve IO total power (uW)
24  *  - Retrieve SoC temperature (milli-degree C) and alarm
25  */
26 #include <linux/acpi.h>
27 #include <linux/dma-mapping.h>
28 #include <linux/hwmon.h>
29 #include <linux/hwmon-sysfs.h>
30 #include <linux/io.h>
31 #include <linux/interrupt.h>
32 #include <linux/kfifo.h>
33 #include <linux/mailbox_controller.h>
34 #include <linux/mailbox_client.h>
35 #include <linux/module.h>
36 #include <linux/of.h>
37 #include <linux/platform_device.h>
38 
39 #include <acpi/pcc.h>
40 
41 /* SLIMpro message defines */
42 #define MSG_TYPE_DBG			0
43 #define MSG_TYPE_ERR			7
44 #define MSG_TYPE_PWRMGMT		9
45 
46 #define MSG_TYPE(v)			(((v) & 0xF0000000) >> 28)
47 #define MSG_TYPE_SET(v)			(((v) << 28) & 0xF0000000)
48 #define MSG_SUBTYPE(v)			(((v) & 0x0F000000) >> 24)
49 #define MSG_SUBTYPE_SET(v)		(((v) << 24) & 0x0F000000)
50 
51 #define DBG_SUBTYPE_SENSOR_READ		4
52 #define SENSOR_RD_MSG			0x04FFE902
53 #define SENSOR_RD_EN_ADDR(a)		((a) & 0x000FFFFF)
54 #define PMD_PWR_REG			0x20
55 #define PMD_PWR_MW_REG			0x26
56 #define SOC_PWR_REG			0x21
57 #define SOC_PWR_MW_REG			0x27
58 #define SOC_TEMP_REG			0x10
59 
60 #define TEMP_NEGATIVE_BIT		8
61 #define SENSOR_INVALID_DATA		BIT(15)
62 
63 #define PWRMGMT_SUBTYPE_TPC		1
64 #define TPC_ALARM			2
65 #define TPC_GET_ALARM			3
66 #define TPC_CMD(v)			(((v) & 0x00FF0000) >> 16)
67 #define TPC_CMD_SET(v)			(((v) << 16) & 0x00FF0000)
68 #define TPC_EN_MSG(hndl, cmd, type) \
69 	(MSG_TYPE_SET(MSG_TYPE_PWRMGMT) | \
70 	MSG_SUBTYPE_SET(hndl) | TPC_CMD_SET(cmd) | type)
71 
72 /* PCC defines */
73 #define PCC_SIGNATURE_MASK		0x50424300
74 #define PCCC_GENERATE_DB_INT		BIT(15)
75 #define PCCS_CMD_COMPLETE		BIT(0)
76 #define PCCS_SCI_DOORBEL		BIT(1)
77 #define PCCS_PLATFORM_NOTIFICATION	BIT(3)
78 /*
79  * Arbitrary retries in case the remote processor is slow to respond
80  * to PCC commands
81  */
82 #define PCC_NUM_RETRIES			500
83 
84 #define ASYNC_MSG_FIFO_SIZE		16
85 #define MBOX_OP_TIMEOUTMS		1000
86 
87 #define WATT_TO_mWATT(x)		((x) * 1000)
88 #define mWATT_TO_uWATT(x)		((x) * 1000)
89 #define CELSIUS_TO_mCELSIUS(x)		((x) * 1000)
90 
91 #define to_xgene_hwmon_dev(cl)		\
92 	container_of(cl, struct xgene_hwmon_dev, mbox_client)
93 
94 enum xgene_hwmon_version {
95 	XGENE_HWMON_V1 = 0,
96 	XGENE_HWMON_V2 = 1,
97 };
98 
99 struct slimpro_resp_msg {
100 	u32 msg;
101 	u32 param1;
102 	u32 param2;
103 } __packed;
104 
105 struct xgene_hwmon_dev {
106 	struct device		*dev;
107 	struct mbox_chan	*mbox_chan;
108 	struct mbox_client	mbox_client;
109 	int			mbox_idx;
110 
111 	spinlock_t		kfifo_lock;
112 	struct mutex		rd_mutex;
113 	struct completion	rd_complete;
114 	int			resp_pending;
115 	struct slimpro_resp_msg sync_msg;
116 
117 	struct work_struct	workq;
118 	struct kfifo_rec_ptr_1	async_msg_fifo;
119 
120 	struct device		*hwmon_dev;
121 	bool			temp_critical_alarm;
122 
123 	phys_addr_t		comm_base_addr;
124 	void			*pcc_comm_addr;
125 	u64			usecs_lat;
126 };
127 
128 /*
129  * This function tests and clears a bitmask then returns its old value
130  */
xgene_word_tst_and_clr(u16 * addr,u16 mask)131 static u16 xgene_word_tst_and_clr(u16 *addr, u16 mask)
132 {
133 	u16 ret, val;
134 
135 	val = le16_to_cpu(READ_ONCE(*addr));
136 	ret = val & mask;
137 	val &= ~mask;
138 	WRITE_ONCE(*addr, cpu_to_le16(val));
139 
140 	return ret;
141 }
142 
xgene_hwmon_pcc_rd(struct xgene_hwmon_dev * ctx,u32 * msg)143 static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
144 {
145 	struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr;
146 	u32 *ptr = (void *)(generic_comm_base + 1);
147 	int rc, i;
148 	u16 val;
149 
150 	mutex_lock(&ctx->rd_mutex);
151 	init_completion(&ctx->rd_complete);
152 	ctx->resp_pending = true;
153 
154 	/* Write signature for subspace */
155 	WRITE_ONCE(generic_comm_base->signature,
156 		   cpu_to_le32(PCC_SIGNATURE_MASK | ctx->mbox_idx));
157 
158 	/* Write to the shared command region */
159 	WRITE_ONCE(generic_comm_base->command,
160 		   cpu_to_le16(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT));
161 
162 	/* Flip CMD COMPLETE bit */
163 	val = le16_to_cpu(READ_ONCE(generic_comm_base->status));
164 	val &= ~PCCS_CMD_COMPLETE;
165 	WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val));
166 
167 	/* Copy the message to the PCC comm space */
168 	for (i = 0; i < sizeof(struct slimpro_resp_msg) / 4; i++)
169 		WRITE_ONCE(ptr[i], cpu_to_le32(msg[i]));
170 
171 	/* Ring the doorbell */
172 	rc = mbox_send_message(ctx->mbox_chan, msg);
173 	if (rc < 0) {
174 		dev_err(ctx->dev, "Mailbox send error %d\n", rc);
175 		goto err;
176 	}
177 	if (!wait_for_completion_timeout(&ctx->rd_complete,
178 					 usecs_to_jiffies(ctx->usecs_lat))) {
179 		dev_err(ctx->dev, "Mailbox operation timed out\n");
180 		rc = -ETIMEDOUT;
181 		goto err;
182 	}
183 
184 	/* Check for error message */
185 	if (MSG_TYPE(ctx->sync_msg.msg) == MSG_TYPE_ERR) {
186 		rc = -EINVAL;
187 		goto err;
188 	}
189 
190 	msg[0] = ctx->sync_msg.msg;
191 	msg[1] = ctx->sync_msg.param1;
192 	msg[2] = ctx->sync_msg.param2;
193 
194 err:
195 	mbox_chan_txdone(ctx->mbox_chan, 0);
196 	ctx->resp_pending = false;
197 	mutex_unlock(&ctx->rd_mutex);
198 	return rc;
199 }
200 
xgene_hwmon_rd(struct xgene_hwmon_dev * ctx,u32 * msg)201 static int xgene_hwmon_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
202 {
203 	int rc;
204 
205 	mutex_lock(&ctx->rd_mutex);
206 	init_completion(&ctx->rd_complete);
207 	ctx->resp_pending = true;
208 
209 	rc = mbox_send_message(ctx->mbox_chan, msg);
210 	if (rc < 0) {
211 		dev_err(ctx->dev, "Mailbox send error %d\n", rc);
212 		goto err;
213 	}
214 
215 	if (!wait_for_completion_timeout(&ctx->rd_complete,
216 					 msecs_to_jiffies(MBOX_OP_TIMEOUTMS))) {
217 		dev_err(ctx->dev, "Mailbox operation timed out\n");
218 		rc = -ETIMEDOUT;
219 		goto err;
220 	}
221 
222 	/* Check for error message */
223 	if (MSG_TYPE(ctx->sync_msg.msg) == MSG_TYPE_ERR) {
224 		rc = -EINVAL;
225 		goto err;
226 	}
227 
228 	msg[0] = ctx->sync_msg.msg;
229 	msg[1] = ctx->sync_msg.param1;
230 	msg[2] = ctx->sync_msg.param2;
231 
232 err:
233 	ctx->resp_pending = false;
234 	mutex_unlock(&ctx->rd_mutex);
235 	return rc;
236 }
237 
xgene_hwmon_reg_map_rd(struct xgene_hwmon_dev * ctx,u32 addr,u32 * data)238 static int xgene_hwmon_reg_map_rd(struct xgene_hwmon_dev *ctx, u32 addr,
239 				  u32 *data)
240 {
241 	u32 msg[3];
242 	int rc;
243 
244 	msg[0] = SENSOR_RD_MSG;
245 	msg[1] = SENSOR_RD_EN_ADDR(addr);
246 	msg[2] = 0;
247 
248 	if (acpi_disabled)
249 		rc = xgene_hwmon_rd(ctx, msg);
250 	else
251 		rc = xgene_hwmon_pcc_rd(ctx, msg);
252 
253 	if (rc < 0)
254 		return rc;
255 
256 	/*
257 	 * Check if sensor data is valid.
258 	 */
259 	if (msg[1] & SENSOR_INVALID_DATA)
260 		return -ENODATA;
261 
262 	*data = msg[1];
263 
264 	return rc;
265 }
266 
xgene_hwmon_get_notification_msg(struct xgene_hwmon_dev * ctx,u32 * amsg)267 static int xgene_hwmon_get_notification_msg(struct xgene_hwmon_dev *ctx,
268 					    u32 *amsg)
269 {
270 	u32 msg[3];
271 	int rc;
272 
273 	msg[0] = TPC_EN_MSG(PWRMGMT_SUBTYPE_TPC, TPC_GET_ALARM, 0);
274 	msg[1] = 0;
275 	msg[2] = 0;
276 
277 	rc = xgene_hwmon_pcc_rd(ctx, msg);
278 	if (rc < 0)
279 		return rc;
280 
281 	amsg[0] = msg[0];
282 	amsg[1] = msg[1];
283 	amsg[2] = msg[2];
284 
285 	return rc;
286 }
287 
xgene_hwmon_get_cpu_pwr(struct xgene_hwmon_dev * ctx,u32 * val)288 static int xgene_hwmon_get_cpu_pwr(struct xgene_hwmon_dev *ctx, u32 *val)
289 {
290 	u32 watt, mwatt;
291 	int rc;
292 
293 	rc = xgene_hwmon_reg_map_rd(ctx, PMD_PWR_REG, &watt);
294 	if (rc < 0)
295 		return rc;
296 
297 	rc = xgene_hwmon_reg_map_rd(ctx, PMD_PWR_MW_REG, &mwatt);
298 	if (rc < 0)
299 		return rc;
300 
301 	*val = WATT_TO_mWATT(watt) + mwatt;
302 	return 0;
303 }
304 
xgene_hwmon_get_io_pwr(struct xgene_hwmon_dev * ctx,u32 * val)305 static int xgene_hwmon_get_io_pwr(struct xgene_hwmon_dev *ctx, u32 *val)
306 {
307 	u32 watt, mwatt;
308 	int rc;
309 
310 	rc = xgene_hwmon_reg_map_rd(ctx, SOC_PWR_REG, &watt);
311 	if (rc < 0)
312 		return rc;
313 
314 	rc = xgene_hwmon_reg_map_rd(ctx, SOC_PWR_MW_REG, &mwatt);
315 	if (rc < 0)
316 		return rc;
317 
318 	*val = WATT_TO_mWATT(watt) + mwatt;
319 	return 0;
320 }
321 
xgene_hwmon_get_temp(struct xgene_hwmon_dev * ctx,u32 * val)322 static int xgene_hwmon_get_temp(struct xgene_hwmon_dev *ctx, u32 *val)
323 {
324 	return xgene_hwmon_reg_map_rd(ctx, SOC_TEMP_REG, val);
325 }
326 
327 /*
328  * Sensor temperature/power functions
329  */
temp1_input_show(struct device * dev,struct device_attribute * attr,char * buf)330 static ssize_t temp1_input_show(struct device *dev,
331 				struct device_attribute *attr,
332 				char *buf)
333 {
334 	struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev);
335 	int rc, temp;
336 	u32 val;
337 
338 	rc = xgene_hwmon_get_temp(ctx, &val);
339 	if (rc < 0)
340 		return rc;
341 
342 	temp = sign_extend32(val, TEMP_NEGATIVE_BIT);
343 
344 	return snprintf(buf, PAGE_SIZE, "%d\n", CELSIUS_TO_mCELSIUS(temp));
345 }
346 
temp1_label_show(struct device * dev,struct device_attribute * attr,char * buf)347 static ssize_t temp1_label_show(struct device *dev,
348 				struct device_attribute *attr,
349 				char *buf)
350 {
351 	return snprintf(buf, PAGE_SIZE, "SoC Temperature\n");
352 }
353 
temp1_critical_alarm_show(struct device * dev,struct device_attribute * devattr,char * buf)354 static ssize_t temp1_critical_alarm_show(struct device *dev,
355 					 struct device_attribute *devattr,
356 					 char *buf)
357 {
358 	struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev);
359 
360 	return snprintf(buf, PAGE_SIZE, "%d\n", ctx->temp_critical_alarm);
361 }
362 
power1_label_show(struct device * dev,struct device_attribute * attr,char * buf)363 static ssize_t power1_label_show(struct device *dev,
364 				 struct device_attribute *attr,
365 				 char *buf)
366 {
367 	return snprintf(buf, PAGE_SIZE, "CPU power\n");
368 }
369 
power2_label_show(struct device * dev,struct device_attribute * attr,char * buf)370 static ssize_t power2_label_show(struct device *dev,
371 				 struct device_attribute *attr,
372 				 char *buf)
373 {
374 	return snprintf(buf, PAGE_SIZE, "IO power\n");
375 }
376 
power1_input_show(struct device * dev,struct device_attribute * attr,char * buf)377 static ssize_t power1_input_show(struct device *dev,
378 				 struct device_attribute *attr,
379 				 char *buf)
380 {
381 	struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev);
382 	u32 val;
383 	int rc;
384 
385 	rc = xgene_hwmon_get_cpu_pwr(ctx, &val);
386 	if (rc < 0)
387 		return rc;
388 
389 	return snprintf(buf, PAGE_SIZE, "%u\n", mWATT_TO_uWATT(val));
390 }
391 
power2_input_show(struct device * dev,struct device_attribute * attr,char * buf)392 static ssize_t power2_input_show(struct device *dev,
393 				 struct device_attribute *attr,
394 				 char *buf)
395 {
396 	struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev);
397 	u32 val;
398 	int rc;
399 
400 	rc = xgene_hwmon_get_io_pwr(ctx, &val);
401 	if (rc < 0)
402 		return rc;
403 
404 	return snprintf(buf, PAGE_SIZE, "%u\n", mWATT_TO_uWATT(val));
405 }
406 
407 static DEVICE_ATTR_RO(temp1_label);
408 static DEVICE_ATTR_RO(temp1_input);
409 static DEVICE_ATTR_RO(temp1_critical_alarm);
410 static DEVICE_ATTR_RO(power1_label);
411 static DEVICE_ATTR_RO(power1_input);
412 static DEVICE_ATTR_RO(power2_label);
413 static DEVICE_ATTR_RO(power2_input);
414 
415 static struct attribute *xgene_hwmon_attrs[] = {
416 	&dev_attr_temp1_label.attr,
417 	&dev_attr_temp1_input.attr,
418 	&dev_attr_temp1_critical_alarm.attr,
419 	&dev_attr_power1_label.attr,
420 	&dev_attr_power1_input.attr,
421 	&dev_attr_power2_label.attr,
422 	&dev_attr_power2_input.attr,
423 	NULL,
424 };
425 
426 ATTRIBUTE_GROUPS(xgene_hwmon);
427 
xgene_hwmon_tpc_alarm(struct xgene_hwmon_dev * ctx,struct slimpro_resp_msg * amsg)428 static int xgene_hwmon_tpc_alarm(struct xgene_hwmon_dev *ctx,
429 				 struct slimpro_resp_msg *amsg)
430 {
431 	ctx->temp_critical_alarm = !!amsg->param2;
432 	sysfs_notify(&ctx->dev->kobj, NULL, "temp1_critical_alarm");
433 
434 	return 0;
435 }
436 
xgene_hwmon_process_pwrmsg(struct xgene_hwmon_dev * ctx,struct slimpro_resp_msg * amsg)437 static void xgene_hwmon_process_pwrmsg(struct xgene_hwmon_dev *ctx,
438 				       struct slimpro_resp_msg *amsg)
439 {
440 	if ((MSG_SUBTYPE(amsg->msg) == PWRMGMT_SUBTYPE_TPC) &&
441 	    (TPC_CMD(amsg->msg) == TPC_ALARM))
442 		xgene_hwmon_tpc_alarm(ctx, amsg);
443 }
444 
445 /*
446  * This function is called to process async work queue
447  */
xgene_hwmon_evt_work(struct work_struct * work)448 static void xgene_hwmon_evt_work(struct work_struct *work)
449 {
450 	struct slimpro_resp_msg amsg;
451 	struct xgene_hwmon_dev *ctx;
452 	int ret;
453 
454 	ctx = container_of(work, struct xgene_hwmon_dev, workq);
455 	while (kfifo_out_spinlocked(&ctx->async_msg_fifo, &amsg,
456 				    sizeof(struct slimpro_resp_msg),
457 				    &ctx->kfifo_lock)) {
458 		/*
459 		 * If PCC, send a consumer command to Platform to get info
460 		 * If Slimpro Mailbox, get message from specific FIFO
461 		 */
462 		if (!acpi_disabled) {
463 			ret = xgene_hwmon_get_notification_msg(ctx,
464 							       (u32 *)&amsg);
465 			if (ret < 0)
466 				continue;
467 		}
468 
469 		if (MSG_TYPE(amsg.msg) == MSG_TYPE_PWRMGMT)
470 			xgene_hwmon_process_pwrmsg(ctx, &amsg);
471 	}
472 }
473 
xgene_hwmon_rx_ready(struct xgene_hwmon_dev * ctx,void * msg)474 static int xgene_hwmon_rx_ready(struct xgene_hwmon_dev *ctx, void *msg)
475 {
476 	if (IS_ERR_OR_NULL(ctx->hwmon_dev) && !ctx->resp_pending) {
477 		/* Enqueue to the FIFO */
478 		kfifo_in_spinlocked(&ctx->async_msg_fifo, msg,
479 				    sizeof(struct slimpro_resp_msg),
480 				    &ctx->kfifo_lock);
481 		return -ENODEV;
482 	}
483 
484 	return 0;
485 }
486 
487 /*
488  * This function is called when the SLIMpro Mailbox received a message
489  */
xgene_hwmon_rx_cb(struct mbox_client * cl,void * msg)490 static void xgene_hwmon_rx_cb(struct mbox_client *cl, void *msg)
491 {
492 	struct xgene_hwmon_dev *ctx = to_xgene_hwmon_dev(cl);
493 
494 	/*
495 	 * While the driver registers with the mailbox framework, an interrupt
496 	 * can be pending before the probe function completes its
497 	 * initialization. If such condition occurs, just queue up the message
498 	 * as the driver is not ready for servicing the callback.
499 	 */
500 	if (xgene_hwmon_rx_ready(ctx, msg) < 0)
501 		return;
502 
503 	/*
504 	 * Response message format:
505 	 * msg[0] is the return code of the operation
506 	 * msg[1] is the first parameter word
507 	 * msg[2] is the second parameter word
508 	 *
509 	 * As message only supports dword size, just assign it.
510 	 */
511 
512 	/* Check for sync query */
513 	if (ctx->resp_pending &&
514 	    ((MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_ERR) ||
515 	     (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_DBG &&
516 	      MSG_SUBTYPE(((u32 *)msg)[0]) == DBG_SUBTYPE_SENSOR_READ) ||
517 	     (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_PWRMGMT &&
518 	      MSG_SUBTYPE(((u32 *)msg)[0]) == PWRMGMT_SUBTYPE_TPC &&
519 	      TPC_CMD(((u32 *)msg)[0]) == TPC_ALARM))) {
520 		ctx->sync_msg.msg = ((u32 *)msg)[0];
521 		ctx->sync_msg.param1 = ((u32 *)msg)[1];
522 		ctx->sync_msg.param2 = ((u32 *)msg)[2];
523 
524 		/* Operation waiting for response */
525 		complete(&ctx->rd_complete);
526 
527 		return;
528 	}
529 
530 	/* Enqueue to the FIFO */
531 	kfifo_in_spinlocked(&ctx->async_msg_fifo, msg,
532 			    sizeof(struct slimpro_resp_msg), &ctx->kfifo_lock);
533 	/* Schedule the bottom handler */
534 	schedule_work(&ctx->workq);
535 }
536 
537 /*
538  * This function is called when the PCC Mailbox received a message
539  */
xgene_hwmon_pcc_rx_cb(struct mbox_client * cl,void * msg)540 static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg)
541 {
542 	struct xgene_hwmon_dev *ctx = to_xgene_hwmon_dev(cl);
543 	struct acpi_pcct_shared_memory *generic_comm_base = ctx->pcc_comm_addr;
544 	struct slimpro_resp_msg amsg;
545 
546 	/*
547 	 * While the driver registers with the mailbox framework, an interrupt
548 	 * can be pending before the probe function completes its
549 	 * initialization. If such condition occurs, just queue up the message
550 	 * as the driver is not ready for servicing the callback.
551 	 */
552 	if (xgene_hwmon_rx_ready(ctx, &amsg) < 0)
553 		return;
554 
555 	msg = generic_comm_base + 1;
556 	/* Check if platform sends interrupt */
557 	if (!xgene_word_tst_and_clr(&generic_comm_base->status,
558 				    PCCS_SCI_DOORBEL))
559 		return;
560 
561 	/*
562 	 * Response message format:
563 	 * msg[0] is the return code of the operation
564 	 * msg[1] is the first parameter word
565 	 * msg[2] is the second parameter word
566 	 *
567 	 * As message only supports dword size, just assign it.
568 	 */
569 
570 	/* Check for sync query */
571 	if (ctx->resp_pending &&
572 	    ((MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_ERR) ||
573 	     (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_DBG &&
574 	      MSG_SUBTYPE(((u32 *)msg)[0]) == DBG_SUBTYPE_SENSOR_READ) ||
575 	     (MSG_TYPE(((u32 *)msg)[0]) == MSG_TYPE_PWRMGMT &&
576 	      MSG_SUBTYPE(((u32 *)msg)[0]) == PWRMGMT_SUBTYPE_TPC &&
577 	      TPC_CMD(((u32 *)msg)[0]) == TPC_ALARM))) {
578 		/* Check if platform completes command */
579 		if (xgene_word_tst_and_clr(&generic_comm_base->status,
580 					   PCCS_CMD_COMPLETE)) {
581 			ctx->sync_msg.msg = ((u32 *)msg)[0];
582 			ctx->sync_msg.param1 = ((u32 *)msg)[1];
583 			ctx->sync_msg.param2 = ((u32 *)msg)[2];
584 
585 			/* Operation waiting for response */
586 			complete(&ctx->rd_complete);
587 
588 			return;
589 		}
590 	}
591 
592 	/*
593 	 * Platform notifies interrupt to OSPM.
594 	 * OPSM schedules a consumer command to get this information
595 	 * in a workqueue. Platform must wait until OSPM has issued
596 	 * a consumer command that serves this notification.
597 	 */
598 
599 	/* Enqueue to the FIFO */
600 	kfifo_in_spinlocked(&ctx->async_msg_fifo, &amsg,
601 			    sizeof(struct slimpro_resp_msg), &ctx->kfifo_lock);
602 	/* Schedule the bottom handler */
603 	schedule_work(&ctx->workq);
604 }
605 
xgene_hwmon_tx_done(struct mbox_client * cl,void * msg,int ret)606 static void xgene_hwmon_tx_done(struct mbox_client *cl, void *msg, int ret)
607 {
608 	if (ret) {
609 		dev_dbg(cl->dev, "TX did not complete: CMD sent:%x, ret:%d\n",
610 			*(u16 *)msg, ret);
611 	} else {
612 		dev_dbg(cl->dev, "TX completed. CMD sent:%x, ret:%d\n",
613 			*(u16 *)msg, ret);
614 	}
615 }
616 
617 #ifdef CONFIG_ACPI
618 static const struct acpi_device_id xgene_hwmon_acpi_match[] = {
619 	{"APMC0D29", XGENE_HWMON_V1},
620 	{"APMC0D8A", XGENE_HWMON_V2},
621 	{},
622 };
623 MODULE_DEVICE_TABLE(acpi, xgene_hwmon_acpi_match);
624 #endif
625 
xgene_hwmon_probe(struct platform_device * pdev)626 static int xgene_hwmon_probe(struct platform_device *pdev)
627 {
628 	struct xgene_hwmon_dev *ctx;
629 	struct mbox_client *cl;
630 	int rc;
631 
632 	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
633 	if (!ctx)
634 		return -ENOMEM;
635 
636 	ctx->dev = &pdev->dev;
637 	platform_set_drvdata(pdev, ctx);
638 	cl = &ctx->mbox_client;
639 
640 	spin_lock_init(&ctx->kfifo_lock);
641 	mutex_init(&ctx->rd_mutex);
642 
643 	rc = kfifo_alloc(&ctx->async_msg_fifo,
644 			 sizeof(struct slimpro_resp_msg) * ASYNC_MSG_FIFO_SIZE,
645 			 GFP_KERNEL);
646 	if (rc)
647 		return -ENOMEM;
648 
649 	INIT_WORK(&ctx->workq, xgene_hwmon_evt_work);
650 
651 	/* Request mailbox channel */
652 	cl->dev = &pdev->dev;
653 	cl->tx_done = xgene_hwmon_tx_done;
654 	cl->tx_block = false;
655 	cl->tx_tout = MBOX_OP_TIMEOUTMS;
656 	cl->knows_txdone = false;
657 	if (acpi_disabled) {
658 		cl->rx_callback = xgene_hwmon_rx_cb;
659 		ctx->mbox_chan = mbox_request_channel(cl, 0);
660 		if (IS_ERR(ctx->mbox_chan)) {
661 			dev_err(&pdev->dev,
662 				"SLIMpro mailbox channel request failed\n");
663 			rc = -ENODEV;
664 			goto out_mbox_free;
665 		}
666 	} else {
667 		struct acpi_pcct_hw_reduced *cppc_ss;
668 		const struct acpi_device_id *acpi_id;
669 		int version;
670 
671 		acpi_id = acpi_match_device(pdev->dev.driver->acpi_match_table,
672 					    &pdev->dev);
673 		if (!acpi_id)
674 			return -EINVAL;
675 
676 		version = (int)acpi_id->driver_data;
677 
678 		if (device_property_read_u32(&pdev->dev, "pcc-channel",
679 					     &ctx->mbox_idx)) {
680 			dev_err(&pdev->dev, "no pcc-channel property\n");
681 			rc = -ENODEV;
682 			goto out_mbox_free;
683 		}
684 
685 		cl->rx_callback = xgene_hwmon_pcc_rx_cb;
686 		ctx->mbox_chan = pcc_mbox_request_channel(cl, ctx->mbox_idx);
687 		if (IS_ERR(ctx->mbox_chan)) {
688 			dev_err(&pdev->dev,
689 				"PPC channel request failed\n");
690 			rc = -ENODEV;
691 			goto out_mbox_free;
692 		}
693 
694 		/*
695 		 * The PCC mailbox controller driver should
696 		 * have parsed the PCCT (global table of all
697 		 * PCC channels) and stored pointers to the
698 		 * subspace communication region in con_priv.
699 		 */
700 		cppc_ss = ctx->mbox_chan->con_priv;
701 		if (!cppc_ss) {
702 			dev_err(&pdev->dev, "PPC subspace not found\n");
703 			rc = -ENODEV;
704 			goto out;
705 		}
706 
707 		if (!ctx->mbox_chan->mbox->txdone_irq) {
708 			dev_err(&pdev->dev, "PCC IRQ not supported\n");
709 			rc = -ENODEV;
710 			goto out;
711 		}
712 
713 		/*
714 		 * This is the shared communication region
715 		 * for the OS and Platform to communicate over.
716 		 */
717 		ctx->comm_base_addr = cppc_ss->base_address;
718 		if (ctx->comm_base_addr) {
719 			if (version == XGENE_HWMON_V2)
720 				ctx->pcc_comm_addr = (void __force *)ioremap(
721 							ctx->comm_base_addr,
722 							cppc_ss->length);
723 			else
724 				ctx->pcc_comm_addr = memremap(
725 							ctx->comm_base_addr,
726 							cppc_ss->length,
727 							MEMREMAP_WB);
728 		} else {
729 			dev_err(&pdev->dev, "Failed to get PCC comm region\n");
730 			rc = -ENODEV;
731 			goto out;
732 		}
733 
734 		if (!ctx->pcc_comm_addr) {
735 			dev_err(&pdev->dev,
736 				"Failed to ioremap PCC comm region\n");
737 			rc = -ENOMEM;
738 			goto out;
739 		}
740 
741 		/*
742 		 * cppc_ss->latency is just a Nominal value. In reality
743 		 * the remote processor could be much slower to reply.
744 		 * So add an arbitrary amount of wait on top of Nominal.
745 		 */
746 		ctx->usecs_lat = PCC_NUM_RETRIES * cppc_ss->latency;
747 	}
748 
749 	ctx->hwmon_dev = hwmon_device_register_with_groups(ctx->dev,
750 							   "apm_xgene",
751 							   ctx,
752 							   xgene_hwmon_groups);
753 	if (IS_ERR(ctx->hwmon_dev)) {
754 		dev_err(&pdev->dev, "Failed to register HW monitor device\n");
755 		rc = PTR_ERR(ctx->hwmon_dev);
756 		goto out;
757 	}
758 
759 	/*
760 	 * Schedule the bottom handler if there is a pending message.
761 	 */
762 	schedule_work(&ctx->workq);
763 
764 	dev_info(&pdev->dev, "APM X-Gene SoC HW monitor driver registered\n");
765 
766 	return 0;
767 
768 out:
769 	if (acpi_disabled)
770 		mbox_free_channel(ctx->mbox_chan);
771 	else
772 		pcc_mbox_free_channel(ctx->mbox_chan);
773 out_mbox_free:
774 	kfifo_free(&ctx->async_msg_fifo);
775 
776 	return rc;
777 }
778 
xgene_hwmon_remove(struct platform_device * pdev)779 static int xgene_hwmon_remove(struct platform_device *pdev)
780 {
781 	struct xgene_hwmon_dev *ctx = platform_get_drvdata(pdev);
782 
783 	hwmon_device_unregister(ctx->hwmon_dev);
784 	kfifo_free(&ctx->async_msg_fifo);
785 	if (acpi_disabled)
786 		mbox_free_channel(ctx->mbox_chan);
787 	else
788 		pcc_mbox_free_channel(ctx->mbox_chan);
789 
790 	return 0;
791 }
792 
793 static const struct of_device_id xgene_hwmon_of_match[] = {
794 	{.compatible = "apm,xgene-slimpro-hwmon"},
795 	{}
796 };
797 MODULE_DEVICE_TABLE(of, xgene_hwmon_of_match);
798 
799 static struct platform_driver xgene_hwmon_driver __refdata = {
800 	.probe = xgene_hwmon_probe,
801 	.remove = xgene_hwmon_remove,
802 	.driver = {
803 		.name = "xgene-slimpro-hwmon",
804 		.of_match_table = xgene_hwmon_of_match,
805 		.acpi_match_table = ACPI_PTR(xgene_hwmon_acpi_match),
806 	},
807 };
808 module_platform_driver(xgene_hwmon_driver);
809 
810 MODULE_DESCRIPTION("APM X-Gene SoC hardware monitor");
811 MODULE_LICENSE("GPL");
812