ufs-qcom.c (db6da59cf27b5661ced03754ae0550f8914eda9e) ufs-qcom.c (56541c7c4468a9de26d82ba6e8c10ace286f8fdd)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
4 */
5
6#include <linux/acpi.h>
7#include <linux/time.h>
8#include <linux/clk.h>
9#include <linux/delay.h>
10#include <linux/module.h>
11#include <linux/of.h>
12#include <linux/platform_device.h>
13#include <linux/phy/phy.h>
14#include <linux/gpio/consumer.h>
15#include <linux/reset-controller.h>
16#include <linux/devfreq.h>
17
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
4 */
5
6#include <linux/acpi.h>
7#include <linux/time.h>
8#include <linux/clk.h>
9#include <linux/delay.h>
10#include <linux/module.h>
11#include <linux/of.h>
12#include <linux/platform_device.h>
13#include <linux/phy/phy.h>
14#include <linux/gpio/consumer.h>
15#include <linux/reset-controller.h>
16#include <linux/devfreq.h>
17
18#include <soc/qcom/ice.h>
19
18#include <ufs/ufshcd.h>
19#include "ufshcd-pltfrm.h"
20#include <ufs/unipro.h>
21#include "ufs-qcom.h"
22#include <ufs/ufshci.h>
23#include <ufs/ufs_quirks.h>
24
25#define MCQ_QCFGPTR_MASK GENMASK(7, 0)

--- 24 unchanged lines hidden (view full) ---

50static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
51 u32 clk_cycles);
52
53static struct ufs_qcom_host *rcdev_to_ufs_host(struct reset_controller_dev *rcd)
54{
55 return container_of(rcd, struct ufs_qcom_host, rcdev);
56}
57
20#include <ufs/ufshcd.h>
21#include "ufshcd-pltfrm.h"
22#include <ufs/unipro.h>
23#include "ufs-qcom.h"
24#include <ufs/ufshci.h>
25#include <ufs/ufs_quirks.h>
26
27#define MCQ_QCFGPTR_MASK GENMASK(7, 0)

--- 24 unchanged lines hidden (view full) ---

