/* intel_pch_thermal.c - Intel PCH Thermal driver
 *
 * Copyright (c) 2015, Intel Corporation.
 *
 * Authors:
 *     Tushar Dave <tushar.n.dave@intel.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/thermal.h>

/* Intel PCH thermal Device IDs */
#define PCH_THERMAL_DID_WPT	0x9CA4 /* Wildcat Point */

/* Wildcat Point-LP  PCH Thermal registers */
#define WPT_TEMP	0x0000	/* Temperature */
#define WPT_TSC	0x04	/* Thermal Sensor Control */
#define WPT_TSS	0x06	/* Thermal Sensor Status */
#define WPT_TSEL	0x08	/* Thermal Sensor Enable and Lock */
#define WPT_TSREL	0x0A	/* Thermal Sensor Report Enable and Lock */
#define WPT_TSMIC	0x0C	/* Thermal Sensor SMI Control */
#define WPT_CTT	0x0010	/* Catastrophic Trip Point */
#define WPT_TAHV	0x0014	/* Thermal Alert High Value */
#define WPT_TALV	0x0018	/* Thermal Alert Low Value */
#define WPT_TL		0x00000040	/* Throttle Value */
#define WPT_PHL	0x0060	/* PCH Hot Level */
#define WPT_PHLC	0x62	/* PHL Control */
#define WPT_TAS	0x80	/* Thermal Alert Status */
#define WPT_TSPIEN	0x82	/* PCI Interrupt Event Enables */
#define WPT_TSGPEN	0x84	/* General Purpose Event Enables */

/*  Wildcat Point-LP  PCH Thermal Register bit definitions */
#define WPT_TEMP_TSR	0x00ff	/* Temp TS Reading */
#define WPT_TSC_CPDE	0x01	/* Catastrophic Power-Down Enable */
#define WPT_TSS_TSDSS	0x10	/* Thermal Sensor Dynamic Shutdown Status */
#define WPT_TSS_GPES	0x08	/* GPE status */
#define WPT_TSEL_ETS	0x01    /* Enable TS */
#define WPT_TSEL_PLDB	0x80	/* TSEL Policy Lock-Down Bit */
#define WPT_TL_TOL	0x000001FF	/* T0 Level */
#define WPT_TL_T1L	0x1ff00000	/* T1 Level */
#define WPT_TL_TTEN	0x20000000	/* TT Enable */

static char driver_name[] = "Intel PCH thermal driver";

struct pch_thermal_device {
	void __iomem *hw_base;
	const struct pch_dev_ops *ops;
	struct pci_dev *pdev;
	struct thermal_zone_device *tzd;
	int crt_trip_id;
	unsigned long crt_temp;
	int hot_trip_id;
	unsigned long hot_temp;
};

static int pch_wpt_init(struct pch_thermal_device *ptd, int *nr_trips)
{
	u8 tsel;
	u16 trip_temp;

	*nr_trips = 0;

	/* Check if BIOS has already enabled thermal sensor */
	if (WPT_TSS_TSDSS & readb(ptd->hw_base + WPT_TSS))
		goto read_trips;

	tsel = readb(ptd->hw_base + WPT_TSEL);
	/*
	 * When TSEL's Policy Lock-Down bit is 1, TSEL become RO.
	 * If so, thermal sensor cannot enable. Bail out.
	 */
	if (tsel & WPT_TSEL_PLDB) {
		dev_err(&ptd->pdev->dev, "Sensor can't be enabled\n");
		return -ENODEV;
	}

	writeb(tsel|WPT_TSEL_ETS, ptd->hw_base + WPT_TSEL);
	if (!(WPT_TSS_TSDSS & readb(ptd->hw_base + WPT_TSS))) {
		dev_err(&ptd->pdev->dev, "Sensor can't be enabled\n");
		return -ENODEV;
	}

read_trips:
	ptd->crt_trip_id = -1;
	trip_temp = readw(ptd->hw_base + WPT_CTT);
	trip_temp &= 0x1FF;
	if (trip_temp) {
		/* Resolution of 1/2 degree C and an offset of -50C */
		ptd->crt_temp = trip_temp * 1000 / 2 - 50000;
		ptd->crt_trip_id = 0;
		++(*nr_trips);
	}

	ptd->hot_trip_id = -1;
	trip_temp = readw(ptd->hw_base + WPT_PHL);
	trip_temp &= 0x1FF;
	if (trip_temp) {
		/* Resolution of 1/2 degree C and an offset of -50C */
		ptd->hot_temp = trip_temp * 1000 / 2 - 50000;
		ptd->hot_trip_id = *nr_trips;
		++(*nr_trips);
	}

	return 0;
}

