linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] scsi: ufs-mediatek: Support performance mode for inline encryption engine
@ 2020-09-11  3:24 Stanley Chu
  2020-09-11  3:24 ` [PATCH 1/2] " Stanley Chu
  2020-09-11  3:24 ` [PATCH 2/2] dt-bindings: ufs-mediatek: Add mt8192-ufshci compatible string Stanley Chu
  0 siblings, 2 replies; 3+ messages in thread
From: Stanley Chu @ 2020-09-11  3:24 UTC (permalink / raw)
  To: linux-scsi, devicetree, robh+dt, robh, martin.petersen,
	avri.altman, alim.akhtar, jejb
  Cc: matthias.bgg, bvanassche, linux-mediatek, linux-arm-kernel,
	linux-kernel, kuohong.wang, peter.wang, chun-hung.wu, andy.teng,
	chaotian.jing, cc.chou, arvin.wang, HenryC.Chen, Stanley Chu

Hi Martin, Rob, Avri,

This series adds high-performance mode support for MediaTek UFS inline encryption engine.
This feature is only required in specific platforms, i.e., MT8192 series.

Please help consider this patch set in kernel v5.10.

Thanks.

Stanley Chu (2):
  scsi: ufs-mediatek: Support performance mode for inline encryption
    engine
  dt-bindings: ufs-mediatek: Add mt8192-ufshci compatible string

 .../devicetree/bindings/ufs/ufs-mediatek.txt  |   4 +-
 drivers/scsi/ufs/ufs-mediatek.c               | 178 +++++++++++++++++-
 drivers/scsi/ufs/ufs-mediatek.h               |  22 +++
 3 files changed, 197 insertions(+), 7 deletions(-)

-- 
2.18.0

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] scsi: ufs-mediatek: Support performance mode for inline encryption engine
  2020-09-11  3:24 [PATCH 0/2] scsi: ufs-mediatek: Support performance mode for inline encryption engine Stanley Chu
@ 2020-09-11  3:24 ` Stanley Chu
  2020-09-11  3:24 ` [PATCH 2/2] dt-bindings: ufs-mediatek: Add mt8192-ufshci compatible string Stanley Chu
  1 sibling, 0 replies; 3+ messages in thread
From: Stanley Chu @ 2020-09-11  3:24 UTC (permalink / raw)
  To: linux-scsi, devicetree, robh+dt, robh, martin.petersen,
	avri.altman, alim.akhtar, jejb
  Cc: matthias.bgg, bvanassche, linux-mediatek, linux-arm-kernel,
	linux-kernel, kuohong.wang, peter.wang, chun-hung.wu, andy.teng,
	chaotian.jing, cc.chou, arvin.wang, HenryC.Chen, Stanley Chu

Some MediaTek UFS platforms support high-performance mode that inline
encryption engine can be boosted while UFS is not clock-gated.

The high-performance mode will be enabled if all below conditions are
well-declaired in device tree,

1. Proper platform-specific compatible string which enables the host
   capability "UFS_MTK_CAP_BOOST_CRYPT_ENGINE".

2. "dvfsrc-vcore" node is available in this platform.

3. Clock mux and clock parents of inline encryption engine for both
   "low-power mode" and "high-performance mode".

Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/scsi/ufs/ufs-mediatek.c | 178 ++++++++++++++++++++++++++++++--
 drivers/scsi/ufs/ufs-mediatek.h |  22 ++++
 2 files changed, 194 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 3ec44dfa2567..f6250b54f0a0 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -10,6 +10,7 @@
 #include <linux/bitfield.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
@@ -44,6 +45,28 @@ static struct ufs_dev_fix ufs_mtk_dev_fixups[] = {
 	END_FIX
 };
 
+static const struct ufs_mtk_host_cfg ufs_mtk_mt8192_cfg = {
+	.caps = UFS_MTK_CAP_BOOST_CRYPT_ENGINE,
+};
+
+static const struct of_device_id ufs_mtk_of_match[] = {
+	{
+		.compatible = "mediatek,mt8183-ufshci",
+	},
+	{
+		.compatible = "mediatek,mt8192-ufshci",
+		.data = &ufs_mtk_mt8192_cfg
+	},
+	{},
+};
+
+static bool ufs_mtk_is_boost_crypt_enabled(struct ufs_hba *hba)
+{
+	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+
+	return (host->caps & UFS_MTK_CAP_BOOST_CRYPT_ENGINE);
+}
+
 static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable)
 {
 	u32 tmp;
@@ -294,6 +317,139 @@ static void ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on)
 	host->mphy_powered_on = on;
 }
 
