Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8dbdec2 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mmc: sdhci-msm-ice: Enable ICE HCI if supported"

parents cf5b32c2 92907bcb
Loading
Loading
Loading
Loading
+90 −0
Original line number Diff line number Diff line
@@ -58,6 +58,52 @@ 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;
@@ -96,6 +142,37 @@ int sdhci_msm_ice_get_dev(struct sdhci_host *host)
	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);
@@ -103,6 +180,13 @@ int sdhci_msm_ice_init(struct sdhci_host *host)
	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);
@@ -110,6 +194,8 @@ int sdhci_msm_ice_init(struct sdhci_host *host)
			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;
@@ -227,6 +313,10 @@ int sdhci_msm_ice_reset(struct sdhci_host *host)
		}
	}

	/* 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);
+18 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
 * 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
@@ -37,6 +37,18 @@
#define CORE_VENDOR_SPEC_ICE_CTRL_INFO_2_n	0x308
#define CORE_VENDOR_SPEC_ICE_CTRL_INFO_3_n	0x30C

/* ICE3.0 register which got added cmdq reg space */
#define ICE_CQ_CAPABILITIES	0x04
#define ICE_HCI_SUPPORT		(1 << 28)
#define ICE_CQ_CONFIG		0x08
#define CRYPTO_GENERAL_ENABLE	(1 << 1)

/* ICE3.0 register which got added hc reg space */
#define HC_VENDOR_SPECIFIC_FUNC4	0x260
#define DISABLE_CRYPTO			(1 << 15)
#define HC_VENDOR_SPECIFIC_ICE_CTRL	0x800
#define ICE_SW_RST_EN			(1 << 0)

/* SDHCI MSM ICE CTRL Info register offset */
enum {
	OFFSET_SDHCI_MSM_ICE_CTRL_INFO_BYPASS     = 0,
@@ -76,6 +88,11 @@ enum {
	SDHCI_MSM_ICE_STATE_SUSPENDED  = 2,
};

/* crypto context fields in cmdq data command task descriptor */
#define DATA_UNIT_NUM(x)	(((u64)(x) & 0xFFFFFFFF) << 0)
#define CRYPTO_CONFIG_INDEX(x)	(((u64)(x) & 0xFF) << 32)
#define CRYPTO_ENABLE(x)	(((u64)(x) & 0x1) << 47)

#ifdef CONFIG_MMC_SDHCI_MSM_ICE
int sdhci_msm_ice_get_dev(struct sdhci_host *host);
int sdhci_msm_ice_init(struct sdhci_host *host);
+3 −0
Original line number Diff line number Diff line
@@ -4116,6 +4116,9 @@ static void sdhci_set_default_hw_caps(struct sdhci_msm_host *msm_host,
		msm_host_offset->CORE_VENDOR_SPEC_CAPABILITIES0);
	/* keep track of the value in SDHCI_CAPABILITIES */
	msm_host->caps_0 = caps;

	if ((major == 1) && (minor >= 0x6b))
		msm_host->ice_hci_support = true;
}

#ifdef CONFIG_MMC_CQ_HCI
+3 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2016, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-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
@@ -174,6 +174,8 @@ struct sdhci_msm_ice_data {
struct sdhci_msm_host {
	struct platform_device	*pdev;
	void __iomem *core_mem;    /* MSM SDCC mapped address */
	void __iomem *cryptoio;    /* ICE HCI mapped address */
	bool ice_hci_support;
	int	pwr_irq;	/* power irq */
	struct clk	 *clk;     /* main SD/MMC bus clock */
	struct clk	 *pclk;    /* SDHC peripheral bus clock */