diff --git a/drivers/mmc/host/sdhci-msm-ice.c b/drivers/mmc/host/sdhci-msm-ice.c index c3ceca68ce19..a6ef06aa6f1d 100644 --- a/drivers/mmc/host/sdhci-msm-ice.c +++ b/drivers/mmc/host/sdhci-msm-ice.c @@ -292,7 +292,40 @@ void sdhci_msm_ice_hci_update_cmdq_cfg(u64 dun, unsigned int bypass, *ice_ctx = DATA_UNIT_NUM(dun) | CRYPTO_CONFIG_INDEX(key_index) | CRYPTO_ENABLE(!bypass); +} +static +void sdhci_msm_ice_hci_update_noncq_cfg(struct sdhci_host *host, + u64 dun, unsigned int bypass, short key_index) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_msm_host *msm_host = pltfm_host->priv; + unsigned int crypto_params = 0; + /* + * 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 + */ + /* Configure ICE bypass mode */ + crypto_params |= + (!bypass & MASK_SDHCI_MSM_ICE_HCI_PARAM_CE) + << OFFSET_SDHCI_MSM_ICE_HCI_PARAM_CE; + /* Configure Crypto Configure Index (CCI) */ + crypto_params |= (key_index & + MASK_SDHCI_MSM_ICE_HCI_PARAM_CCI) + << OFFSET_SDHCI_MSM_ICE_HCI_PARAM_CCI; + + writel_relaxed((crypto_params & 0xFFFFFFFF), + msm_host->cryptoio + ICE_NONCQ_CRYPTO_PARAMS); + + /* Update DUN */ + writel_relaxed((dun & 0xFFFFFFFF), + msm_host->cryptoio + ICE_NONCQ_CRYPTO_DUN); + /* Ensure ICE registers are configured before issuing SDHCI request */ + mb(); } int sdhci_msm_ice_cfg(struct sdhci_host *host, struct mmc_request *mrq, @@ -327,7 +360,14 @@ int sdhci_msm_ice_cfg(struct sdhci_host *host, struct mmc_request *mrq, slot, bypass, key_index); } - sdhci_msm_ice_update_cfg(host, lba, slot, bypass, key_index); + if (msm_host->ice_hci_support) { + /* For ICE HCI / ICE3.0 */ + sdhci_msm_ice_hci_update_noncq_cfg(host, lba, bypass, + key_index); + } else { + /* For ICE versions earlier to ICE3.0 */ + sdhci_msm_ice_update_cfg(host, lba, slot, bypass, key_index); + } return 0; } diff --git a/drivers/mmc/host/sdhci-msm-ice.h b/drivers/mmc/host/sdhci-msm-ice.h index 03fe1a4517de..d8d640437522 100644 --- a/drivers/mmc/host/sdhci-msm-ice.h +++ b/drivers/mmc/host/sdhci-msm-ice.h @@ -42,6 +42,8 @@ #define ICE_HCI_SUPPORT (1 << 28) #define ICE_CQ_CONFIG 0x08 #define CRYPTO_GENERAL_ENABLE (1 << 1) +#define ICE_NONCQ_CRYPTO_PARAMS 0x70 +#define ICE_NONCQ_CRYPTO_DUN 0x74 /* ICE3.0 register which got added hc reg space */ #define HC_VENDOR_SPECIFIC_FUNC4 0x260 @@ -52,8 +54,10 @@ /* SDHCI MSM ICE CTRL Info register offset */ enum { OFFSET_SDHCI_MSM_ICE_CTRL_INFO_BYPASS = 0, - OFFSET_SDHCI_MSM_ICE_CTRL_INFO_KEY_INDEX = 0x1, - OFFSET_SDHCI_MSM_ICE_CTRL_INFO_CDU = 0x6, + OFFSET_SDHCI_MSM_ICE_CTRL_INFO_KEY_INDEX = 1, + OFFSET_SDHCI_MSM_ICE_CTRL_INFO_CDU = 6, + OFFSET_SDHCI_MSM_ICE_HCI_PARAM_CCI = 0, + OFFSET_SDHCI_MSM_ICE_HCI_PARAM_CE = 8, }; /* SDHCI MSM ICE CTRL Info register masks */ @@ -61,6 +65,8 @@ enum { MASK_SDHCI_MSM_ICE_CTRL_INFO_BYPASS = 0x1, MASK_SDHCI_MSM_ICE_CTRL_INFO_KEY_INDEX = 0x1F, MASK_SDHCI_MSM_ICE_CTRL_INFO_CDU = 0x7, + MASK_SDHCI_MSM_ICE_HCI_PARAM_CE = 0x1, + MASK_SDHCI_MSM_ICE_HCI_PARAM_CCI = 0xff }; /* SDHCI MSM ICE encryption/decryption bypass state */