Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1/*
   2 * intel_pmc_ipc.c: Driver for the Intel PMC IPC mechanism
   3 *
   4 * (C) Copyright 2014-2015 Intel Corporation
   5 *
   6 * This driver is based on Intel SCU IPC driver(intel_scu_opc.c) by
   7 *     Sreedhara DS <sreedhara.ds@intel.com>
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License
  11 * as published by the Free Software Foundation; version 2
  12 * of the License.
  13 *
  14 * PMC running in ARC processor communicates with other entity running in IA
  15 * core through IPC mechanism which in turn messaging between IA core ad PMC.
  16 */
  17
  18#include <linux/module.h>
  19#include <linux/delay.h>
  20#include <linux/errno.h>
  21#include <linux/init.h>
  22#include <linux/device.h>
  23#include <linux/pm.h>
  24#include <linux/pci.h>
  25#include <linux/platform_device.h>
  26#include <linux/interrupt.h>
  27#include <linux/pm_qos.h>
  28#include <linux/kernel.h>
  29#include <linux/bitops.h>
  30#include <linux/sched.h>
  31#include <linux/atomic.h>
  32#include <linux/notifier.h>
  33#include <linux/suspend.h>
  34#include <linux/acpi.h>
  35#include <linux/io-64-nonatomic-lo-hi.h>
  36#include <linux/spinlock.h>
  37
  38#include <asm/intel_pmc_ipc.h>
  39
  40#include <linux/platform_data/itco_wdt.h>
  41
  42/*
  43 * IPC registers
  44 * The IA write to IPC_CMD command register triggers an interrupt to the ARC,
  45 * The ARC handles the interrupt and services it, writing optional data to
  46 * the IPC1 registers, updates the IPC_STS response register with the status.
  47 */
  48#define IPC_CMD			0x0
  49#define		IPC_CMD_MSI		0x100
  50#define		IPC_CMD_SIZE		16
  51#define		IPC_CMD_SUBCMD		12
  52#define IPC_STATUS		0x04
  53#define		IPC_STATUS_IRQ		0x4
  54#define		IPC_STATUS_ERR		0x2
  55#define		IPC_STATUS_BUSY		0x1
  56#define IPC_SPTR		0x08
  57#define IPC_DPTR		0x0C
  58#define IPC_WRITE_BUFFER	0x80
  59#define IPC_READ_BUFFER		0x90
  60
  61/* Residency with clock rate at 19.2MHz to usecs */
  62#define S0IX_RESIDENCY_IN_USECS(d, s)		\
  63({						\
  64	u64 result = 10ull * ((d) + (s));	\
  65	do_div(result, 192);			\
  66	result;					\
  67})
  68
  69/*
  70 * 16-byte buffer for sending data associated with IPC command.
  71 */
  72#define IPC_DATA_BUFFER_SIZE	16
  73
  74#define IPC_LOOP_CNT		3000000
  75#define IPC_MAX_SEC		3
  76
  77#define IPC_TRIGGER_MODE_IRQ		true
  78
  79/* exported resources from IFWI */
  80#define PLAT_RESOURCE_IPC_INDEX		0
  81#define PLAT_RESOURCE_IPC_SIZE		0x1000
  82#define PLAT_RESOURCE_GCR_OFFSET	0x1000
  83#define PLAT_RESOURCE_GCR_SIZE		0x1000
  84#define PLAT_RESOURCE_BIOS_DATA_INDEX	1
  85#define PLAT_RESOURCE_BIOS_IFACE_INDEX	2
  86#define PLAT_RESOURCE_TELEM_SSRAM_INDEX	3
  87#define PLAT_RESOURCE_ISP_DATA_INDEX	4
  88#define PLAT_RESOURCE_ISP_IFACE_INDEX	5
  89#define PLAT_RESOURCE_GTD_DATA_INDEX	6
  90#define PLAT_RESOURCE_GTD_IFACE_INDEX	7
  91#define PLAT_RESOURCE_ACPI_IO_INDEX	0
  92
  93/*
  94 * BIOS does not create an ACPI device for each PMC function,
  95 * but exports multiple resources from one ACPI device(IPC) for
  96 * multiple functions. This driver is responsible to create a
  97 * platform device and to export resources for those functions.
  98 */
  99#define TCO_DEVICE_NAME			"iTCO_wdt"
 100#define SMI_EN_OFFSET			0x40
 101#define SMI_EN_SIZE			4
 102#define TCO_BASE_OFFSET			0x60
 103#define TCO_REGS_SIZE			16
 104#define PUNIT_DEVICE_NAME		"intel_punit_ipc"
 105#define TELEMETRY_DEVICE_NAME		"intel_telemetry"
 106#define TELEM_SSRAM_SIZE		240
 107#define TELEM_PMC_SSRAM_OFFSET		0x1B00
 108#define TELEM_PUNIT_SSRAM_OFFSET	0x1A00
 109#define TCO_PMC_OFFSET			0x8
 110#define TCO_PMC_SIZE			0x4
 111
 112/* PMC register bit definitions */
 113
 114/* PMC_CFG_REG bit masks */
 115#define PMC_CFG_NO_REBOOT_MASK		(1 << 4)
 116#define PMC_CFG_NO_REBOOT_EN		(1 << 4)
 117#define PMC_CFG_NO_REBOOT_DIS		(0 << 4)
 118
 119static struct intel_pmc_ipc_dev {
 120	struct device *dev;
 121	void __iomem *ipc_base;
 122	bool irq_mode;
 123	int irq;
 124	int cmd;
 125	struct completion cmd_complete;
 126
 127	/* The following PMC BARs share the same ACPI device with the IPC */
 128	resource_size_t acpi_io_base;
 129	int acpi_io_size;
 130	struct platform_device *tco_dev;
 131
 132	/* gcr */
 133	void __iomem *gcr_mem_base;
 134	bool has_gcr_regs;
 135	spinlock_t gcr_lock;
 136
 137	/* punit */
 138	struct platform_device *punit_dev;
 139
 140	/* Telemetry */
 141	resource_size_t telem_pmc_ssram_base;
 142	resource_size_t telem_punit_ssram_base;
 143	int telem_pmc_ssram_size;
 144	int telem_punit_ssram_size;
 145	u8 telem_res_inval;
 146	struct platform_device *telemetry_dev;
 147} ipcdev;
 148
 149static char *ipc_err_sources[] = {
 150	[IPC_ERR_NONE] =
 151		"no error",
 152	[IPC_ERR_CMD_NOT_SUPPORTED] =
 153		"command not supported",
 154	[IPC_ERR_CMD_NOT_SERVICED] =
 155		"command not serviced",
 156	[IPC_ERR_UNABLE_TO_SERVICE] =
 157		"unable to service",
 158	[IPC_ERR_CMD_INVALID] =
 159		"command invalid",
 160	[IPC_ERR_CMD_FAILED] =
 161		"command failed",
 162	[IPC_ERR_EMSECURITY] =
 163		"Invalid Battery",
 164	[IPC_ERR_UNSIGNEDKERNEL] =
 165		"Unsigned kernel",
 166};
 167
 168/* Prevent concurrent calls to the PMC */
 169static DEFINE_MUTEX(ipclock);
 170
 171static inline void ipc_send_command(u32 cmd)
 172{
 173	ipcdev.cmd = cmd;
 174	if (ipcdev.irq_mode) {
 175		reinit_completion(&ipcdev.cmd_complete);
 176		cmd |= IPC_CMD_MSI;
 177	}
 178	writel(cmd, ipcdev.ipc_base + IPC_CMD);
 179}
 180
 181static inline u32 ipc_read_status(void)
 182{
 183	return readl(ipcdev.ipc_base + IPC_STATUS);
 184}
 185
 186static inline void ipc_data_writel(u32 data, u32 offset)
 187{
 188	writel(data, ipcdev.ipc_base + IPC_WRITE_BUFFER + offset);
 189}
 190
 191static inline u8 __maybe_unused ipc_data_readb(u32 offset)
 192{
 193	return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
 194}
 195
 196static inline u32 ipc_data_readl(u32 offset)
 197{
 198	return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
 199}
 200
 201static inline u64 gcr_data_readq(u32 offset)
 202{
 203	return readq(ipcdev.gcr_mem_base + offset);
 204}
 205
 206static inline int is_gcr_valid(u32 offset)
 207{
 208	if (!ipcdev.has_gcr_regs)
 209		return -EACCES;
 210
 211	if (offset > PLAT_RESOURCE_GCR_SIZE)
 212		return -EINVAL;
 213
 214	return 0;
 215}
 216
 217/**
 218 * intel_pmc_gcr_read() - Read a 32-bit PMC GCR register
 219 * @offset:	offset of GCR register from GCR address base
 220 * @data:	data pointer for storing the register output
 221 *
 222 * Reads the 32-bit PMC GCR register at given offset.
 223 *
 224 * Return:	negative value on error or 0 on success.
 225 */
 226int intel_pmc_gcr_read(u32 offset, u32 *data)
 227{
 228	int ret;
 229
 230	spin_lock(&ipcdev.gcr_lock);
 231
 232	ret = is_gcr_valid(offset);
 233	if (ret < 0) {
 234		spin_unlock(&ipcdev.gcr_lock);
 235		return ret;
 236	}
 237
 238	*data = readl(ipcdev.gcr_mem_base + offset);
 239
 240	spin_unlock(&ipcdev.gcr_lock);
 241
 242	return 0;
 243}
 244EXPORT_SYMBOL_GPL(intel_pmc_gcr_read);
 245
 246/**
 247 * intel_pmc_gcr_read64() - Read a 64-bit PMC GCR register
 248 * @offset:	offset of GCR register from GCR address base
 249 * @data:	data pointer for storing the register output
 250 *
 251 * Reads the 64-bit PMC GCR register at given offset.
 252 *
 253 * Return:	negative value on error or 0 on success.
 254 */
 255int intel_pmc_gcr_read64(u32 offset, u64 *data)
 256{
 257	int ret;
 258
 259	spin_lock(&ipcdev.gcr_lock);
 260
 261	ret = is_gcr_valid(offset);
 262	if (ret < 0) {
 263		spin_unlock(&ipcdev.gcr_lock);
 264		return ret;
 265	}
 266
 267	*data = readq(ipcdev.gcr_mem_base + offset);
 268
 269	spin_unlock(&ipcdev.gcr_lock);
 270
 271	return 0;
 272}
 273EXPORT_SYMBOL_GPL(intel_pmc_gcr_read64);
 274
 275/**
 276 * intel_pmc_gcr_write() - Write PMC GCR register
 277 * @offset:	offset of GCR register from GCR address base
 278 * @data:	register update value
 279 *
 280 * Writes the PMC GCR register of given offset with given
 281 * value.
 282 *
 283 * Return:	negative value on error or 0 on success.
 284 */
 285int intel_pmc_gcr_write(u32 offset, u32 data)
 286{
 287	int ret;
 288
 289	spin_lock(&ipcdev.gcr_lock);
 290
 291	ret = is_gcr_valid(offset);
 292	if (ret < 0) {
 293		spin_unlock(&ipcdev.gcr_lock);
 294		return ret;
 295	}
 296
 297	writel(data, ipcdev.gcr_mem_base + offset);
 298
 299	spin_unlock(&ipcdev.gcr_lock);
 300
 301	return 0;
 302}
 303EXPORT_SYMBOL_GPL(intel_pmc_gcr_write);
 304
 305/**
 306 * intel_pmc_gcr_update() - Update PMC GCR register bits
 307 * @offset:	offset of GCR register from GCR address base
 308 * @mask:	bit mask for update operation
 309 * @val:	update value
 310 *
 311 * Updates the bits of given GCR register as specified by
 312 * @mask and @val.
 313 *
 314 * Return:	negative value on error or 0 on success.
 315 */
 316int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val)
 317{
 318	u32 new_val;
 319	int ret = 0;
 320
 321	spin_lock(&ipcdev.gcr_lock);
 322
 323	ret = is_gcr_valid(offset);
 324	if (ret < 0)
 325		goto gcr_ipc_unlock;
 326
 327	new_val = readl(ipcdev.gcr_mem_base + offset);
 328
 329	new_val &= ~mask;
 330	new_val |= val & mask;
 331
 332	writel(new_val, ipcdev.gcr_mem_base + offset);
 333
 334	new_val = readl(ipcdev.gcr_mem_base + offset);
 335
 336	/* check whether the bit update is successful */
 337	if ((new_val & mask) != (val & mask)) {
 338		ret = -EIO;
 339		goto gcr_ipc_unlock;
 340	}
 341
 342gcr_ipc_unlock:
 343	spin_unlock(&ipcdev.gcr_lock);
 344	return ret;
 345}
 346EXPORT_SYMBOL_GPL(intel_pmc_gcr_update);
 347
 348static int update_no_reboot_bit(void *priv, bool set)
 349{
 350	u32 value = set ? PMC_CFG_NO_REBOOT_EN : PMC_CFG_NO_REBOOT_DIS;
 351
 352	return intel_pmc_gcr_update(PMC_GCR_PMC_CFG_REG,
 353				    PMC_CFG_NO_REBOOT_MASK, value);
 354}
 355
 356static int intel_pmc_ipc_check_status(void)
 357{
 358	int status;
 359	int ret = 0;
 360
 361	if (ipcdev.irq_mode) {
 362		if (0 == wait_for_completion_timeout(
 363				&ipcdev.cmd_complete, IPC_MAX_SEC * HZ))
 364			ret = -ETIMEDOUT;
 365	} else {
 366		int loop_count = IPC_LOOP_CNT;
 367
 368		while ((ipc_read_status() & IPC_STATUS_BUSY) && --loop_count)
 369			udelay(1);
 370		if (loop_count == 0)
 371			ret = -ETIMEDOUT;
 372	}
 373
 374	status = ipc_read_status();
 375	if (ret == -ETIMEDOUT) {
 376		dev_err(ipcdev.dev,
 377			"IPC timed out, TS=0x%x, CMD=0x%x\n",
 378			status, ipcdev.cmd);
 379		return ret;
 380	}
 381
 382	if (status & IPC_STATUS_ERR) {
 383		int i;
 384
 385		ret = -EIO;
 386		i = (status >> IPC_CMD_SIZE) & 0xFF;
 387		if (i < ARRAY_SIZE(ipc_err_sources))
 388			dev_err(ipcdev.dev,
 389				"IPC failed: %s, STS=0x%x, CMD=0x%x\n",
 390				ipc_err_sources[i], status, ipcdev.cmd);
 391		else
 392			dev_err(ipcdev.dev,
 393				"IPC failed: unknown, STS=0x%x, CMD=0x%x\n",
 394				status, ipcdev.cmd);
 395		if ((i == IPC_ERR_UNSIGNEDKERNEL) || (i == IPC_ERR_EMSECURITY))
 396			ret = -EACCES;
 397	}
 398
 399	return ret;
 400}
 401
 402/**
 403 * intel_pmc_ipc_simple_command() - Simple IPC command
 404 * @cmd:	IPC command code.
 405 * @sub:	IPC command sub type.
 406 *
 407 * Send a simple IPC command to PMC when don't need to specify
 408 * input/output data and source/dest pointers.
 409 *
 410 * Return:	an IPC error code or 0 on success.
 411 */
 412int intel_pmc_ipc_simple_command(int cmd, int sub)
 413{
 414	int ret;
 415
 416	mutex_lock(&ipclock);
 417	if (ipcdev.dev == NULL) {
 418		mutex_unlock(&ipclock);
 419		return -ENODEV;
 420	}
 421	ipc_send_command(sub << IPC_CMD_SUBCMD | cmd);
 422	ret = intel_pmc_ipc_check_status();
 423	mutex_unlock(&ipclock);
 424
 425	return ret;
 426}
 427EXPORT_SYMBOL_GPL(intel_pmc_ipc_simple_command);
 428
 429/**
 430 * intel_pmc_ipc_raw_cmd() - IPC command with data and pointers
 431 * @cmd:	IPC command code.
 432 * @sub:	IPC command sub type.
 433 * @in:		input data of this IPC command.
 434 * @inlen:	input data length in bytes.
 435 * @out:	output data of this IPC command.
 436 * @outlen:	output data length in dwords.
 437 * @sptr:	data writing to SPTR register.
 438 * @dptr:	data writing to DPTR register.
 439 *
 440 * Send an IPC command to PMC with input/output data and source/dest pointers.
 441 *
 442 * Return:	an IPC error code or 0 on success.
 443 */
 444int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
 445			  u32 outlen, u32 dptr, u32 sptr)
 446{
 447	u32 wbuf[4] = { 0 };
 448	int ret;
 449	int i;
 450
 451	if (inlen > IPC_DATA_BUFFER_SIZE || outlen > IPC_DATA_BUFFER_SIZE / 4)
 452		return -EINVAL;
 453
 454	mutex_lock(&ipclock);
 455	if (ipcdev.dev == NULL) {
 456		mutex_unlock(&ipclock);
 457		return -ENODEV;
 458	}
 459	memcpy(wbuf, in, inlen);
 460	writel(dptr, ipcdev.ipc_base + IPC_DPTR);
 461	writel(sptr, ipcdev.ipc_base + IPC_SPTR);
 462	/* The input data register is 32bit register and inlen is in Byte */
 463	for (i = 0; i < ((inlen + 3) / 4); i++)
 464		ipc_data_writel(wbuf[i], 4 * i);
 465	ipc_send_command((inlen << IPC_CMD_SIZE) |
 466			(sub << IPC_CMD_SUBCMD) | cmd);
 467	ret = intel_pmc_ipc_check_status();
 468	if (!ret) {
 469		/* out is read from 32bit register and outlen is in 32bit */
 470		for (i = 0; i < outlen; i++)
 471			*out++ = ipc_data_readl(4 * i);
 472	}
 473	mutex_unlock(&ipclock);
 474
 475	return ret;
 476}
 477EXPORT_SYMBOL_GPL(intel_pmc_ipc_raw_cmd);
 478
 479/**
 480 * intel_pmc_ipc_command() -  IPC command with input/output data
 481 * @cmd:	IPC command code.
 482 * @sub:	IPC command sub type.
 483 * @in:		input data of this IPC command.
 484 * @inlen:	input data length in bytes.
 485 * @out:	output data of this IPC command.
 486 * @outlen:	output data length in dwords.
 487 *
 488 * Send an IPC command to PMC with input/output data.
 489 *
 490 * Return:	an IPC error code or 0 on success.
 491 */
 492int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
 493			  u32 *out, u32 outlen)
 494{
 495	return intel_pmc_ipc_raw_cmd(cmd, sub, in, inlen, out, outlen, 0, 0);
 496}
 497EXPORT_SYMBOL_GPL(intel_pmc_ipc_command);
 498
 499static irqreturn_t ioc(int irq, void *dev_id)
 500{
 501	int status;
 502
 503	if (ipcdev.irq_mode) {
 504		status = ipc_read_status();
 505		writel(status | IPC_STATUS_IRQ, ipcdev.ipc_base + IPC_STATUS);
 506	}
 507	complete(&ipcdev.cmd_complete);
 508
 509	return IRQ_HANDLED;
 510}
 511
 512static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 513{
 514	struct intel_pmc_ipc_dev *pmc = &ipcdev;
 515	int ret;
 516
 517	/* Only one PMC is supported */
 518	if (pmc->dev)
 519		return -EBUSY;
 520
 521	pmc->irq_mode = IPC_TRIGGER_MODE_IRQ;
 522
 523	spin_lock_init(&ipcdev.gcr_lock);
 524
 525	ret = pcim_enable_device(pdev);
 526	if (ret)
 527		return ret;
 528
 529	ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
 530	if (ret)
 531		return ret;
 532
 533	init_completion(&pmc->cmd_complete);
 534
 535	pmc->ipc_base = pcim_iomap_table(pdev)[0];
 536
 537	ret = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_pmc_ipc",
 538				pmc);
 539	if (ret) {
 540		dev_err(&pdev->dev, "Failed to request irq\n");
 541		return ret;
 542	}
 543
 544	pmc->dev = &pdev->dev;
 545
 546	pci_set_drvdata(pdev, pmc);
 547
 548	return 0;
 549}
 550
 551static const struct pci_device_id ipc_pci_ids[] = {
 552	{PCI_VDEVICE(INTEL, 0x0a94), 0},
 553	{PCI_VDEVICE(INTEL, 0x1a94), 0},
 554	{PCI_VDEVICE(INTEL, 0x5a94), 0},
 555	{ 0,}
 556};
 557MODULE_DEVICE_TABLE(pci, ipc_pci_ids);
 558
 559static struct pci_driver ipc_pci_driver = {
 560	.name = "intel_pmc_ipc",
 561	.id_table = ipc_pci_ids,
 562	.probe = ipc_pci_probe,
 563};
 564
 565static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
 566					      struct device_attribute *attr,
 567					      const char *buf, size_t count)
 568{
 569	int subcmd;
 570	int cmd;
 571	int ret;
 572
 573	ret = sscanf(buf, "%d %d", &cmd, &subcmd);
 574	if (ret != 2) {
 575		dev_err(dev, "Error args\n");
 576		return -EINVAL;
 577	}
 578
 579	ret = intel_pmc_ipc_simple_command(cmd, subcmd);
 580	if (ret) {
 581		dev_err(dev, "command %d error with %d\n", cmd, ret);
 582		return ret;
 583	}
 584	return (ssize_t)count;
 585}
 586
 587static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
 588					     struct device_attribute *attr,
 589					     const char *buf, size_t count)
 590{
 591	unsigned long val;
 592	int subcmd;
 593	int ret;
 594
 595	if (kstrtoul(buf, 0, &val))
 596		return -EINVAL;
 597
 598	if (val)
 599		subcmd = 1;
 600	else
 601		subcmd = 0;
 602	ret = intel_pmc_ipc_simple_command(PMC_IPC_NORTHPEAK_CTRL, subcmd);
 603	if (ret) {
 604		dev_err(dev, "command north %d error with %d\n", subcmd, ret);
 605		return ret;
 606	}
 607	return (ssize_t)count;
 608}
 609
 610static DEVICE_ATTR(simplecmd, S_IWUSR,
 611		   NULL, intel_pmc_ipc_simple_cmd_store);
 612static DEVICE_ATTR(northpeak, S_IWUSR,
 613		   NULL, intel_pmc_ipc_northpeak_store);
 614
 615static struct attribute *intel_ipc_attrs[] = {
 616	&dev_attr_northpeak.attr,
 617	&dev_attr_simplecmd.attr,
 618	NULL
 619};
 620
 621static const struct attribute_group intel_ipc_group = {
 622	.attrs = intel_ipc_attrs,
 623};
 624
 625static struct resource punit_res_array[] = {
 626	/* Punit BIOS */
 627	{
 628		.flags = IORESOURCE_MEM,
 629	},
 630	{
 631		.flags = IORESOURCE_MEM,
 632	},
 633	/* Punit ISP */
 634	{
 635		.flags = IORESOURCE_MEM,
 636	},
 637	{
 638		.flags = IORESOURCE_MEM,
 639	},
 640	/* Punit GTD */
 641	{
 642		.flags = IORESOURCE_MEM,
 643	},
 644	{
 645		.flags = IORESOURCE_MEM,
 646	},
 647};
 648
 649#define TCO_RESOURCE_ACPI_IO		0
 650#define TCO_RESOURCE_SMI_EN_IO		1
 651#define TCO_RESOURCE_GCR_MEM		2
 652static struct resource tco_res[] = {
 653	/* ACPI - TCO */
 654	{
 655		.flags = IORESOURCE_IO,
 656	},
 657	/* ACPI - SMI */
 658	{
 659		.flags = IORESOURCE_IO,
 660	},
 661};
 662
 663static struct itco_wdt_platform_data tco_info = {
 664	.name = "Apollo Lake SoC",
 665	.version = 5,
 666	.no_reboot_priv = &ipcdev,
 667	.update_no_reboot_bit = update_no_reboot_bit,
 668};
 669
 670#define TELEMETRY_RESOURCE_PUNIT_SSRAM	0
 671#define TELEMETRY_RESOURCE_PMC_SSRAM	1
 672static struct resource telemetry_res[] = {
 673	/*Telemetry*/
 674	{
 675		.flags = IORESOURCE_MEM,
 676	},
 677	{
 678		.flags = IORESOURCE_MEM,
 679	},
 680};
 681
 682static int ipc_create_punit_device(void)
 683{
 684	struct platform_device *pdev;
 685	const struct platform_device_info pdevinfo = {
 686		.parent = ipcdev.dev,
 687		.name = PUNIT_DEVICE_NAME,
 688		.id = -1,
 689		.res = punit_res_array,
 690		.num_res = ARRAY_SIZE(punit_res_array),
 691		};
 692
 693	pdev = platform_device_register_full(&pdevinfo);
 694	if (IS_ERR(pdev))
 695		return PTR_ERR(pdev);
 696
 697	ipcdev.punit_dev = pdev;
 698
 699	return 0;
 700}
 701
 702static int ipc_create_tco_device(void)
 703{
 704	struct platform_device *pdev;
 705	struct resource *res;
 706	const struct platform_device_info pdevinfo = {
 707		.parent = ipcdev.dev,
 708		.name = TCO_DEVICE_NAME,
 709		.id = -1,
 710		.res = tco_res,
 711		.num_res = ARRAY_SIZE(tco_res),
 712		.data = &tco_info,
 713		.size_data = sizeof(tco_info),
 714		};
 715
 716	res = tco_res + TCO_RESOURCE_ACPI_IO;
 717	res->start = ipcdev.acpi_io_base + TCO_BASE_OFFSET;
 718	res->end = res->start + TCO_REGS_SIZE - 1;
 719
 720	res = tco_res + TCO_RESOURCE_SMI_EN_IO;
 721	res->start = ipcdev.acpi_io_base + SMI_EN_OFFSET;
 722	res->end = res->start + SMI_EN_SIZE - 1;
 723
 724	pdev = platform_device_register_full(&pdevinfo);
 725	if (IS_ERR(pdev))
 726		return PTR_ERR(pdev);
 727
 728	ipcdev.tco_dev = pdev;
 729
 730	return 0;
 731}
 732
 733static int ipc_create_telemetry_device(void)
 734{
 735	struct platform_device *pdev;
 736	struct resource *res;
 737	const struct platform_device_info pdevinfo = {
 738		.parent = ipcdev.dev,
 739		.name = TELEMETRY_DEVICE_NAME,
 740		.id = -1,
 741		.res = telemetry_res,
 742		.num_res = ARRAY_SIZE(telemetry_res),
 743		};
 744
 745	res = telemetry_res + TELEMETRY_RESOURCE_PUNIT_SSRAM;
 746	res->start = ipcdev.telem_punit_ssram_base;
 747	res->end = res->start + ipcdev.telem_punit_ssram_size - 1;
 748
 749	res = telemetry_res + TELEMETRY_RESOURCE_PMC_SSRAM;
 750	res->start = ipcdev.telem_pmc_ssram_base;
 751	res->end = res->start + ipcdev.telem_pmc_ssram_size - 1;
 752
 753	pdev = platform_device_register_full(&pdevinfo);
 754	if (IS_ERR(pdev))
 755		return PTR_ERR(pdev);
 756
 757	ipcdev.telemetry_dev = pdev;
 758
 759	return 0;
 760}
 761
 762static int ipc_create_pmc_devices(void)
 763{
 764	int ret;
 765
 766	/* If we have ACPI based watchdog use that instead */
 767	if (!acpi_has_watchdog()) {
 768		ret = ipc_create_tco_device();
 769		if (ret) {
 770			dev_err(ipcdev.dev, "Failed to add tco platform device\n");
 771			return ret;
 772		}
 773	}
 774
 775	ret = ipc_create_punit_device();
 776	if (ret) {
 777		dev_err(ipcdev.dev, "Failed to add punit platform device\n");
 778		platform_device_unregister(ipcdev.tco_dev);
 779	}
 780
 781	if (!ipcdev.telem_res_inval) {
 782		ret = ipc_create_telemetry_device();
 783		if (ret)
 784			dev_warn(ipcdev.dev,
 785				"Failed to add telemetry platform device\n");
 786	}
 787
 788	return ret;
 789}
 790
 791static int ipc_plat_get_res(struct platform_device *pdev)
 792{
 793	struct resource *res, *punit_res;
 794	void __iomem *addr;
 795	int size;
 796
 797	res = platform_get_resource(pdev, IORESOURCE_IO,
 798				    PLAT_RESOURCE_ACPI_IO_INDEX);
 799	if (!res) {
 800		dev_err(&pdev->dev, "Failed to get io resource\n");
 801		return -ENXIO;
 802	}
 803	size = resource_size(res);
 804	ipcdev.acpi_io_base = res->start;
 805	ipcdev.acpi_io_size = size;
 806	dev_info(&pdev->dev, "io res: %pR\n", res);
 807
 808	punit_res = punit_res_array;
 809	/* This is index 0 to cover BIOS data register */
 810	res = platform_get_resource(pdev, IORESOURCE_MEM,
 811				    PLAT_RESOURCE_BIOS_DATA_INDEX);
 812	if (!res) {
 813		dev_err(&pdev->dev, "Failed to get res of punit BIOS data\n");
 814		return -ENXIO;
 815	}
 816	*punit_res = *res;
 817	dev_info(&pdev->dev, "punit BIOS data res: %pR\n", res);
 818
 819	/* This is index 1 to cover BIOS interface register */
 820	res = platform_get_resource(pdev, IORESOURCE_MEM,
 821				    PLAT_RESOURCE_BIOS_IFACE_INDEX);
 822	if (!res) {
 823		dev_err(&pdev->dev, "Failed to get res of punit BIOS iface\n");
 824		return -ENXIO;
 825	}
 826	*++punit_res = *res;
 827	dev_info(&pdev->dev, "punit BIOS interface res: %pR\n", res);
 828
 829	/* This is index 2 to cover ISP data register, optional */
 830	res = platform_get_resource(pdev, IORESOURCE_MEM,
 831				    PLAT_RESOURCE_ISP_DATA_INDEX);
 832	++punit_res;
 833	if (res) {
 834		*punit_res = *res;
 835		dev_info(&pdev->dev, "punit ISP data res: %pR\n", res);
 836	}
 837
 838	/* This is index 3 to cover ISP interface register, optional */
 839	res = platform_get_resource(pdev, IORESOURCE_MEM,
 840				    PLAT_RESOURCE_ISP_IFACE_INDEX);
 841	++punit_res;
 842	if (res) {
 843		*punit_res = *res;
 844		dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res);
 845	}
 846
 847	/* This is index 4 to cover GTD data register, optional */
 848	res = platform_get_resource(pdev, IORESOURCE_MEM,
 849				    PLAT_RESOURCE_GTD_DATA_INDEX);
 850	++punit_res;
 851	if (res) {
 852		*punit_res = *res;
 853		dev_info(&pdev->dev, "punit GTD data res: %pR\n", res);
 854	}
 855
 856	/* This is index 5 to cover GTD interface register, optional */
 857	res = platform_get_resource(pdev, IORESOURCE_MEM,
 858				    PLAT_RESOURCE_GTD_IFACE_INDEX);
 859	++punit_res;
 860	if (res) {
 861		*punit_res = *res;
 862		dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res);
 863	}
 864
 865	res = platform_get_resource(pdev, IORESOURCE_MEM,
 866				    PLAT_RESOURCE_IPC_INDEX);
 867	if (!res) {
 868		dev_err(&pdev->dev, "Failed to get ipc resource\n");
 869		return -ENXIO;
 870	}
 871	size = PLAT_RESOURCE_IPC_SIZE + PLAT_RESOURCE_GCR_SIZE;
 872	res->end = res->start + size - 1;
 873
 874	addr = devm_ioremap_resource(&pdev->dev, res);
 875	if (IS_ERR(addr))
 876		return PTR_ERR(addr);
 877
 878	ipcdev.ipc_base = addr;
 879
 880	ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET;
 881	dev_info(&pdev->dev, "ipc res: %pR\n", res);
 882
 883	ipcdev.telem_res_inval = 0;
 884	res = platform_get_resource(pdev, IORESOURCE_MEM,
 885				    PLAT_RESOURCE_TELEM_SSRAM_INDEX);
 886	if (!res) {
 887		dev_err(&pdev->dev, "Failed to get telemetry ssram resource\n");
 888		ipcdev.telem_res_inval = 1;
 889	} else {
 890		ipcdev.telem_punit_ssram_base = res->start +
 891						TELEM_PUNIT_SSRAM_OFFSET;
 892		ipcdev.telem_punit_ssram_size = TELEM_SSRAM_SIZE;
 893		ipcdev.telem_pmc_ssram_base = res->start +
 894						TELEM_PMC_SSRAM_OFFSET;
 895		ipcdev.telem_pmc_ssram_size = TELEM_SSRAM_SIZE;
 896		dev_info(&pdev->dev, "telemetry ssram res: %pR\n", res);
 897	}
 898
 899	return 0;
 900}
 901
 902/**
 903 * intel_pmc_s0ix_counter_read() - Read S0ix residency.
 904 * @data: Out param that contains current S0ix residency count.
 905 *
 906 * Return: an error code or 0 on success.
 907 */
 908int intel_pmc_s0ix_counter_read(u64 *data)
 909{
 910	u64 deep, shlw;
 911
 912	if (!ipcdev.has_gcr_regs)
 913		return -EACCES;
 914
 915	deep = gcr_data_readq(PMC_GCR_TELEM_DEEP_S0IX_REG);
 916	shlw = gcr_data_readq(PMC_GCR_TELEM_SHLW_S0IX_REG);
 917
 918	*data = S0IX_RESIDENCY_IN_USECS(deep, shlw);
 919
 920	return 0;
 921}
 922EXPORT_SYMBOL_GPL(intel_pmc_s0ix_counter_read);
 923
 924#ifdef CONFIG_ACPI
 925static const struct acpi_device_id ipc_acpi_ids[] = {
 926	{ "INT34D2", 0},
 927	{ }
 928};
 929MODULE_DEVICE_TABLE(acpi, ipc_acpi_ids);
 930#endif
 931
 932static int ipc_plat_probe(struct platform_device *pdev)
 933{
 934	int ret;
 935
 936	ipcdev.dev = &pdev->dev;
 937	ipcdev.irq_mode = IPC_TRIGGER_MODE_IRQ;
 938	init_completion(&ipcdev.cmd_complete);
 939	spin_lock_init(&ipcdev.gcr_lock);
 940
 941	ipcdev.irq = platform_get_irq(pdev, 0);
 942	if (ipcdev.irq < 0) {
 943		dev_err(&pdev->dev, "Failed to get irq\n");
 944		return -EINVAL;
 945	}
 946
 947	ret = ipc_plat_get_res(pdev);
 948	if (ret) {
 949		dev_err(&pdev->dev, "Failed to request resource\n");
 950		return ret;
 951	}
 952
 953	ret = ipc_create_pmc_devices();
 954	if (ret) {
 955		dev_err(&pdev->dev, "Failed to create pmc devices\n");
 956		return ret;
 957	}
 958
 959	if (devm_request_irq(&pdev->dev, ipcdev.irq, ioc, IRQF_NO_SUSPEND,
 960			     "intel_pmc_ipc", &ipcdev)) {
 961		dev_err(&pdev->dev, "Failed to request irq\n");
 962		ret = -EBUSY;
 963		goto err_irq;
 964	}
 965
 966	ret = sysfs_create_group(&pdev->dev.kobj, &intel_ipc_group);
 967	if (ret) {
 968		dev_err(&pdev->dev, "Failed to create sysfs group %d\n",
 969			ret);
 970		goto err_sys;
 971	}
 972
 973	ipcdev.has_gcr_regs = true;
 974
 975	return 0;
 976err_sys:
 977	devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev);
 978err_irq:
 979	platform_device_unregister(ipcdev.tco_dev);
 980	platform_device_unregister(ipcdev.punit_dev);
 981	platform_device_unregister(ipcdev.telemetry_dev);
 982
 983	return ret;
 984}
 985
 986static int ipc_plat_remove(struct platform_device *pdev)
 987{
 988	sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group);
 989	devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev);
 990	platform_device_unregister(ipcdev.tco_dev);
 991	platform_device_unregister(ipcdev.punit_dev);
 992	platform_device_unregister(ipcdev.telemetry_dev);
 993	ipcdev.dev = NULL;
 994	return 0;
 995}
 996
 997static struct platform_driver ipc_plat_driver = {
 998	.remove = ipc_plat_remove,
 999	.probe = ipc_plat_probe,
1000	.driver = {
1001		.name = "pmc-ipc-plat",
1002		.acpi_match_table = ACPI_PTR(ipc_acpi_ids),
1003	},
1004};
1005
1006static int __init intel_pmc_ipc_init(void)
1007{
1008	int ret;
1009
1010	ret = platform_driver_register(&ipc_plat_driver);
1011	if (ret) {
1012		pr_err("Failed to register PMC ipc platform driver\n");
1013		return ret;
1014	}
1015	ret = pci_register_driver(&ipc_pci_driver);
1016	if (ret) {
1017		pr_err("Failed to register PMC ipc pci driver\n");
1018		platform_driver_unregister(&ipc_plat_driver);
1019		return ret;
1020	}
1021	return ret;
1022}
1023
1024static void __exit intel_pmc_ipc_exit(void)
1025{
1026	pci_unregister_driver(&ipc_pci_driver);
1027	platform_driver_unregister(&ipc_plat_driver);
1028}
1029
1030MODULE_AUTHOR("Zha Qipeng <qipeng.zha@intel.com>");
1031MODULE_DESCRIPTION("Intel PMC IPC driver");
1032MODULE_LICENSE("GPL");
1033
1034/* Some modules are dependent on this, so init earlier */
1035fs_initcall(intel_pmc_ipc_init);
1036module_exit(intel_pmc_ipc_exit);