Merge "mmc: sdhci-msm-ice: Factor out update config from sdhci_msm_ice_cfg"
diff --git a/drivers/mmc/host/cmdq_hci.c b/drivers/mmc/host/cmdq_hci.c
index bfe1242..7c3638c 100644
--- a/drivers/mmc/host/cmdq_hci.c
+++ b/drivers/mmc/host/cmdq_hci.c
@@ -729,6 +729,15 @@
goto ring_doorbell;
}
+ if (cq_host->ops->crypto_cfg) {
+ err = cq_host->ops->crypto_cfg(mmc, mrq, tag);
+ if (err) {
+ pr_err("%s: failed to configure crypto: err %d tag %d\n",
+ mmc_hostname(mmc), err, tag);
+ goto out;
+ }
+ }
+
task_desc = (__le64 __force *)get_desc(cq_host, tag);
cmdq_prep_task_desc(mrq, &data, 1,
@@ -778,6 +787,8 @@
CMDQ_SEND_STATUS_TRIGGER, CQ_VENDOR_CFG);
cmdq_runtime_pm_put(cq_host);
+ if (cq_host->ops->crypto_cfg_reset)
+ cq_host->ops->crypto_cfg_reset(mmc, tag);
mrq->done(mrq);
}
diff --git a/drivers/mmc/host/cmdq_hci.h b/drivers/mmc/host/cmdq_hci.h
index 5347b3ab..8e9f765 100644
--- a/drivers/mmc/host/cmdq_hci.h
+++ b/drivers/mmc/host/cmdq_hci.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, 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
@@ -208,6 +208,9 @@
void (*enhanced_strobe_mask)(struct mmc_host *mmc, bool set);
int (*reset)(struct mmc_host *mmc);
void (*post_cqe_halt)(struct mmc_host *mmc);
+ int (*crypto_cfg)(struct mmc_host *mmc, struct mmc_request *mrq,
+ u32 slot);
+ void (*crypto_cfg_reset)(struct mmc_host *mmc, unsigned int slot);
};
static inline void cmdq_writel(struct cmdq_host *host, u32 val, int reg)
diff --git a/drivers/mmc/host/sdhci-msm-ice.c b/drivers/mmc/host/sdhci-msm-ice.c
index ba6e51c..acc4ae0 100644
--- a/drivers/mmc/host/sdhci-msm-ice.c
+++ b/drivers/mmc/host/sdhci-msm-ice.c
@@ -1,5 +1,5 @@
/*
- * 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
@@ -13,19 +13,6 @@
#include "sdhci-msm-ice.h"
-static void sdhci_msm_ice_success_cb(void *host_ctrl,
- enum ice_event_completion evt)
-{
- struct sdhci_msm_host *msm_host = (struct sdhci_msm_host *)host_ctrl;
-
- if ((msm_host->ice.state == SDHCI_MSM_ICE_STATE_DISABLED &&
- evt == ICE_INIT_COMPLETION) || (msm_host->ice.state ==
- SDHCI_MSM_ICE_STATE_SUSPENDED && evt == ICE_RESUME_COMPLETION))
- msm_host->ice.state = SDHCI_MSM_ICE_STATE_ACTIVE;
-
- complete(&msm_host->ice.async_done);
-}
-
static void sdhci_msm_ice_error_cb(void *host_ctrl, u32 error)
{
struct sdhci_msm_host *msm_host = (struct sdhci_msm_host *)host_ctrl;
@@ -35,8 +22,6 @@
if (msm_host->ice.state == SDHCI_MSM_ICE_STATE_ACTIVE)
msm_host->ice.state = SDHCI_MSM_ICE_STATE_DISABLED;
-
- complete(&msm_host->ice.async_done);
}
static struct platform_device *sdhci_msm_ice_get_pdevice(struct device *dev)
@@ -194,34 +179,69 @@
struct sdhci_msm_host *msm_host = pltfm_host->priv;
int err = 0;
- init_completion(&msm_host->ice.async_done);
- if (msm_host->ice.vops->config) {
+ 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_success_cb,
sdhci_msm_ice_error_cb);
if (err) {
pr_err("%s: ice init err %d\n",
mmc_hostname(host->mmc), err);
- return 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;
}
- if (!wait_for_completion_timeout(&msm_host->ice.async_done,
- msecs_to_jiffies(SDHCI_MSM_ICE_COMPLETION_TIMEOUT_MS))) {
- pr_err("%s: ice init timedout after %d ms\n",
- mmc_hostname(host->mmc),
- SDHCI_MSM_ICE_COMPLETION_TIMEOUT_MS);
- sdhci_msm_ice_print_regs(host);
- return -ETIMEDOUT;
- }
+out:
+ return err;
+}
- 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;
- }
- return 0;
+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);
+}
+
+static
+void sdhci_msm_ice_update_cfg(struct sdhci_host *host, u64 lba,
+ u32 slot, unsigned int bypass, short key_index)
+{
+ unsigned int ctrl_info_val = 0;
+
+ /* Configure ICE index */
+ ctrl_info_val =
+ (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();
}
int sdhci_msm_ice_cfg(struct sdhci_host *host, struct mmc_request *mrq,
@@ -232,7 +252,6 @@
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;
@@ -247,9 +266,10 @@
req = mrq->req;
if (req) {
lba = req->__sector;
- if (msm_host->ice.vops->config) {
- err = msm_host->ice.vops->config(msm_host->ice.pdev,
- req, &ice_set);
+ 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);
@@ -274,32 +294,8 @@
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();
+ sdhci_msm_ice_update_cfg(host, lba, slot, bypass,
+ ice_set.crypto_data.key_index);
return 0;
}
@@ -315,25 +311,19 @@
return -EINVAL;
}
- init_completion(&msm_host->ice.async_done);
-
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 (!wait_for_completion_timeout(&msm_host->ice.async_done,
- msecs_to_jiffies(SDHCI_MSM_ICE_COMPLETION_TIMEOUT_MS))) {
- pr_err("%s: ice reset timedout after %d ms\n",
- mmc_hostname(host->mmc),
- SDHCI_MSM_ICE_COMPLETION_TIMEOUT_MS);
- sdhci_msm_ice_print_regs(host);
- return -ETIMEDOUT;
- }
+ /* 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",
@@ -356,8 +346,6 @@
return -EINVAL;
}
- init_completion(&msm_host->ice.async_done);
-
if (msm_host->ice.vops->resume) {
err = msm_host->ice.vops->resume(msm_host->ice.pdev);
if (err) {
@@ -367,20 +355,7 @@
}
}
- if (!wait_for_completion_timeout(&msm_host->ice.async_done,
- msecs_to_jiffies(SDHCI_MSM_ICE_COMPLETION_TIMEOUT_MS))) {
- pr_err("%s: ice resume timedout after %d ms\n",
- mmc_hostname(host->mmc),
- SDHCI_MSM_ICE_COMPLETION_TIMEOUT_MS);
- sdhci_msm_ice_print_regs(host);
- return -ETIMEDOUT;
- }
-
- if (msm_host->ice.state != SDHCI_MSM_ICE_STATE_ACTIVE) {
- pr_err("%s: ice is in invalid state after resume %d\n",
- mmc_hostname(host->mmc), msm_host->ice.state);
- return -EINVAL;
- }
+ msm_host->ice.state = SDHCI_MSM_ICE_STATE_ACTIVE;
return 0;
}
diff --git a/drivers/mmc/host/sdhci-msm-ice.h b/drivers/mmc/host/sdhci-msm-ice.h
index 88ef0e2..23922cf 100644
--- a/drivers/mmc/host/sdhci-msm-ice.h
+++ b/drivers/mmc/host/sdhci-msm-ice.h
@@ -17,7 +17,6 @@
#include <linux/io.h>
#include <linux/of.h>
-#include <linux/async.h>
#include <linux/blkdev.h>
#include <crypto/ice.h>
@@ -97,6 +96,7 @@
#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);
+void sdhci_msm_ice_cfg_reset(struct sdhci_host *host, u32 slot);
int sdhci_msm_ice_cfg(struct sdhci_host *host, struct mmc_request *mrq,
u32 slot);
int sdhci_msm_ice_reset(struct sdhci_host *host);
@@ -120,6 +120,11 @@
{
return 0;
}
+
+inline void sdhci_msm_ice_cfg_reset(struct sdhci_host *host, u32 slot)
+{
+}
+
inline int sdhci_msm_ice_cfg(struct sdhci_host *host,
struct mmc_request *mrq, u32 slot)
{
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 77f7c96..b6c17ec0 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -3474,6 +3474,7 @@
if (host->is_crypto_en) {
sdhci_msm_ice_get_status(host, &sts);
pr_info("%s: ICE status %x\n", mmc_hostname(host->mmc), sts);
+ sdhci_msm_ice_print_regs(host);
}
}
@@ -3483,8 +3484,14 @@
struct sdhci_msm_host *msm_host = pltfm_host->priv;
/* Set ICE core to be reset in sync with SDHC core */
- if (msm_host->ice.pdev)
- writel_relaxed(1, host->ioaddr + CORE_VENDOR_SPEC_ICE_CTRL);
+ if (msm_host->ice.pdev) {
+ if (msm_host->ice_hci_support)
+ writel_relaxed(1, host->ioaddr +
+ HC_VENDOR_SPECIFIC_ICE_CTRL);
+ else
+ writel_relaxed(1,
+ host->ioaddr + CORE_VENDOR_SPEC_ICE_CTRL);
+ }
sdhci_reset(host, mask);
}
diff --git a/drivers/mmc/host/sdhci-msm.h b/drivers/mmc/host/sdhci-msm.h
index 53a8c67..cdbaaa9 100644
--- a/drivers/mmc/host/sdhci-msm.h
+++ b/drivers/mmc/host/sdhci-msm.h
@@ -165,7 +165,6 @@
struct sdhci_msm_ice_data {
struct qcom_ice_variant_ops *vops;
- struct completion async_done;
struct platform_device *pdev;
int state;
};
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1d69a9b..3eada3b 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -3746,6 +3746,27 @@
SDHCI_INT_RESPONSE, SDHCI_INT_ENABLE);
sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS);
}
+static int sdhci_cmdq_crypto_cfg(struct mmc_host *mmc,
+ struct mmc_request *mrq, u32 slot)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+
+ if (!host->is_crypto_en)
+ return 0;
+
+ return sdhci_crypto_cfg(host, mrq, slot);
+}
+
+static void sdhci_cmdq_crypto_cfg_reset(struct mmc_host *mmc, unsigned int slot)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+
+ if (!host->is_crypto_en)
+ return;
+
+ if (host->ops->crypto_cfg_reset)
+ host->ops->crypto_cfg_reset(host, slot);
+}
#else
static void sdhci_cmdq_set_transfer_params(struct mmc_host *mmc)
{
@@ -3789,6 +3810,18 @@
static void sdhci_cmdq_post_cqe_halt(struct mmc_host *mmc)
{
+
+}
+
+static int sdhci_cmdq_crypto_cfg(struct mmc_host *mmc,
+ struct mmc_request *mrq, u32 slot)
+{
+ return 0;
+}
+
+static void sdhci_cmdq_crypto_cfg_reset(struct mmc_host *mmc, unsigned int slot)
+{
+
}
#endif
@@ -3801,6 +3834,8 @@
.enhanced_strobe_mask = sdhci_enhanced_strobe_mask,
.post_cqe_halt = sdhci_cmdq_post_cqe_halt,
.set_transfer_params = sdhci_cmdq_set_transfer_params,
+ .crypto_cfg = sdhci_cmdq_crypto_cfg,
+ .crypto_cfg_reset = sdhci_cmdq_crypto_cfg_reset,
};
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 45296d4..04e806c 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -671,6 +671,7 @@
int (*crypto_engine_cfg)(struct sdhci_host *host,
struct mmc_request *mrq, u32 slot);
int (*crypto_engine_reset)(struct sdhci_host *host);
+ void (*crypto_cfg_reset)(struct sdhci_host *host, unsigned int slot);
void (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
void (*hw_reset)(struct sdhci_host *host);
void (*adma_workaround)(struct sdhci_host *host, u32 intmask);