mbox series

[v5,0/6] Add dedicated Qcom ICE driver

Message ID 20230403200530.2103099-1-abel.vesa@linaro.org
Headers show
Series Add dedicated Qcom ICE driver | expand

Message

Abel Vesa April 3, 2023, 8:05 p.m. UTC
As both SDCC and UFS drivers use the ICE with duplicated implementation,
while none of the currently supported platforms make use concomitantly
of the same ICE IP block instance, the new SM8550 allows both UFS and
SDCC to do so. In order to support such scenario, there is a need for
a unified implementation and a devicetree node to be shared between
both types of storage devices. So lets drop the duplicate implementation
of the ICE from both SDCC and UFS and make it a dedicated (soc) driver.
Also, switch all UFS and SDCC devicetree nodes to use the new ICE
approach.

The v4 is here:
https://lore.kernel.org/all/20230327134734.3256974-1-abel.vesa@linaro.org/

Changes since v4:
 * dropped the SDHCI dt-bindings patch as it will be added along
   with the first use of qcom,ice property from an SDHCI DT node

See each individual patch for changelogs.

Abel Vesa (6):
  dt-bindings: crypto: Add Qualcomm Inline Crypto Engine
  dt-bindings: ufs: qcom: Add ICE phandle
  soc: qcom: Make the Qualcomm UFS/SDCC ICE a dedicated driver
  scsi: ufs: ufs-qcom: Switch to the new ICE API
  mmc: sdhci-msm: Switch to the new ICE API
  arm64: dts: qcom: sm8550: Add the Inline Crypto Engine node

 .../crypto/qcom,inline-crypto-engine.yaml     |  42 ++
 .../devicetree/bindings/ufs/qcom,ufs.yaml     |  19 +
 arch/arm64/boot/dts/qcom/sm8550.dtsi          |  10 +
 drivers/mmc/host/Kconfig                      |   2 +-
 drivers/mmc/host/sdhci-msm.c                  | 220 +++--------
 drivers/soc/qcom/Kconfig                      |   4 +
 drivers/soc/qcom/Makefile                     |   1 +
 drivers/soc/qcom/ice.c                        | 365 ++++++++++++++++++
 drivers/ufs/host/Kconfig                      |   2 +-
 drivers/ufs/host/Makefile                     |   4 +-
 drivers/ufs/host/ufs-qcom-ice.c               | 244 ------------
 drivers/ufs/host/ufs-qcom.c                   |  97 ++++-
 drivers/ufs/host/ufs-qcom.h                   |  32 +-
 include/soc/qcom/ice.h                        |  37 ++
 14 files changed, 626 insertions(+), 453 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml
 create mode 100644 drivers/soc/qcom/ice.c
 delete mode 100644 drivers/ufs/host/ufs-qcom-ice.c
 create mode 100644 include/soc/qcom/ice.h

Comments

Eric Biggers April 6, 2023, 8:22 p.m. UTC | #1
On Mon, Apr 03, 2023 at 11:05:29PM +0300, Abel Vesa wrote:
> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
> index 8ac81d57a3df..1a6e63b7af12 100644
> --- a/drivers/mmc/host/sdhci-msm.c
> +++ b/drivers/mmc/host/sdhci-msm.c
> @@ -19,6 +19,8 @@
>  #include <linux/firmware/qcom/qcom_scm.h>
>  #include <linux/regulator/consumer.h>
>  #include <linux/interconnect.h>
>  #include <linux/pinctrl/consumer.h>
>  #include <linux/reset.h>
>  
> +#include <soc/qcom/ice.h>

The include of <linux/firmware/qcom/qcom_scm.h> should be removed.

