/*
 * Copyright (c) 2015, 2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that 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 "sdhci-msm-ice.h"

static void sdhci_msm_ice_error_cb(void *host_ctrl, u32 error)
{
	struct sdhci_msm_host *msm_host = (struct sdhci_msm_host *)host_ctrl;

	dev_err(&msm_host->pdev->dev, "%s: Error in ice operation 0x%x",
		__func__, error);

	if (msm_host->ice.state == SDHCI_MSM_ICE_STATE_ACTIVE)
		msm_host->ice.state = SDHCI_MSM_ICE_STATE_DISABLED;
}

static struct platform_device *sdhci_msm_ice_get_pdevice(struct device *dev)
{
	struct device_node *node;
	struct platform_device *ice_pdev = NULL;

	node = of_parse_phandle(dev->of_node, SDHC_MSM_CRYPTO_LABEL, 0);
	if (!node) {
		dev_dbg(dev, "%s: sdhc-msm-crypto property not specified\n",
			__func__);
		goto out;
	}
	ice_pdev = qcom_ice_get_pdevice(node);
out:
	return ice_pdev;
}

static
struct qcom_ice_variant_ops *sdhci_msm_ice_get_vops(struct device *dev)
{
	struct qcom_ice_variant_ops *ice_vops = NULL;
	struct device_node *node;

	node = of_parse_phandle(dev->of_node, SDHC_MSM_CRYPTO_LABEL, 0);
	if (!node) {
		dev_dbg(dev, "%s: sdhc-msm-crypto property not specified\n",
			__func__);
		goto out;
	}
	ice_vops = qcom_ice_get_variant_ops(node);
	of_node_put(node);
out:
	return ice_vops;
}

static
void sdhci_msm_enable_ice_hci(struct sdhci_host *host, bool enable)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_msm_host *msm_host = pltfm_host->priv;
	u32 config = 0;
	u32 ice_cap = 0;

	/*
	 * Enable the cryptographic support inside SDHC.
	 * This is a global config which needs to be enabled
	 * all the time.
	 * Only when it it is enabled, the ICE_HCI capability
	 * will get reflected in CQCAP register.
	 */
	config = readl_relaxed(host->ioaddr + HC_VENDOR_SPECIFIC_FUNC4);

	if (enable)
		config &= ~DISABLE_CRYPTO;
	else
		config |= DISABLE_CRYPTO;
	writel_relaxed(config, host->ioaddr + HC_VENDOR_SPECIFIC_FUNC4);

	/*
	 * CQCAP register is in different register space from above
	 * ice global enable register. So a mb() is required to ensure
	 * above write gets completed before reading the CQCAP register.
	 */
	mb();

	/*
	 * Check if ICE HCI capability support is present
	 * If present, enable it.
	 */
	ice_cap = readl_relaxed(msm_host->cryptoio + ICE_CQ_CAPABILITIES);
	if (ice_cap & ICE_HCI_SUPPORT) {
		config = readl_relaxed(msm_host->cryptoio + ICE_CQ_CONFIG);

		if (enable)
			config |= CRYPTO_GENERAL_ENABLE;
		else
			config &= ~CRYPTO_GENERAL_ENABLE;
		writel_relaxed(config, msm_host->cryptoio + ICE_CQ_CONFIG);
	}
}

int sdhci_msm_ice_get_dev(struct sdhci_host *host)
{
	struct device *sdhc_dev;
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_msm_host *msm_host = pltfm_host->priv;

	if (!msm_host || !msm_host->pdev) {
		pr_err("%s: invalid msm_host %p or msm_host->pdev\n",
			__func__, msm_host);
		return -EINVAL;
	}

	sdhc_dev = &msm_host->pdev->dev;
	msm_host->ice.vops  = sdhci_msm_ice_get_vops(sdhc_dev);
	msm_host->ice.pdev = sdhci_msm_ice_get_pdevice(sdhc_dev);

	if (msm_host->ice.pdev == ERR_PTR(-EPROBE_DEFER)) {
		dev_err(sdhc_dev, "%s: ICE device not probed yet\n",
			__func__);
		msm_host->ice.pdev = NULL;
		msm_host->ice.vops = NULL;
		return -EPROBE_DEFER;
	}

	if (!msm_host->ice.pdev) {
		dev_dbg(sdhc_dev, "%s: invalid platform device\n", __func__);
		msm_host->ice.vops = NULL;
		return -ENODEV;
	}
	if (!msm_host->ice.vops) {
		dev_dbg(sdhc_dev, "%s: invalid ice vops\n", __func__);
		msm_host->ice.pdev = NULL;
		return -ENODEV;
	}
	msm_host->ice.state = SDHCI_MSM_ICE_STATE_DISABLED;
	return 0;
}