+static int ufs_mtk_get_host_clk(struct device *dev, const char *name,
+				struct clk **clk_out)
+{
+	struct clk *clk;
+	int err = 0;
+
+	clk = devm_clk_get(dev, name);
+	if (IS_ERR(clk))
+		err = PTR_ERR(clk);
+	else
+		*clk_out = clk;
+
+	return err;
+}
+
+static void ufs_mtk_boost_crypt(struct ufs_hba *hba, bool boost)
+{
+	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+	struct ufs_mtk_crypt_cfg *cfg;
+	struct regulator *reg;
+	int volt, ret;
+
+	if (!ufs_mtk_is_boost_crypt_enabled(hba))
+		return;
+
+	cfg = host->crypt;
+	volt = cfg->vcore_volt;
+	reg = cfg->reg_vcore;
+
+	ret = clk_prepare_enable(cfg->clk_crypt_mux);
+	if (ret) {
+		dev_info(hba->dev, "clk_prepare_enable(): %d\n",
+			 ret);
+		return;
+	}
+
+	if (boost) {
+		ret = regulator_set_voltage(reg, volt, INT_MAX);
+		if (ret) {
+			dev_info(hba->dev,
+				 "failed to set vcore to %d\n", volt);
+			goto out;
+		}
+
+		ret = clk_set_parent(cfg->clk_crypt_mux,
+				     cfg->clk_crypt_perf);
+		if (ret) {
+			dev_info(hba->dev,
+				 "failed to set clk_crypt_perf\n");
+			regulator_set_voltage(reg, 0, INT_MAX);
+			goto out;
+		}
+	} else {
+		ret = clk_set_parent(cfg->clk_crypt_mux,
+				     cfg->clk_crypt_lp);
+		if (ret) {
+			dev_info(hba->dev,
+				 "failed to set clk_crypt_lp\n");
+			goto out;
+		}
+
+		ret = regulator_set_voltage(reg, 0, INT_MAX);
+		if (ret) {
+			dev_info(hba->dev,
+				 "failed to set vcore to MIN\n");
+		}
+	}
+out:
+	clk_disable_unprepare(cfg->clk_crypt_mux);
+
+	dev_info(hba->dev, "boost %d, %d\n", boost, ret);
+}
+
+static int ufs_mtk_init_host_clk(struct ufs_hba *hba, const char *name,
+				 struct clk **clk)
+{
+	int ret;
+
+	ret = ufs_mtk_get_host_clk(hba->dev, name, clk);
+	if (ret) {
+		dev_info(hba->dev, "%s: failed to get %s: %d", __func__,
+			 name, ret);
+	}
+
+	return ret;
+}
+
+static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
+{
+	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
+	struct ufs_mtk_crypt_cfg *cfg;
+	struct device *dev = hba->dev;
+	struct regulator *reg;
+
+	host->caps = host->cfg->caps;
+
+	if (!ufs_mtk_is_boost_crypt_enabled(hba))
+		return;
+
+	host->crypt = devm_kzalloc(dev, sizeof(*(host->crypt)),
+				   GFP_KERNEL);
+	if (!host->crypt)
+		goto disable_caps;
+
+	reg = devm_regulator_get_optional(dev, "dvfsrc-vcore");
+	if (IS_ERR(reg)) {
+		dev_info(dev, "failed to get dvfsrc-vcore: %ld",
+			 PTR_ERR(reg));
+		goto disable_caps;
+	}
+
+	cfg = host->crypt;
+	if (ufs_mtk_init_host_clk(hba, "crypt_mux",
+				  &cfg->clk_crypt_mux))
+		goto disable_caps;
+
+	if (ufs_mtk_init_host_clk(hba, "crypt_lp",
+				  &cfg->clk_crypt_lp))
+		goto disable_caps;
+
+	if (ufs_mtk_init_host_clk(hba, "crypt_perf",
+				  &cfg->clk_crypt_perf))
+		goto disable_caps;
+
+	cfg->reg_vcore = reg;
+	cfg->vcore_volt = 600000;
+	dev_info(dev, "caps: boost-crypt");
+	return;
+
+disable_caps:
+	host->caps &= ~UFS_MTK_CAP_BOOST_CRYPT_ENGINE;
+}
+
 /**
  * ufs_mtk_setup_clocks - enables/disable clocks
  * @hba: host controller instance
@@ -336,12 +492,14 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
 		}
 
 		if (clk_pwr_off) {
+			ufs_mtk_boost_crypt(hba, on);
 			ufs_mtk_setup_ref_clk(hba, on);
 			ufs_mtk_mphy_power_on(hba, on);
 		}
 	} else if (on && status == POST_CHANGE) {
 		ufs_mtk_mphy_power_on(hba, on);
 		ufs_mtk_setup_ref_clk(hba, on);
+		ufs_mtk_boost_crypt(hba, on);
 	}
 
 	return ret;
@@ -359,8 +517,9 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
  */
 static int ufs_mtk_init(struct ufs_hba *hba)
 {
-	struct ufs_mtk_host *host;
+	const struct of_device_id *id;
 	struct device *dev = hba->dev;
+	struct ufs_mtk_host *host;
 	int err = 0;
 
 	host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
@@ -373,6 +532,18 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 	host->hba = hba;
 	ufshcd_set_variant(hba, host);
 
+	/* Get host capability and platform data */
+	id = of_match_device(ufs_mtk_of_match, dev);
+	if (!id) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	if (id->data) {
+		host->cfg = (struct ufs_mtk_host_cfg *)id->data;
+		ufs_mtk_init_host_caps(hba);
+	}
+
 	err = ufs_mtk_bind_mphy(hba);
 	if (err)
 		goto out_variant_clear;
@@ -782,11 +953,6 @@ static int ufs_mtk_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static const struct of_device_id ufs_mtk_of_match[] = {
-	{ .compatible = "mediatek,mt8183-ufshci"},
-	{},
-};
-
 static const struct dev_pm_ops ufs_mtk_pm_ops = {
 	.suspend         = ufshcd_pltfrm_suspend,
 	.resume          = ufshcd_pltfrm_resume,
diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h
index 5c32d5f52759..2b6a1312c9bc 100644
--- a/drivers/scsi/ufs/ufs-mediatek.h
+++ b/drivers/scsi/ufs/ufs-mediatek.h
@@ -89,9 +89,31 @@ enum {
 	TX_CLK_GATE_EN          = 3,
 };
 
+/*
+ * Host capability
+ */
+enum ufs_mtk_host_caps {
+	UFS_MTK_CAP_BOOST_CRYPT_ENGINE         = 1 << 0,
+};
+
+struct ufs_mtk_crypt_cfg {
+	struct regulator *reg_vcore;
+	struct clk *clk_crypt_perf;
+	struct clk *clk_crypt_mux;
+	struct clk *clk_crypt_lp;
+	int vcore_volt;
+};
+
+struct ufs_mtk_host_cfg {
+	enum ufs_mtk_host_caps caps;
+};
+
 struct ufs_mtk_host {
 	struct ufs_hba *hba;
 	struct phy *mphy;
+	struct ufs_mtk_host_cfg *cfg;
+	struct ufs_mtk_crypt_cfg *crypt;
+	enum ufs_mtk_host_caps caps;
 	struct reset_control *hci_reset;
 	struct reset_control *unipro_reset;
 	struct reset_control *crypto_reset;
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] dt-bindings: ufs-mediatek: Add mt8192-ufshci compatible string
  2020-09-11  3:24 [PATCH 0/2] scsi: ufs-mediatek: Support performance mode for inline encryption engine Stanley Chu
  2020-09-11  3:24 ` [PATCH 1/2] " Stanley Chu
@ 2020-09-11  3:24 ` Stanley Chu
  1 sibling, 0 replies; 3+ messages in thread
From: Stanley Chu @ 2020-09-11  3:24 UTC (permalink / raw)
  To: linux-scsi, devicetree, robh+dt, robh, martin.petersen,
	avri.altman, alim.akhtar, jejb
  Cc: matthias.bgg, bvanassche, linux-mediatek, linux-arm-kernel,
	linux-kernel, kuohong.wang, peter.wang, chun-hung.wu, andy.teng,
	chaotian.jing, cc.chou, arvin.wang, HenryC.Chen, Stanley Chu

Add "mediatek,mt8192-ufshci" compatible string to for MediaTek
UFS host controller present on MT8192 chipsets.

Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 Documentation/devicetree/bindings/ufs/ufs-mediatek.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/ufs/ufs-mediatek.txt b/Documentation/devicetree/bindings/ufs/ufs-mediatek.txt
index 72aab8547308..63a953b672d2 100644
--- a/Documentation/devicetree/bindings/ufs/ufs-mediatek.txt
+++ b/Documentation/devicetree/bindings/ufs/ufs-mediatek.txt
@@ -9,7 +9,9 @@ contain a phandle reference to UFS M-PHY node.
 Required properties for UFS nodes:
 - compatible         : Compatible list, contains the following controller:
                        "mediatek,mt8183-ufshci" for MediaTek UFS host controller
-                       present on MT81xx chipsets.
+                       present on MT8183 chipsets.
+                       "mediatek,mt8192-ufshci" for MediaTek UFS host controller
+                       present on MT8192 chipsets.
 - reg                : Address and length of the UFS register set.
 - phys               : phandle to m-phy.
 - clocks             : List of phandle and clock specifier pairs.
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-09-11  3:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-11  3:24 [PATCH 0/2] scsi: ufs-mediatek: Support performance mode for inline encryption engine Stanley Chu
2020-09-11  3:24 ` [PATCH 1/2] " Stanley Chu
2020-09-11  3:24 ` [PATCH 2/2] dt-bindings: ufs-mediatek: Add mt8192-ufshci compatible string Stanley Chu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).