Loading drivers/mmc/host/sdhci-msm-ice.c +90 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); Loading @@ -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; Loading Loading @@ -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); Loading drivers/mmc/host/sdhci-msm-ice.h +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 Loading Loading @@ -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, Loading Loading @@ -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); Loading drivers/mmc/host/sdhci-msm.c +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading drivers/mmc/host/sdhci-msm.h +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 Loading Loading @@ -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 */ Loading Loading
drivers/mmc/host/sdhci-msm-ice.c +90 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); Loading @@ -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; Loading Loading @@ -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); Loading
drivers/mmc/host/sdhci-msm-ice.h +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 Loading Loading @@ -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, Loading Loading @@ -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); Loading
drivers/mmc/host/sdhci-msm.c +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
drivers/mmc/host/sdhci-msm.h +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 Loading Loading @@ -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 */ Loading