static
int sdhci_msm_ice_pltfm_init(struct sdhci_msm_host *msm_host)
{
	struct resource *ice_memres = NULL;
	struct platform_device *pdev = msm_host->pdev;
	int err = 0;

	if (!msm_host->ice_hci_support)
		goto out;
	/*
	 * ICE HCI registers are present in cmdq register space.
	 * So map the cmdq mem for accessing ICE HCI registers.
	 */
	ice_memres = platform_get_resource_byname(pdev,
						IORESOURCE_MEM, "cmdq_mem");
	if (!ice_memres) {
		dev_err(&pdev->dev, "Failed to get iomem resource for ice\n");
		err = -EINVAL;
		goto out;
	}
	msm_host->cryptoio = devm_ioremap(&pdev->dev,
					ice_memres->start,
					resource_size(ice_memres));
	if (!msm_host->cryptoio) {
		dev_err(&pdev->dev, "Failed to remap registers\n");
		err = -ENOMEM;
	}
out:
	return err;
}

int sdhci_msm_ice_init(struct sdhci_host *host)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_msm_host *msm_host = pltfm_host->priv;
	int err = 0;

	if (msm_host->ice.vops->init) {
		err = sdhci_msm_ice_pltfm_init(msm_host);
		if (err)
			goto out;

		if (msm_host->ice_hci_support)
			sdhci_msm_enable_ice_hci(host, true);

		err = msm_host->ice.vops->init(msm_host->ice.pdev,
					msm_host,
					sdhci_msm_ice_error_cb);
		if (err) {
			pr_err("%s: ice init err %d\n",
				mmc_hostname(host->mmc), err);
			sdhci_msm_ice_print_regs(host);
			if (msm_host->ice_hci_support)
				sdhci_msm_enable_ice_hci(host, false);
			goto out;
		}
		msm_host->ice.state = SDHCI_MSM_ICE_STATE_ACTIVE;
	}

out:
	return err;
}

void sdhci_msm_ice_cfg_reset(struct sdhci_host *host, u32 slot)
{
	writel_relaxed(SDHCI_MSM_ICE_ENABLE_BYPASS,
		host->ioaddr + CORE_VENDOR_SPEC_ICE_CTRL_INFO_3_n + 16 * slot);
}

int sdhci_msm_ice_cfg(struct sdhci_host *host, struct mmc_request *mrq,
			u32 slot)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_msm_host *msm_host = pltfm_host->priv;
	int err = 0;
	struct ice_data_setting ice_set;
	sector_t lba = 0;
	unsigned int ctrl_info_val = 0;
	unsigned int bypass = SDHCI_MSM_ICE_ENABLE_BYPASS;
	struct request *req;

	if (msm_host->ice.state != SDHCI_MSM_ICE_STATE_ACTIVE) {
		pr_err("%s: ice is in invalid state %d\n",
			mmc_hostname(host->mmc), msm_host->ice.state);
		return -EINVAL;
	}

	BUG_ON(!mrq);
	memset(&ice_set, 0, sizeof(struct ice_data_setting));
	req = mrq->req;
	if (req) {
		lba = req->__sector;
		if (msm_host->ice.vops->config_start) {
			err = msm_host->ice.vops->config_start(
							msm_host->ice.pdev,
							req, &ice_set, false);
			if (err) {
				pr_err("%s: ice config failed %d\n",
						mmc_hostname(host->mmc), err);
				return err;
			}
		}
		/* if writing data command */
		if (rq_data_dir(req) == WRITE)
			bypass = ice_set.encr_bypass ?
					SDHCI_MSM_ICE_ENABLE_BYPASS :
					SDHCI_MSM_ICE_DISABLE_BYPASS;
		/* if reading data command */
		else if (rq_data_dir(req) == READ)
			bypass = ice_set.decr_bypass ?
					SDHCI_MSM_ICE_ENABLE_BYPASS :
					SDHCI_MSM_ICE_DISABLE_BYPASS;
		pr_debug("%s: %s: slot %d encr_bypass %d bypass %d decr_bypass %d key_index %d\n",
				mmc_hostname(host->mmc),
				(rq_data_dir(req) == WRITE) ? "WRITE" : "READ",
				slot, ice_set.encr_bypass, bypass,
				ice_set.decr_bypass,
				ice_set.crypto_data.key_index);
	}

	/* Configure ICE index */
	ctrl_info_val =
		(ice_set.crypto_data.key_index &
		 MASK_SDHCI_MSM_ICE_CTRL_INFO_KEY_INDEX)
		 << OFFSET_SDHCI_MSM_ICE_CTRL_INFO_KEY_INDEX;

	/* Configure data unit size of transfer request */
	ctrl_info_val |=
		(SDHCI_MSM_ICE_TR_DATA_UNIT_512_B &
		 MASK_SDHCI_MSM_ICE_CTRL_INFO_CDU)
		 << OFFSET_SDHCI_MSM_ICE_CTRL_INFO_CDU;

	/* Configure ICE bypass mode */
	ctrl_info_val |=
		(bypass & MASK_SDHCI_MSM_ICE_CTRL_INFO_BYPASS)
		 << OFFSET_SDHCI_MSM_ICE_CTRL_INFO_BYPASS;

	writel_relaxed((lba & 0xFFFFFFFF),
		host->ioaddr + CORE_VENDOR_SPEC_ICE_CTRL_INFO_1_n + 16 * slot);
	writel_relaxed(((lba >> 32) & 0xFFFFFFFF),
		host->ioaddr + CORE_VENDOR_SPEC_ICE_CTRL_INFO_2_n + 16 * slot);
	writel_relaxed(ctrl_info_val,
		host->ioaddr + CORE_VENDOR_SPEC_ICE_CTRL_INFO_3_n + 16 * slot);

	/* Ensure ICE registers are configured before issuing SDHCI request */
	mb();
	return 0;
}