>  static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
>  			      struct cqhci_host *cq_host)
>  {
>  	struct mmc_host *mmc = msm_host->mmc;
>  	struct device *dev = mmc_dev(mmc);
> -	struct resource *res;
>  
>  	if (!(cqhci_readl(cq_host, CQHCI_CAP) & CQHCI_CAP_CS))
>  		return 0;
>  
> -	res = platform_get_resource_byname(msm_host->pdev, IORESOURCE_MEM,
> -					   "ice");
> -	if (!res) {
> -		dev_warn(dev, "ICE registers not found\n");
> -		goto disable;
> -	}
> -
> -	if (!qcom_scm_ice_available()) {
> -		dev_warn(dev, "ICE SCM interface not found\n");
> -		goto disable;
> +	msm_host->ice = of_qcom_ice_get(dev);
> +	if (msm_host->ice == ERR_PTR(-EOPNOTSUPP)) {
> +		dev_warn(dev, "Disabling inline encryption support\n");
> +		msm_host->ice = NULL;
>  	}
>  
> -	msm_host->ice_mem = devm_ioremap_resource(dev, res);
> -	if (IS_ERR(msm_host->ice_mem))
> -		return PTR_ERR(msm_host->ice_mem);
> -
> -	if (!sdhci_msm_ice_supported(msm_host))
> -		goto disable;
> +	if (IS_ERR(msm_host->ice))
> +		return PTR_ERR(msm_host->ice);
>  
>  	mmc->caps2 |= MMC_CAP2_CRYPTO;
> -	return 0;
>  
> -disable:
> -	dev_warn(dev, "Disabling inline encryption support\n");
>  	return 0;
>  }

This is sometimes setting MMC_CAP2_CRYPTO when ICE is unsupported.

BTW, it would be better to set not msm_host->ice until it's known that it will
have a valid value:

	ice = of_qcom_ice_get(dev);
	if (ice == ERR_PTR(-EOPNOTSUPP)) {
		dev_warn(dev, "Disabling inline encryption support\n");
		return 0;
	}
	if (IS_ERR_OR_NULL(ice))
		return PTR_ERR_OR_ZERO(ice);

	msm_host->ice = ice;
	mmc->caps2 |= MMC_CAP2_CRYPTO;
	return 0;

- Eric
Eric Biggers April 6, 2023, 8:34 p.m. UTC | #2
On Mon, Apr 03, 2023 at 11:05:27PM +0300, Abel Vesa wrote:
> This takes the already existing duplicated support in both ufs-qcom
> and sdhci-msm drivers and makes it a dedicated driver that can be used
> by both mentioned drivers. The reason for this is because, staring with
> SM8550, the ICE IP block is shared between UFS and SDCC, which means we
> need to probe a dedicated device and share it between those two
> consumers. So let's add the ICE dedicated driver as a soc driver.
> Platforms that already have ICE supported, will use it as a library
> as the of_qcom_ice_get will return an ICE instance created for the
> consumer device. This allows the backwards compatibility with old-style
> devicetree approach. Also, add support to HW version 4.x since it
> works out-of-the-box with the current driver. The 4.x HW version is
> found on SM8550 platform.

Can you please split up long paragraphs like this into multiple paragraphs?

> +	pdev = of_find_device_by_node(node);
> +	if (!pdev) {
> +		dev_err(dev, "Cannot find device node %s\n", node->name);
> +		ice = ERR_PTR(-EPROBE_DEFER);
> +		goto out;
> +	}
> +
> +	ice = platform_get_drvdata(pdev);
> +	if (!ice) {
> +		dev_err(dev, "Cannot get ice instance from %s\n",
> +			dev_name(&pdev->dev));
> +		platform_device_put(pdev);
> +		ice = ERR_PTR(-EPROBE_DEFER);
> +		goto out;
> +	}
> +
> +	ice->link = device_link_add(dev, &pdev->dev, DL_FLAG_AUTOREMOVE_SUPPLIER);
> +	if (!ice->link) {
> +		dev_err(&pdev->dev,
> +			"Failed to create device link to consumer %s\n",
> +			dev_name(dev));
> +		ice = ERR_PTR(-EINVAL);
> +	}

Is a call to platform_device_put() missing above?

- Eric