52static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
53 u32 clk_cycles);
54
55static struct ufs_qcom_host *rcdev_to_ufs_host(struct reset_controller_dev *rcd)
56{
57 return container_of(rcd, struct ufs_qcom_host, rcdev);
58}
59
60#ifdef CONFIG_SCSI_UFS_CRYPTO
61
62static inline void ufs_qcom_ice_enable(struct ufs_qcom_host *host)
63{
64 if (host->hba->caps & UFSHCD_CAP_CRYPTO)
65 qcom_ice_enable(host->ice);
66}
67
68static int ufs_qcom_ice_init(struct ufs_qcom_host *host)
69{
70 struct ufs_hba *hba = host->hba;
71 struct device *dev = hba->dev;
72 struct qcom_ice *ice;
73
74 ice = of_qcom_ice_get(dev);
75 if (ice == ERR_PTR(-EOPNOTSUPP)) {
76 dev_warn(dev, "Disabling inline encryption support\n");
77 ice = NULL;
78 }
79
80 if (IS_ERR_OR_NULL(ice))
81 return PTR_ERR_OR_ZERO(ice);
82
83 host->ice = ice;
84 hba->caps |= UFSHCD_CAP_CRYPTO;
85
86 return 0;
87}
88
89static inline int ufs_qcom_ice_resume(struct ufs_qcom_host *host)
90{
91 if (host->hba->caps & UFSHCD_CAP_CRYPTO)
92 return qcom_ice_resume(host->ice);
93
94 return 0;
95}
96
97static inline int ufs_qcom_ice_suspend(struct ufs_qcom_host *host)
98{
99 if (host->hba->caps & UFSHCD_CAP_CRYPTO)
100 return qcom_ice_suspend(host->ice);
101
102 return 0;
103}
104
105static int ufs_qcom_ice_program_key(struct ufs_hba *hba,
106 const union ufs_crypto_cfg_entry *cfg,
107 int slot)
108{
109 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
110 union ufs_crypto_cap_entry cap;
111 bool config_enable =
112 cfg->config_enable & UFS_CRYPTO_CONFIGURATION_ENABLE;
113
114 /* Only AES-256-XTS has been tested so far. */
115 cap = hba->crypto_cap_array[cfg->crypto_cap_idx];
116 if (cap.algorithm_id != UFS_CRYPTO_ALG_AES_XTS ||
117 cap.key_size != UFS_CRYPTO_KEY_SIZE_256)
118 return -EINVAL;
119
120 if (config_enable)
121 return qcom_ice_program_key(host->ice,
122 QCOM_ICE_CRYPTO_ALG_AES_XTS,
123 QCOM_ICE_CRYPTO_KEY_SIZE_256,
124 cfg->crypto_key,
125 cfg->data_unit_size, slot);
126 else
127 return qcom_ice_evict_key(host->ice, slot);
128}
129
130#else
131
132#define ufs_qcom_ice_program_key NULL
133
134static inline void ufs_qcom_ice_enable(struct ufs_qcom_host *host)
135{
136}
137
138static int ufs_qcom_ice_init(struct ufs_qcom_host *host)
139{
140 return 0;
141}
142
143static inline int ufs_qcom_ice_resume(struct ufs_qcom_host *host)
144{
145 return 0;
146}
147
148static inline int ufs_qcom_ice_suspend(struct ufs_qcom_host *host)
149{
150 return 0;
151}
152#endif
153
58static int ufs_qcom_host_clk_get(struct device *dev,
59 const char *name, struct clk **clk_out, bool optional)
60{
61 struct clk *clk;
62 int err = 0;
63
64 clk = devm_clk_get(dev, name);
65 if (!IS_ERR(clk)) {

--- 536 unchanged lines hidden (view full) ---

602
603 /* reset the connected UFS device during power down */
604 ufs_qcom_device_reset_ctrl(hba, true);
605
606 } else if (!ufs_qcom_is_link_active(hba)) {
607 ufs_qcom_disable_lane_clks(host);
608 }
609
154static int ufs_qcom_host_clk_get(struct device *dev,
155 const char *name, struct clk **clk_out, bool optional)
156{
157 struct clk *clk;
158 int err = 0;
159
160 clk = devm_clk_get(dev, name);
161 if (!IS_ERR(clk)) {

--- 536 unchanged lines hidden (view full) ---

698
699 /* reset the connected UFS device during power down */
700 ufs_qcom_device_reset_ctrl(hba, true);
701
702 } else if (!ufs_qcom_is_link_active(hba)) {
703 ufs_qcom_disable_lane_clks(host);
704 }
705
610 return 0;
706 return ufs_qcom_ice_suspend(host);
611}
612
613static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
614{
615 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
616 struct phy *phy = host->generic_phy;
617 int err;
618

--- 229 unchanged lines hidden (view full) ---

848static void ufs_qcom_set_caps(struct ufs_hba *hba)
849{
850 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
851
852 hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING;
853 hba->caps |= UFSHCD_CAP_CLK_SCALING | UFSHCD_CAP_WB_WITH_CLK_SCALING;
854 hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
855 hba->caps |= UFSHCD_CAP_WB_EN;
707}
708
709static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
710{
711 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
712 struct phy *phy = host->generic_phy;
713 int err;
714

--- 229 unchanged lines hidden (view full) ---

944static void ufs_qcom_set_caps(struct ufs_hba *hba)
945{
946 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
947
948 hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING;
949 hba->caps |= UFSHCD_CAP_CLK_SCALING | UFSHCD_CAP_WB_WITH_CLK_SCALING;
950 hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
951 hba->caps |= UFSHCD_CAP_WB_EN;
856 hba->caps |= UFSHCD_CAP_CRYPTO;
857 hba->caps |= UFSHCD_CAP_AGGR_POWER_COLLAPSE;
858 hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND;
859
860 if (host->hw_ver.major >= 0x2) {
861 host->caps = UFS_QCOM_CAP_QUNIPRO |
862 UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE;
863 }
864}

--- 686 unchanged lines hidden (view full) ---

1551static irqreturn_t ufs_qcom_mcq_esi_handler(int irq, void *__hba)
1552{
1553 struct ufs_hba *hba = __hba;
1554 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
1555 u32 id = irq - host->esi_base;
1556 struct ufs_hw_queue *hwq = &hba->uhq[id];
1557
1558 ufshcd_mcq_write_cqis(hba, 0x1, id);
952 hba->caps |= UFSHCD_CAP_AGGR_POWER_COLLAPSE;
953 hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND;
954
955 if (host->hw_ver.major >= 0x2) {
956 host->caps = UFS_QCOM_CAP_QUNIPRO |
957 UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE;
958 }
959}

--- 686 unchanged lines hidden (view full) ---

1646static irqreturn_t ufs_qcom_mcq_esi_handler(int irq, void *__hba)
1647{
1648 struct ufs_hba *hba = __hba;
1649 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
1650 u32 id = irq - host->esi_base;
1651 struct ufs_hw_queue *hwq = &hba->uhq[id];
1652
1653 ufshcd_mcq_write_cqis(hba, 0x1, id);
1559 ufshcd_mcq_poll_cqe_nolock(hba, hwq);
1654 ufshcd_mcq_poll_cqe_lock(hba, hwq);
1560
1561 return IRQ_HANDLED;
1562}
1563
1564static int ufs_qcom_config_esi(struct ufs_hba *hba)
1565{
1566 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
1567 struct msi_desc *desc;

--- 150 unchanged lines hidden (view full) ---

1718 .restore = ufshcd_system_restore,
1719 .thaw = ufshcd_system_thaw,
1720#endif
1721};
1722
1723static struct platform_driver ufs_qcom_pltform = {
1724 .probe = ufs_qcom_probe,
1725 .remove = ufs_qcom_remove,
1655
1656 return IRQ_HANDLED;
1657}
1658
1659static int ufs_qcom_config_esi(struct ufs_hba *hba)
1660{
1661 struct ufs_qcom_host *host = ufshcd_get_variant(hba);
1662 struct msi_desc *desc;

--- 150 unchanged lines hidden (view full) ---

1813 .restore = ufshcd_system_restore,
1814 .thaw = ufshcd_system_thaw,
1815#endif
1816};
1817
1818static struct platform_driver ufs_qcom_pltform = {
1819 .probe = ufs_qcom_probe,
1820 .remove = ufs_qcom_remove,
1726 .shutdown = ufshcd_pltfrm_shutdown,
1727 .driver = {
1728 .name = "ufshcd-qcom",
1729 .pm = &ufs_qcom_pm_ops,
1730 .of_match_table = of_match_ptr(ufs_qcom_of_match),
1731 .acpi_match_table = ACPI_PTR(ufs_qcom_acpi_match),
1732 },
1733};
1734module_platform_driver(ufs_qcom_pltform);
1735
1736MODULE_LICENSE("GPL v2");
1821 .driver = {
1822 .name = "ufshcd-qcom",
1823 .pm = &ufs_qcom_pm_ops,
1824 .of_match_table = of_match_ptr(ufs_qcom_of_match),
1825 .acpi_match_table = ACPI_PTR(ufs_qcom_acpi_match),
1826 },
1827};
1828module_platform_driver(ufs_qcom_pltform);
1829
1830MODULE_LICENSE("GPL v2");