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

Commit 2df488a1 authored by Veerabhadrarao Badiganti's avatar Veerabhadrarao Badiganti
Browse files

mmc: cmdq_hci: ice: Changes for supporting ICE HCI in CMDQ mode



On SDHC v5.0 onwards, SDHC includes the inline interface
for cryptographic operations which is ICE HCI.

This patch includes the driver changes for supporting crypto
operations with ICE HCI in cmdq mode.

Change-Id: I618a0a4b7356f2f19c31d67fca1664daa51b09f9
Signed-off-by: default avatarVeerabhadrarao Badiganti <vbadigan@codeaurora.org>
parent a60300ce
Loading
Loading
Loading
Loading
+44 −2
Original line number Diff line number Diff line
@@ -345,6 +345,7 @@ static int cmdq_enable(struct mmc_host *mmc)
{
	int err = 0;
	u32 cqcfg;
	u32 cqcap = 0;
	bool dcmd_enable;
	struct cmdq_host *cq_host = mmc_cmdq_private(mmc);

@@ -373,6 +374,18 @@ static int cmdq_enable(struct mmc_host *mmc)
	cqcfg = ((cq_host->caps & CMDQ_TASK_DESC_SZ_128 ? CQ_TASK_DESC_SZ : 0) |
			(dcmd_enable ? CQ_DCMD : 0));

	cqcap = cmdq_readl(cq_host, CQCAP);
	if (cqcap & CQCAP_CS) {
		/*
		 * In case host controller supports cryptographic operations
		 * then, it uses 128bit task descriptor. Upper 64 bits of task
		 * descriptor would be used to pass crypto specific informaton.
		 */
		cq_host->caps |= CMDQ_CAP_CRYPTO_SUPPORT |
				 CMDQ_TASK_DESC_SZ_128;
		cqcfg |= CQ_ICE_ENABLE;
	}

	cmdq_writel(cq_host, cqcfg, CQCFG);
	/* enable CQ_HOST */
	cmdq_writel(cq_host, cmdq_readl(cq_host, CQCFG) | CQ_ENABLE,
@@ -688,6 +701,30 @@ static void cmdq_prep_dcmd_desc(struct mmc_host *mmc,
		upper_32_bits(*task_desc));
}

static inline
void cmdq_prep_crypto_desc(struct cmdq_host *cq_host, u64 *task_desc,
			u64 ice_ctx)
{
	u64 *ice_desc = NULL;

	if (cq_host->caps & CMDQ_CAP_CRYPTO_SUPPORT) {
		/*
		 * Get the address of ice context for the given task descriptor.
		 * ice context is present in the upper 64bits of task descriptor
		 * ice_conext_base_address = task_desc + 8-bytes
		 */
		ice_desc = (__le64 __force *)((u8 *)task_desc +
						CQ_TASK_DESC_TASK_PARAMS_SIZE);
		memset(ice_desc, 0, CQ_TASK_DESC_ICE_PARAMS_SIZE);

		/*
		 *  Assign upper 64bits data of task descritor with ice context
		 */
		if (ice_ctx)
			*ice_desc = cpu_to_le64(ice_ctx);
	}
}

static void cmdq_pm_qos_vote(struct sdhci_host *host, struct mmc_request *mrq)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -711,6 +748,7 @@ static int cmdq_request(struct mmc_host *mmc, struct mmc_request *mrq)
	u32 tag = mrq->cmdq_req->tag;
	struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc);
	struct sdhci_host *host = mmc_priv(mmc);
	u64 ice_ctx = 0;

	if (!cq_host->enabled) {
		pr_err("%s: CMDQ host not enabled yet !!!\n",
@@ -730,7 +768,7 @@ static int cmdq_request(struct mmc_host *mmc, struct mmc_request *mrq)
	}

	if (cq_host->ops->crypto_cfg) {
		err = cq_host->ops->crypto_cfg(mmc, mrq, tag);
		err = cq_host->ops->crypto_cfg(mmc, mrq, tag, &ice_ctx);
		if (err) {
			pr_err("%s: failed to configure crypto: err %d tag %d\n",
					mmc_hostname(mmc), err, tag);
@@ -743,6 +781,9 @@ static int cmdq_request(struct mmc_host *mmc, struct mmc_request *mrq)
	cmdq_prep_task_desc(mrq, &data, 1,
			    (mrq->cmdq_req->cmdq_req_flags & QBR));
	*task_desc = cpu_to_le64(data);

	cmdq_prep_crypto_desc(cq_host, task_desc, ice_ctx);

	cmdq_log_task_desc_history(cq_host, *task_desc, false);

	err = cmdq_prep_tran_desc(mrq, cq_host, tag);
@@ -787,7 +828,8 @@ static void cmdq_finish_data(struct mmc_host *mmc, unsigned int tag)
			    CMDQ_SEND_STATUS_TRIGGER, CQ_VENDOR_CFG);

	cmdq_runtime_pm_put(cq_host);
	if (cq_host->ops->crypto_cfg_reset)
	if (!(cq_host->caps & CMDQ_CAP_CRYPTO_SUPPORT) &&
			cq_host->ops->crypto_cfg_reset)
		cq_host->ops->crypto_cfg_reset(mmc, tag);
	mrq->done(mrq);
}
+7 −1
Original line number Diff line number Diff line
@@ -18,11 +18,13 @@
#define CQVER		0x00
/* capabilities */
#define CQCAP		0x04
#define CQCAP_CS	(1 << 28)
/* configuration */
#define CQCFG		0x08
#define CQ_DCMD		0x00001000
#define CQ_TASK_DESC_SZ 0x00000100
#define CQ_ENABLE	0x00000001
#define CQ_ICE_ENABLE	0x00000002

/* control */
#define CQCTL		0x0C
@@ -144,6 +146,9 @@
#define CQ_VENDOR_CFG	0x100
#define CMDQ_SEND_STATUS_TRIGGER (1 << 31)

#define CQ_TASK_DESC_TASK_PARAMS_SIZE	8
#define CQ_TASK_DESC_ICE_PARAMS_SIZE	8

struct task_history {
	u64 task;
	bool is_dcmd;
@@ -161,6 +166,7 @@ struct cmdq_host {
	u32 dcmd_slot;
	u32 caps;
#define CMDQ_TASK_DESC_SZ_128 0x1
#define CMDQ_CAP_CRYPTO_SUPPORT 0x2

	u32 quirks;
#define CMDQ_QUIRK_SHORT_TXFR_DESC_SZ 0x1
@@ -208,7 +214,7 @@ struct cmdq_host_ops {
	void (*enhanced_strobe_mask)(struct mmc_host *mmc, bool set);
	int (*reset)(struct mmc_host *mmc);
	int (*crypto_cfg)(struct mmc_host *mmc, struct mmc_request *mrq,
				u32 slot);
				u32 slot, u64 *ice_ctx);
	void (*crypto_cfg_reset)(struct mmc_host *mmc, unsigned int slot);
	void (*post_cqe_halt)(struct mmc_host *mmc);
};
+27 −1
Original line number Diff line number Diff line
@@ -276,6 +276,25 @@ void sdhci_msm_ice_update_cfg(struct sdhci_host *host, u64 lba,
	mb();
}

static inline
void sdhci_msm_ice_hci_update_cmdq_cfg(u64 dun, unsigned int bypass,
				short key_index, u64 *ice_ctx)
{
	/*
	 * The naming convention got changed between ICE2.0 and ICE3.0
	 * registers fields. Below is the equivalent names for
	 * ICE3.0 Vs ICE2.0:
	 *   Data Unit Number(DUN) == Logical Base address(LBA)
	 *   Crypto Configuration index (CCI) == Key Index
	 *   Crypto Enable (CE) == !BYPASS
	 */
	 if (ice_ctx)
		*ice_ctx = DATA_UNIT_NUM(dun) |
			CRYPTO_CONFIG_INDEX(key_index) |
			CRYPTO_ENABLE(!bypass);

}

int sdhci_msm_ice_cfg(struct sdhci_host *host, struct mmc_request *mrq,
			u32 slot)
{
@@ -344,7 +363,14 @@ int sdhci_msm_ice_cmdq_cfg(struct sdhci_host *host,
				slot, bypass, key_index);
	}

	if (msm_host->ice_hci_support) {
		/* For ICE HCI / ICE3.0 */
		sdhci_msm_ice_hci_update_cmdq_cfg(lba, bypass, key_index,
						ice_ctx);
	} else {
		/* For ICE versions earlier to ICE3.0 */
		sdhci_msm_ice_update_cfg(host, lba, slot, bypass, key_index);
	}
	return 0;
}

+4 −3
Original line number Diff line number Diff line
@@ -3632,7 +3632,7 @@ static void sdhci_cmdq_clear_set_dumpregs(struct mmc_host *mmc, bool set)
		host->ops->clear_set_dumpregs(host, set);
}
static int sdhci_cmdq_crypto_cfg(struct mmc_host *mmc,
		struct mmc_request *mrq, u32 slot)
		struct mmc_request *mrq, u32 slot, u64 *ice_ctx)
{
	struct sdhci_host *host = mmc_priv(mmc);
	int err = 0;
@@ -3651,7 +3651,8 @@ static int sdhci_cmdq_crypto_cfg(struct mmc_host *mmc,
	}

	if (host->ops->crypto_engine_cmdq_cfg) {
		err = host->ops->crypto_engine_cmdq_cfg(host, mrq, slot, NULL);
		err = host->ops->crypto_engine_cmdq_cfg(host, mrq,
				slot, ice_ctx);
		if (err) {
			pr_err("%s: failed to configure crypto\n",
					mmc_hostname(host->mmc));
@@ -3722,7 +3723,7 @@ static void sdhci_cmdq_clear_set_dumpregs(struct mmc_host *mmc, bool set)

}
static int sdhci_cmdq_crypto_cfg(struct mmc_host *mmc,
		struct mmc_request *mrq, u32 slot)
		struct mmc_request *mrq, u32 slot, u64 *ice_ctx)
{
	return 0;
}