static int pch_wpt_get_temp(struct pch_thermal_device *ptd, int *temp)
{
	u8 wpt_temp;

	wpt_temp = WPT_TEMP_TSR & readl(ptd->hw_base + WPT_TEMP);

	/* Resolution of 1/2 degree C and an offset of -50C */
	*temp = (wpt_temp * 1000 / 2 - 50000);

	return 0;
}

struct pch_dev_ops {
	int (*hw_init)(struct pch_thermal_device *ptd, int *nr_trips);
	int (*get_temp)(struct pch_thermal_device *ptd, int *temp);
};


/* dev ops for Wildcat Point */
static struct pch_dev_ops pch_dev_ops_wpt = {
	.hw_init = pch_wpt_init,
	.get_temp = pch_wpt_get_temp,
};

static int pch_thermal_get_temp(struct thermal_zone_device *tzd, int *temp)
{
	struct pch_thermal_device *ptd = tzd->devdata;

	return	ptd->ops->get_temp(ptd, temp);
}

static int pch_get_trip_type(struct thermal_zone_device *tzd, int trip,
			     enum thermal_trip_type *type)
{
	struct pch_thermal_device *ptd = tzd->devdata;

	if (ptd->crt_trip_id == trip)
		*type = THERMAL_TRIP_CRITICAL;
	else if (ptd->hot_trip_id == trip)
		*type = THERMAL_TRIP_HOT;
	else
		return -EINVAL;

	return 0;
}

static int pch_get_trip_temp(struct thermal_zone_device *tzd, int trip, int *temp)
{
	struct pch_thermal_device *ptd = tzd->devdata;

	if (ptd->crt_trip_id == trip)
		*temp = ptd->crt_temp;
	else if (ptd->hot_trip_id == trip)
		*temp = ptd->hot_temp;
	else
		return -EINVAL;

	return 0;
}

static struct thermal_zone_device_ops tzd_ops = {
	.get_temp = pch_thermal_get_temp,
	.get_trip_type = pch_get_trip_type,
	.get_trip_temp = pch_get_trip_temp,
};


static int intel_pch_thermal_probe(struct pci_dev *pdev,
				   const struct pci_device_id *id)
{
	struct pch_thermal_device *ptd;
	int err;
	int nr_trips;
	char *dev_name;

	ptd = devm_kzalloc(&pdev->dev, sizeof(*ptd), GFP_KERNEL);
	if (!ptd)
		return -ENOMEM;

	switch (pdev->device) {
	case PCH_THERMAL_DID_WPT:
		ptd->ops = &pch_dev_ops_wpt;
		dev_name = "pch_wildcat_point";
		break;
	default:
		dev_err(&pdev->dev, "unknown pch thermal device\n");
		return -ENODEV;
	}

	pci_set_drvdata(pdev, ptd);
	ptd->pdev = pdev;

	err = pci_enable_device(pdev);
	if (err) {
		dev_err(&pdev->dev, "failed to enable pci device\n");
		return err;
	}

	err = pci_request_regions(pdev, driver_name);
	if (err) {
		dev_err(&pdev->dev, "failed to request pci region\n");
		goto error_disable;
	}

	ptd->hw_base = pci_ioremap_bar(pdev, 0);
	if (!ptd->hw_base) {
		err = -ENOMEM;
		dev_err(&pdev->dev, "failed to map mem base\n");
		goto error_release;
	}

	err = ptd->ops->hw_init(ptd, &nr_trips);
	if (err)
		goto error_cleanup;

	ptd->tzd = thermal_zone_device_register(dev_name, nr_trips, 0, ptd,
						&tzd_ops, NULL, 0, 0);
	if (IS_ERR(ptd->tzd)) {
		dev_err(&pdev->dev, "Failed to register thermal zone %s\n",
			dev_name);
		err = PTR_ERR(ptd->tzd);
		goto error_cleanup;
	}

	return 0;

error_cleanup:
	iounmap(ptd->hw_base);
error_release:
	pci_release_regions(pdev);
error_disable:
	pci_disable_device(pdev);
	dev_err(&pdev->dev, "pci device failed to probe\n");
	return err;
}

static void intel_pch_thermal_remove(struct pci_dev *pdev)
{
	struct pch_thermal_device *ptd = pci_get_drvdata(pdev);

	thermal_zone_device_unregister(ptd->tzd);
	iounmap(ptd->hw_base);
	pci_set_drvdata(pdev, NULL);
	pci_release_region(pdev, 0);
	pci_disable_device(pdev);
}

static struct pci_device_id intel_pch_thermal_id[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_WPT) },
	{ 0, },
};
MODULE_DEVICE_TABLE(pci, intel_pch_thermal_id);

static struct pci_driver intel_pch_thermal_driver = {
	.name		= "intel_pch_thermal",
	.id_table	= intel_pch_thermal_id,
	.probe		= intel_pch_thermal_probe,
	.remove		= intel_pch_thermal_remove,
};

module_pci_driver(intel_pch_thermal_driver);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel PCH Thermal driver");