int sdhci_msm_ice_reset(struct sdhci_host *host)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_msm_host *msm_host = pltfm_host->priv;
	int err = 0;

	if (msm_host->ice.state != SDHCI_MSM_ICE_STATE_ACTIVE) {
		pr_err("%s: ice is in invalid state before reset %d\n",
			mmc_hostname(host->mmc), msm_host->ice.state);
		return -EINVAL;
	}

	if (msm_host->ice.vops->reset) {
		err = msm_host->ice.vops->reset(msm_host->ice.pdev);
		if (err) {
			pr_err("%s: ice reset failed %d\n",
					mmc_hostname(host->mmc), err);
			sdhci_msm_ice_print_regs(host);
			return err;
		}
	}

	/* If ICE HCI support is present then re-enable it */
	if (msm_host->ice_hci_support)
		sdhci_msm_enable_ice_hci(host, true);

	if (msm_host->ice.state != SDHCI_MSM_ICE_STATE_ACTIVE) {
		pr_err("%s: ice is in invalid state after reset %d\n",
			mmc_hostname(host->mmc), msm_host->ice.state);
		return -EINVAL;
	}
	return 0;
}

int sdhci_msm_ice_resume(struct sdhci_host *host)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_msm_host *msm_host = pltfm_host->priv;
	int err = 0;

	if (msm_host->ice.state !=
			SDHCI_MSM_ICE_STATE_SUSPENDED) {
		pr_err("%s: ice is in invalid state before resume %d\n",
			mmc_hostname(host->mmc), msm_host->ice.state);
		return -EINVAL;
	}

	if (msm_host->ice.vops->resume) {
		err = msm_host->ice.vops->resume(msm_host->ice.pdev);
		if (err) {
			pr_err("%s: ice resume failed %d\n",
					mmc_hostname(host->mmc), err);
			return err;
		}
	}

	msm_host->ice.state = SDHCI_MSM_ICE_STATE_ACTIVE;
	return 0;
}

int sdhci_msm_ice_suspend(struct sdhci_host *host)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_msm_host *msm_host = pltfm_host->priv;
	int err = 0;

	if (msm_host->ice.state !=
			SDHCI_MSM_ICE_STATE_ACTIVE) {
		pr_err("%s: ice is in invalid state before resume %d\n",
			mmc_hostname(host->mmc), msm_host->ice.state);
		return -EINVAL;
	}

	if (msm_host->ice.vops->suspend) {
		err = msm_host->ice.vops->suspend(msm_host->ice.pdev);
		if (err) {
			pr_err("%s: ice suspend failed %d\n",
					mmc_hostname(host->mmc), err);
			return -EINVAL;
		}
	}
	msm_host->ice.state = SDHCI_MSM_ICE_STATE_SUSPENDED;
	return 0;
}

int sdhci_msm_ice_get_status(struct sdhci_host *host, int *ice_status)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_msm_host *msm_host = pltfm_host->priv;
	int stat = -EINVAL;

	if (msm_host->ice.state != SDHCI_MSM_ICE_STATE_ACTIVE) {
		pr_err("%s: ice is in invalid state %d\n",
			mmc_hostname(host->mmc), msm_host->ice.state);
		return -EINVAL;
	}

	if (msm_host->ice.vops->status) {
		*ice_status = 0;
		stat = msm_host->ice.vops->status(msm_host->ice.pdev);
		if (stat < 0) {
			pr_err("%s: ice get sts failed %d\n",
					mmc_hostname(host->mmc), stat);
			return -EINVAL;
		}
		*ice_status = stat;
	}
	return 0;
}

void sdhci_msm_ice_print_regs(struct sdhci_host *host)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_msm_host *msm_host = pltfm_host->priv;

	if (msm_host->ice.vops->debug)
		msm_host->ice.vops->debug(msm_host->ice.pdev);
}
