* [PATCH v4 0/7] Initial support for RK3576 UFS controller
@ 2024-11-04 7:31 Shawn Lin
2024-11-04 7:31 ` [PATCH v4 1/7] scsi: ufs: core: Add UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE Shawn Lin
` (6 more replies)
0 siblings, 7 replies; 20+ messages in thread
From: Shawn Lin @ 2024-11-04 7:31 UTC (permalink / raw)
To: Rob Herring, James E . J . Bottomley, Martin K . Petersen,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Heiko Stuebner,
Rafael J . Wysocki
Cc: Manivannan Sadhasivam, Alim Akhtar, Avri Altman, Bart Van Assche,
YiFeng Zhao, Liang Chen, linux-scsi, linux-rockchip, devicetree,
linux-pm, Shawn Lin
This patchset adds initial UFS controller support for RK3576 SoC.
Patch 1 adds new quirk and patch 2 is the dt-bindings. Patch 3-6 deal
with rpm and spm support in advanced suggested by Ulf. Final patch 5 is
the driver added.
Changes in v4:
- properly describe reset-gpios
- deal with power domain of rpm and spm suggested by Ulf
- Fix typo and disable clks in ufs_rockchip_remove
- remove clk_disable_unprepare(host->ref_out_clk) from
ufs_rockchip_remove
Changes in v3:
- rename the file to rockchip,rk3576-ufshc.yaml
- add description for reset-gpios
- use rockchip,rk3576-ufshc as compatible
- reword Kconfig description
- elaborate more about controller in commit msg
- use rockchip,rk3576-ufshc for compatible
- remove useless header file
- remove inline for ufshcd_is_device_present
- use usleep_range instead
- remove initialization, reverse Xmas order
- remove useless varibles
- check vops for null
- other small fixes for err path
- remove pm_runtime_set_active
- fix the active and inactive reset-gpios logic
- fix rpm_lvl and spm_lvl to 5 and move to end of probe path
- remove unnecessary system PM callbacks
- use UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE instead
of UFSHCI_QUIRK_BROKEN_HCE
Changes in v2:
- rename the file
- add reset-gpios
Shawn Lin (6):
scsi: ufs: core: Add UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE
dt-bindings: ufs: Document Rockchip UFS host controller
soc: rockchip: add header for suspend mode SIP interface
pmdomain: rockchip: Add smc call to inform firmware
PM: wakeup: Add device_clr_wakeup_path()
scsi: ufs: rockchip: initial support for UFS
Ulf Hansson (1):
pmdomain: core: Introduce dev_pm_genpd_rpm_always_on()
.../bindings/ufs/rockchip,rk3576-ufshc.yaml | 105 +++++++
drivers/pmdomain/core.c | 34 +++
drivers/pmdomain/rockchip/pm-domains.c | 7 +
drivers/ufs/core/ufshcd.c | 17 ++
drivers/ufs/host/Kconfig | 12 +
drivers/ufs/host/Makefile | 1 +
drivers/ufs/host/ufs-rockchip.c | 340 +++++++++++++++++++++
drivers/ufs/host/ufs-rockchip.h | 51 ++++
include/linux/pm_domain.h | 7 +
include/linux/pm_wakeup.h | 7 +
include/soc/rockchip/rockchip_sip.h | 3 +
include/ufs/ufshcd.h | 6 +
12 files changed, 590 insertions(+)
create mode 100644 Documentation/devicetree/bindings/ufs/rockchip,rk3576-ufshc.yaml
create mode 100644 drivers/ufs/host/ufs-rockchip.c
create mode 100644 drivers/ufs/host/ufs-rockchip.h
--
2.7.4
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v4 1/7] scsi: ufs: core: Add UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE
2024-11-04 7:31 [PATCH v4 0/7] Initial support for RK3576 UFS controller Shawn Lin
@ 2024-11-04 7:31 ` Shawn Lin
2024-11-07 15:51 ` Manivannan Sadhasivam
2024-11-04 7:31 ` [PATCH v4 2/7] dt-bindings: ufs: Document Rockchip UFS host controller Shawn Lin
` (5 subsequent siblings)
6 siblings, 1 reply; 20+ messages in thread
From: Shawn Lin @ 2024-11-04 7:31 UTC (permalink / raw)
To: Rob Herring, James E . J . Bottomley, Martin K . Petersen,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Heiko Stuebner,
Rafael J . Wysocki
Cc: Manivannan Sadhasivam, Alim Akhtar, Avri Altman, Bart Van Assche,
YiFeng Zhao, Liang Chen, linux-scsi, linux-rockchip, devicetree,
linux-pm, Shawn Lin
HCE on Rockchip SoC is different from both of ufshcd_hba_execute_hce()
and UFSHCI_QUIRK_BROKEN_HCE case. It need to do dme_reset and dme_enable
after enabling HCE. So in order not to abuse UFSHCI_QUIRK_BROKEN_HCE, add
a new quirk UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE, to deal with that
limitation.
Suggested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
Changes in v4:
- fix typo
Changes in v3: None
Changes in v2: None
drivers/ufs/core/ufshcd.c | 17 +++++++++++++++++
include/ufs/ufshcd.h | 6 ++++++
2 files changed, 23 insertions(+)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 7cab1031..4084bf9 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -4819,6 +4819,7 @@ static int ufshcd_hba_execute_hce(struct ufs_hba *hba)
{
int retry_outer = 3;
int retry_inner;
+ int ret;
start:
if (ufshcd_is_hba_active(hba))
@@ -4865,6 +4866,22 @@ static int ufshcd_hba_execute_hce(struct ufs_hba *hba)
/* enable UIC related interrupts */
ufshcd_enable_intr(hba, UFSHCD_UIC_MASK);
+ /*
+ * Do dme_reset and dme_enable if a UFS host controller needs
+ * this procedure to actually finish HCE.
+ */
+ if (hba->quirks & UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE) {
+ ret = ufshcd_dme_reset(hba);
+ if (!ret) {
+ ret = ufshcd_dme_enable(hba);
+ if (ret)
+ dev_err(hba->dev,
+ "Failed to do dme_enable after HCE.\n");
+ } else {
+ dev_err(hba->dev, "Failed to do dme_reset after HCE.\n");
+ }
+ }
+
ufshcd_vops_hce_enable_notify(hba, POST_CHANGE);
return 0;
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index a95282b..e939af8 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -685,6 +685,12 @@ enum ufshcd_quirks {
* single doorbell mode.
*/
UFSHCD_QUIRK_BROKEN_LSDBS_CAP = 1 << 25,
+
+ /*
+ * This quirk needs to be enabled if host controller need to
+ * do dme_reset and dme_enable after hce.
+ */
+ UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE = 1 << 26,
};
enum ufshcd_caps {
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v4 2/7] dt-bindings: ufs: Document Rockchip UFS host controller
2024-11-04 7:31 [PATCH v4 0/7] Initial support for RK3576 UFS controller Shawn Lin
2024-11-04 7:31 ` [PATCH v4 1/7] scsi: ufs: core: Add UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE Shawn Lin
@ 2024-11-04 7:31 ` Shawn Lin
2024-11-07 15:42 ` Manivannan Sadhasivam
2024-11-04 7:31 ` [PATCH v4 3/7] soc: rockchip: add header for suspend mode SIP interface Shawn Lin
` (4 subsequent siblings)
6 siblings, 1 reply; 20+ messages in thread
From: Shawn Lin @ 2024-11-04 7:31 UTC (permalink / raw)
To: Rob Herring, James E . J . Bottomley, Martin K . Petersen,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Heiko Stuebner,
Rafael J . Wysocki
Cc: Manivannan Sadhasivam, Alim Akhtar, Avri Altman, Bart Van Assche,
YiFeng Zhao, Liang Chen, linux-scsi, linux-rockchip, devicetree,
linux-pm, Shawn Lin
Document Rockchip UFS host controller for RK3576 SoC.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
Changes in v4:
- properly describe reset-gpios
Changes in v3:
- rename the file to rockchip,rk3576-ufshc.yaml
- add description for reset-gpios
- use rockchip,rk3576-ufshc as compatible
Changes in v2:
- rename the file
- add reset-gpios
.../bindings/ufs/rockchip,rk3576-ufshc.yaml | 105 +++++++++++++++++++++
1 file changed, 105 insertions(+)
create mode 100644 Documentation/devicetree/bindings/ufs/rockchip,rk3576-ufshc.yaml
diff --git a/Documentation/devicetree/bindings/ufs/rockchip,rk3576-ufshc.yaml b/Documentation/devicetree/bindings/ufs/rockchip,rk3576-ufshc.yaml
new file mode 100644
index 0000000..bc4c3de
--- /dev/null
+++ b/Documentation/devicetree/bindings/ufs/rockchip,rk3576-ufshc.yaml
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ufs/rockchip,rk3576-ufshc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip UFS Host Controller
+
+maintainers:
+ - Shawn Lin <shawn.lin@rock-chips.com>
+
+allOf:
+ - $ref: ufs-common.yaml
+
+properties:
+ compatible:
+ const: rockchip,rk3576-ufshc
+
+ reg:
+ maxItems: 5
+
+ reg-names:
+ items:
+ - const: hci
+ - const: mphy
+ - const: hci_grf
+ - const: mphy_grf
+ - const: hci_apb
+
+ clocks:
+ maxItems: 4
+
+ clock-names:
+ items:
+ - const: core
+ - const: pclk
+ - const: pclk_mphy
+ - const: ref_out
+
+ power-domains:
+ maxItems: 1
+
+ resets:
+ maxItems: 4
+
+ reset-names:
+ items:
+ - const: biu
+ - const: sys
+ - const: ufs
+ - const: grf
+
+ reset-gpios:
+ maxItems: 1
+ description: |
+ GPIO specifiers for host to reset the whole UFS device including PHY and
+ memory. This gpio is active low and should choose the one whose high output
+ voltage is lower than 1.5V based on the UFS spec.
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - clock-names
+ - interrupts
+ - power-domains
+ - resets
+ - reset-names
+ - reset-gpios
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/rockchip,rk3576-cru.h>
+ #include <dt-bindings/reset/rockchip,rk3576-cru.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/power/rockchip,rk3576-power.h>
+ #include <dt-bindings/pinctrl/rockchip.h>
+ #include <dt-bindings/gpio/gpio.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ ufs: ufs@2a2d0000 {
+ compatible = "rockchip,rk3576-ufshc";
+ reg = <0x0 0x2a2d0000 0x0 0x10000>,
+ <0x0 0x2b040000 0x0 0x10000>,
+ <0x0 0x2601f000 0x0 0x1000>,
+ <0x0 0x2603c000 0x0 0x1000>,
+ <0x0 0x2a2e0000 0x0 0x10000>;
+ reg-names = "hci", "mphy", "hci_grf", "mphy_grf", "hci_apb";
+ clocks = <&cru ACLK_UFS_SYS>, <&cru PCLK_USB_ROOT>, <&cru PCLK_MPHY>,
+ <&cru CLK_REF_UFS_CLKOUT>;
+ clock-names = "core", "pclk", "pclk_mphy", "ref_out";
+ interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&power RK3576_PD_USB>;
+ resets = <&cru SRST_A_UFS_BIU>, <&cru SRST_A_UFS_SYS>, <&cru SRST_A_UFS>,
+ <&cru SRST_P_UFS_GRF>;
+ reset-names = "biu", "sys", "ufs", "grf";
+ reset-gpios = <&gpio4 RK_PD0 GPIO_ACTIVE_LOW>;
+ };
+ };
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v4 3/7] soc: rockchip: add header for suspend mode SIP interface
2024-11-04 7:31 [PATCH v4 0/7] Initial support for RK3576 UFS controller Shawn Lin
2024-11-04 7:31 ` [PATCH v4 1/7] scsi: ufs: core: Add UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE Shawn Lin
2024-11-04 7:31 ` [PATCH v4 2/7] dt-bindings: ufs: Document Rockchip UFS host controller Shawn Lin
@ 2024-11-04 7:31 ` Shawn Lin
2024-11-04 7:31 ` [PATCH v4 4/7] pmdomain: core: Introduce dev_pm_genpd_rpm_always_on() Shawn Lin
` (3 subsequent siblings)
6 siblings, 0 replies; 20+ messages in thread
From: Shawn Lin @ 2024-11-04 7:31 UTC (permalink / raw)
To: Rob Herring, James E . J . Bottomley, Martin K . Petersen,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Heiko Stuebner,
Rafael J . Wysocki
Cc: Manivannan Sadhasivam, Alim Akhtar, Avri Altman, Bart Van Assche,
YiFeng Zhao, Liang Chen, linux-scsi, linux-rockchip, devicetree,
linux-pm, Shawn Lin
Add ROCKCHIP_SIP_SUSPEND_MODE to pass down parameters to Trusted Firmware
in order to decide suspend mode. Currently only add ROCKCHIP_SLEEP_PD_CONFIG
which teaches firmware to power down controllers or not.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
include/soc/rockchip/rockchip_sip.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h
index c46a9ae..501ad1f 100644
--- a/include/soc/rockchip/rockchip_sip.h
+++ b/include/soc/rockchip/rockchip_sip.h
@@ -6,6 +6,9 @@
#ifndef __SOC_ROCKCHIP_SIP_H
#define __SOC_ROCKCHIP_SIP_H
+#define ROCKCHIP_SIP_SUSPEND_MODE 0x82000003
+#define ROCKCHIP_SLEEP_PD_CONFIG 0xff
+
#define ROCKCHIP_SIP_DRAM_FREQ 0x82000008
#define ROCKCHIP_SIP_CONFIG_DRAM_INIT 0x00
#define ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE 0x01
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v4 4/7] pmdomain: core: Introduce dev_pm_genpd_rpm_always_on()
2024-11-04 7:31 [PATCH v4 0/7] Initial support for RK3576 UFS controller Shawn Lin
` (2 preceding siblings ...)
2024-11-04 7:31 ` [PATCH v4 3/7] soc: rockchip: add header for suspend mode SIP interface Shawn Lin
@ 2024-11-04 7:31 ` Shawn Lin
2024-11-04 19:04 ` kernel test robot
` (2 more replies)
2024-11-04 7:31 ` [PATCH v4 5/7] pmdomain: rockchip: Add smc call to inform firmware Shawn Lin
` (2 subsequent siblings)
6 siblings, 3 replies; 20+ messages in thread
From: Shawn Lin @ 2024-11-04 7:31 UTC (permalink / raw)
To: Rob Herring, James E . J . Bottomley, Martin K . Petersen,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Heiko Stuebner,
Rafael J . Wysocki
Cc: Manivannan Sadhasivam, Alim Akhtar, Avri Altman, Bart Van Assche,
YiFeng Zhao, Liang Chen, linux-scsi, linux-rockchip, devicetree,
linux-pm
From: Ulf Hansson <ulf.hansson@linaro.org>
For some usecases a consumer driver requires its device to remain power-on
from the PM domain perspective during runtime. Using dev PM qos along with
the genpd governors, doesn't work for this case as would potentially
prevent the device from being runtime suspended too.
To support these usecases, let's introduce dev_pm_genpd_rpm_always_on() to
allow consumers drivers to dynamically control the behaviour in genpd for a
device that is attached to it.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/pmdomain/core.c | 34 ++++++++++++++++++++++++++++++++++
include/linux/pm_domain.h | 7 +++++++
2 files changed, 41 insertions(+)
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 5ede0f7..02bb5c8 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -692,6 +692,36 @@ bool dev_pm_genpd_get_hwmode(struct device *dev)
}
EXPORT_SYMBOL_GPL(dev_pm_genpd_get_hwmode);
+/**
+ * dev_pm_genpd_rpm_always_on() - Control if the PM domain can be powered off.
+ *
+ * @dev: Device for which the PM domain may need to stay on for.
+ * @on: Value to set or unset for the condition.
+ *
+ * For some usecases a consumer driver requires its device to remain power-on
+ * from the PM domain perspective during runtime. This function allows the
+ * behaviour to be dynamically controlled for a device attached to a genpd.
+ *
+ * It is assumed that the users guarantee that the genpd wouldn't be detached
+ * while this routine is getting called.
+ *
+ * Return: Returns 0 on success and negative error values on failures.
+ */
+int dev_pm_genpd_rpm_always_on(struct device *dev, bool on)
+{
+ struct generic_pm_domain *genpd;
+
+ genpd = dev_to_genpd_safe(dev);
+ if (!genpd)
+ return -ENODEV;
+
+ genpd_lock(genpd);
+ dev_gpd_data(dev)->rpm_always_on = on;
+ genpd_unlock(genpd);
+
+ return 0;
+}
+
static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed)
{
unsigned int state_idx = genpd->state_idx;
@@ -863,6 +893,10 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
if (!pm_runtime_suspended(pdd->dev) ||
irq_safe_dev_in_sleep_domain(pdd->dev, genpd))
not_suspended++;
+
+ /* The device may need its PM domain to stay powered on. */
+ if (to_gpd_data(pdd)->rpm_always_on)
+ return -EBUSY;
}
if (not_suspended > 1 || (not_suspended == 1 && !one_dev_on))
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index b637ec1..30186ad 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -245,6 +245,7 @@ struct generic_pm_domain_data {
unsigned int default_pstate;
unsigned int rpm_pstate;
bool hw_mode;
+ bool rpm_always_on;
void *data;
};
@@ -277,6 +278,7 @@ ktime_t dev_pm_genpd_get_next_hrtimer(struct device *dev);
void dev_pm_genpd_synced_poweroff(struct device *dev);
int dev_pm_genpd_set_hwmode(struct device *dev, bool enable);
bool dev_pm_genpd_get_hwmode(struct device *dev);
+int dev_pm_genpd_rpm_always_on(struct device *dev, bool on);
extern struct dev_power_governor simple_qos_governor;
extern struct dev_power_governor pm_domain_always_on_gov;
@@ -360,6 +362,11 @@ static inline bool dev_pm_genpd_get_hwmode(struct device *dev)
return false;
}
+static inline int dev_pm_genpd_rpm_always_on(struct device *dev, bool on)
+{
+ return -EOPNOTSUPP;
+}
+
#define simple_qos_governor (*(struct dev_power_governor *)(NULL))
#define pm_domain_always_on_gov (*(struct dev_power_governor *)(NULL))
#endif
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v4 5/7] pmdomain: rockchip: Add smc call to inform firmware
2024-11-04 7:31 [PATCH v4 0/7] Initial support for RK3576 UFS controller Shawn Lin
` (3 preceding siblings ...)
2024-11-04 7:31 ` [PATCH v4 4/7] pmdomain: core: Introduce dev_pm_genpd_rpm_always_on() Shawn Lin
@ 2024-11-04 7:31 ` Shawn Lin
2024-11-04 7:32 ` [PATCH v4 6/7] PM: wakeup: Add device_clr_wakeup_path() Shawn Lin
2024-11-04 7:32 ` [PATCH v4 7/7] scsi: ufs: rockchip: initial support for UFS Shawn Lin
6 siblings, 0 replies; 20+ messages in thread
From: Shawn Lin @ 2024-11-04 7:31 UTC (permalink / raw)
To: Rob Herring, James E . J . Bottomley, Martin K . Petersen,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Heiko Stuebner,
Rafael J . Wysocki
Cc: Manivannan Sadhasivam, Alim Akhtar, Avri Altman, Bart Van Assche,
YiFeng Zhao, Liang Chen, linux-scsi, linux-rockchip, devicetree,
linux-pm, Shawn Lin
Inform firmware to keep the power domain on or off.
Suggested-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/pmdomain/rockchip/pm-domains.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c
index cb0f938..8b5dd7f 100644
--- a/drivers/pmdomain/rockchip/pm-domains.c
+++ b/drivers/pmdomain/rockchip/pm-domains.c
@@ -5,6 +5,7 @@
* Copyright (c) 2015 ROCKCHIP, Co. Ltd.
*/
+#include <linux/arm-smccc.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/err.h>
@@ -20,6 +21,7 @@
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include <soc/rockchip/pm_domains.h>
+#include <soc/rockchip/rockchip_sip.h>
#include <dt-bindings/power/px30-power.h>
#include <dt-bindings/power/rockchip,rv1126-power.h>
#include <dt-bindings/power/rk3036-power.h>
@@ -567,6 +569,11 @@ static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
genpd->name, is_on);
return;
}
+
+ /* Inform firmware to keep this pd on or off */
+ arm_smccc_smc(ROCKCHIP_SIP_SUSPEND_MODE, ROCKCHIP_SLEEP_PD_CONFIG,
+ pmu->info->pwr_offset + pd_pwr_offset,
+ pd->info->pwr_mask, on, 0, 0, 0, NULL);
}
static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v4 6/7] PM: wakeup: Add device_clr_wakeup_path()
2024-11-04 7:31 [PATCH v4 0/7] Initial support for RK3576 UFS controller Shawn Lin
` (4 preceding siblings ...)
2024-11-04 7:31 ` [PATCH v4 5/7] pmdomain: rockchip: Add smc call to inform firmware Shawn Lin
@ 2024-11-04 7:32 ` Shawn Lin
2024-11-04 7:32 ` [PATCH v4 7/7] scsi: ufs: rockchip: initial support for UFS Shawn Lin
6 siblings, 0 replies; 20+ messages in thread
From: Shawn Lin @ 2024-11-04 7:32 UTC (permalink / raw)
To: Rob Herring, James E . J . Bottomley, Martin K . Petersen,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Heiko Stuebner,
Rafael J . Wysocki
Cc: Manivannan Sadhasivam, Alim Akhtar, Avri Altman, Bart Van Assche,
YiFeng Zhao, Liang Chen, linux-scsi, linux-rockchip, devicetree,
linux-pm, Shawn Lin
device_clr_wakeup_path() is used to disable wakeup path support
which is symmetrical to device_set_wakeup_path().
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
include/linux/pm_wakeup.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h
index 76cd1f9..45405a3 100644
--- a/include/linux/pm_wakeup.h
+++ b/include/linux/pm_wakeup.h
@@ -94,6 +94,11 @@ static inline void device_set_wakeup_path(struct device *dev)
dev->power.wakeup_path = true;
}
+static inline void device_clr_wakeup_path(struct device *dev)
+{
+ dev->power.wakeup_path = false;
+}
+
/* drivers/base/power/wakeup.c */
extern struct wakeup_source *wakeup_source_create(const char *name);
extern void wakeup_source_destroy(struct wakeup_source *ws);
@@ -177,6 +182,8 @@ static inline bool device_wakeup_path(struct device *dev)
static inline void device_set_wakeup_path(struct device *dev) {}
+static inline void device_clr_wakeup_path(struct device *dev) {}
+
static inline void __pm_stay_awake(struct wakeup_source *ws) {}
static inline void pm_stay_awake(struct device *dev) {}
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v4 7/7] scsi: ufs: rockchip: initial support for UFS
2024-11-04 7:31 [PATCH v4 0/7] Initial support for RK3576 UFS controller Shawn Lin
` (5 preceding siblings ...)
2024-11-04 7:32 ` [PATCH v4 6/7] PM: wakeup: Add device_clr_wakeup_path() Shawn Lin
@ 2024-11-04 7:32 ` Shawn Lin
2024-11-04 10:57 ` Ulf Hansson
2024-11-09 12:12 ` Manivannan Sadhasivam
6 siblings, 2 replies; 20+ messages in thread
From: Shawn Lin @ 2024-11-04 7:32 UTC (permalink / raw)
To: Rob Herring, James E . J . Bottomley, Martin K . Petersen,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Heiko Stuebner,
Rafael J . Wysocki
Cc: Manivannan Sadhasivam, Alim Akhtar, Avri Altman, Bart Van Assche,
YiFeng Zhao, Liang Chen, linux-scsi, linux-rockchip, devicetree,
linux-pm, Shawn Lin
RK3576 SoC contains a UFS controller, add initial support for it.
The features are:
(1) support UFS 2.0 features
(2) High speed up to HS-G3
(3) 2RX-2TX lanes
(4) auto H8 entry and exit
Software limitation:
(1) HCE procedure: enable controller->enable intr->dme_reset->dme_enable
(2) disable unipro timeout values before power mode change
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
Changes in v4:
- deal with power domain of rpm and spm suggested by Ulf
- Fix typo and disable clks in ufs_rockchip_remove
- remove clk_disable_unprepare(host->ref_out_clk) from
ufs_rockchip_remove
Changes in v3:
- reword Kconfig description
- elaborate more about controller in commit msg
- use rockchip,rk3576-ufshc for compatible
- remove useless header file
- remove inline for ufshcd_is_device_present
- use usleep_range instead
- remove initialization, reverse Xmas order
- remove useless varibles
- check vops for null
- other small fixes for err path
- remove pm_runtime_set_active
- fix the active and inactive reset-gpios logic
- fix rpm_lvl and spm_lvl to 5 and move to end of probe path
- remove unnecessary system PM callbacks
- use UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE instead
of UFSHCI_QUIRK_BROKEN_HCE
Changes in v2: None
drivers/ufs/host/Kconfig | 12 ++
drivers/ufs/host/Makefile | 1 +
drivers/ufs/host/ufs-rockchip.c | 340 ++++++++++++++++++++++++++++++++++++++++
drivers/ufs/host/ufs-rockchip.h | 51 ++++++
4 files changed, 404 insertions(+)
create mode 100644 drivers/ufs/host/ufs-rockchip.c
create mode 100644 drivers/ufs/host/ufs-rockchip.h
diff --git a/drivers/ufs/host/Kconfig b/drivers/ufs/host/Kconfig
index 580c8d0..191fbd7 100644
--- a/drivers/ufs/host/Kconfig
+++ b/drivers/ufs/host/Kconfig
@@ -142,3 +142,15 @@ config SCSI_UFS_SPRD
Select this if you have UFS controller on Unisoc chipset.
If unsure, say N.
+
+config SCSI_UFS_ROCKCHIP
+ tristate "Rockchip UFS host controller driver"
+ depends on SCSI_UFSHCD_PLATFORM && (ARCH_ROCKCHIP || COMPILE_TEST)
+ help
+ This selects the Rockchip specific additions to UFSHCD platform driver.
+ UFS host on Rockchip needs some vendor specific configuration before
+ accessing the hardware which includes PHY configuration and vendor
+ specific registers.
+
+ Select this if you have UFS controller on Rockchip chipset.
+ If unsure, say N.
diff --git a/drivers/ufs/host/Makefile b/drivers/ufs/host/Makefile
index 4573aea..2f97feb 100644
--- a/drivers/ufs/host/Makefile
+++ b/drivers/ufs/host/Makefile
@@ -10,5 +10,6 @@ obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o
obj-$(CONFIG_SCSI_UFS_MEDIATEK) += ufs-mediatek.o
obj-$(CONFIG_SCSI_UFS_RENESAS) += ufs-renesas.o
+obj-$(CONFIG_SCSI_UFS_ROCKCHIP) += ufs-rockchip.o
obj-$(CONFIG_SCSI_UFS_SPRD) += ufs-sprd.o
obj-$(CONFIG_SCSI_UFS_TI_J721E) += ti-j721e-ufs.o
diff --git a/drivers/ufs/host/ufs-rockchip.c b/drivers/ufs/host/ufs-rockchip.c
new file mode 100644
index 0000000..9c277bc
--- /dev/null
+++ b/drivers/ufs/host/ufs-rockchip.c
@@ -0,0 +1,340 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Rockchip UFS Host Controller driver
+ *
+ * Copyright (C) 2024 Rockchip Electronics Co.Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_wakeup.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#include <ufs/ufshcd.h>
+#include <ufs/unipro.h>
+#include "ufshcd-pltfrm.h"
+#include "ufs-rockchip.h"
+
+static int ufs_rockchip_hce_enable_notify(struct ufs_hba *hba,
+ enum ufs_notify_change_status status)
+{
+ int err = 0;
+
+ if (status == POST_CHANGE)
+ err = ufshcd_vops_phy_initialization(hba);
+
+ return err;
+}
+
+static void ufs_rockchip_set_pm_lvl(struct ufs_hba *hba)
+{
+ hba->rpm_lvl = UFS_PM_LVL_5;
+ hba->spm_lvl = UFS_PM_LVL_5;
+}
+
+static int ufs_rockchip_rk3576_phy_init(struct ufs_hba *hba)
+{
+ struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
+
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(PA_LOCAL_TX_LCC_ENABLE, 0x0), 0x0);
+ /* enable the mphy DME_SET cfg */
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x200, 0x0), 0x40);
+ for (int i = 0; i < 2; i++) {
+ /* Configuration M-TX */
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xaa, SEL_TX_LANE0 + i), 0x06);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xa9, SEL_TX_LANE0 + i), 0x02);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xad, SEL_TX_LANE0 + i), 0x44);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xac, SEL_TX_LANE0 + i), 0xe6);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xab, SEL_TX_LANE0 + i), 0x07);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x94, SEL_TX_LANE0 + i), 0x93);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x93, SEL_TX_LANE0 + i), 0xc9);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x7f, SEL_TX_LANE0 + i), 0x00);
+ /* Configuration M-RX */
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x12, SEL_RX_LANE0 + i), 0x06);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x11, SEL_RX_LANE0 + i), 0x00);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1d, SEL_RX_LANE0 + i), 0x58);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1c, SEL_RX_LANE0 + i), 0x8c);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1b, SEL_RX_LANE0 + i), 0x02);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x25, SEL_RX_LANE0 + i), 0xf6);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x2f, SEL_RX_LANE0 + i), 0x69);
+ }
+ /* disable the mphy DME_SET cfg */
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x200, 0x0), 0x00);
+
+ ufs_sys_writel(host->mphy_base, 0x80, 0x08C);
+ ufs_sys_writel(host->mphy_base, 0xB5, 0x110);
+ ufs_sys_writel(host->mphy_base, 0xB5, 0x250);
+
+ ufs_sys_writel(host->mphy_base, 0x03, 0x134);
+ ufs_sys_writel(host->mphy_base, 0x03, 0x274);
+
+ ufs_sys_writel(host->mphy_base, 0x38, 0x0E0);
+ ufs_sys_writel(host->mphy_base, 0x38, 0x220);
+
+ ufs_sys_writel(host->mphy_base, 0x50, 0x164);
+ ufs_sys_writel(host->mphy_base, 0x50, 0x2A4);
+
+ ufs_sys_writel(host->mphy_base, 0x80, 0x178);
+ ufs_sys_writel(host->mphy_base, 0x80, 0x2B8);
+
+ ufs_sys_writel(host->mphy_base, 0x18, 0x1B0);
+ ufs_sys_writel(host->mphy_base, 0x18, 0x2F0);
+
+ ufs_sys_writel(host->mphy_base, 0x03, 0x128);
+ ufs_sys_writel(host->mphy_base, 0x03, 0x268);
+
+ ufs_sys_writel(host->mphy_base, 0x20, 0x12C);
+ ufs_sys_writel(host->mphy_base, 0x20, 0x26C);
+
+ ufs_sys_writel(host->mphy_base, 0xC0, 0x120);
+ ufs_sys_writel(host->mphy_base, 0xC0, 0x260);
+
+ ufs_sys_writel(host->mphy_base, 0x03, 0x094);
+
+ ufs_sys_writel(host->mphy_base, 0x03, 0x1B4);
+ ufs_sys_writel(host->mphy_base, 0x03, 0x2F4);
+
+ ufs_sys_writel(host->mphy_base, 0xC0, 0x08C);
+ usleep_range(1, 2);
+ ufs_sys_writel(host->mphy_base, 0x00, 0x08C);
+
+ usleep_range(200, 250);
+ /* start link up */
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(MIB_T_DBG_CPORT_TX_ENDIAN, 0), 0x0);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(MIB_T_DBG_CPORT_RX_ENDIAN, 0), 0x0);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(N_DEVICEID, 0), 0x0);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(N_DEVICEID_VALID, 0), 0x1);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(T_PEERDEVICEID, 0), 0x1);
+ ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(T_CONNECTIONSTATE, 0), 0x1);
+
+ return 0;
+}
+
+static int ufs_rockchip_common_init(struct ufs_hba *hba)
+{
+ struct device *dev = hba->dev;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct ufs_rockchip_host *host;
+ int err;
+
+ host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
+ if (!host)
+ return -ENOMEM;
+
+ /* system control register for hci */
+ host->ufs_sys_ctrl = devm_platform_ioremap_resource_byname(pdev, "hci_grf");
+ if (IS_ERR(host->ufs_sys_ctrl))
+ return dev_err_probe(dev, PTR_ERR(host->ufs_sys_ctrl),
+ "cannot ioremap for hci system control register\n");
+
+ /* system control register for mphy */
+ host->ufs_phy_ctrl = devm_platform_ioremap_resource_byname(pdev, "mphy_grf");
+ if (IS_ERR(host->ufs_phy_ctrl))
+ return dev_err_probe(dev, PTR_ERR(host->ufs_phy_ctrl),
+ "cannot ioremap for mphy system control register\n");
+
+ /* mphy base register */
+ host->mphy_base = devm_platform_ioremap_resource_byname(pdev, "mphy");
+ if (IS_ERR(host->mphy_base))
+ return dev_err_probe(dev, PTR_ERR(host->mphy_base),
+ "cannot ioremap for mphy base register\n");
+
+ host->rst = devm_reset_control_array_get_exclusive(dev);
+ if (IS_ERR(host->rst))
+ return dev_err_probe(dev, PTR_ERR(host->rst),
+ "failed to get reset control\n");
+
+ reset_control_assert(host->rst);
+ usleep_range(1, 2);
+ reset_control_deassert(host->rst);
+
+ host->ref_out_clk = devm_clk_get_enabled(dev, "ref_out");
+ if (IS_ERR(host->ref_out_clk))
+ return dev_err_probe(dev, PTR_ERR(host->ref_out_clk),
+ "ref_out unavailable\n");
+
+ host->rst_gpio = devm_gpiod_get(&pdev->dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(host->rst_gpio))
+ return dev_err_probe(&pdev->dev, PTR_ERR(host->rst_gpio),
+ "invalid reset-gpios property in node\n");
+
+ host->clks[0].id = "core";
+ host->clks[1].id = "pclk";
+ host->clks[2].id = "pclk_mphy";
+ err = devm_clk_bulk_get_optional(dev, UFS_MAX_CLKS, host->clks);
+ if (err)
+ return dev_err_probe(dev, err, "failed to get clocks\n");
+
+ err = clk_bulk_prepare_enable(UFS_MAX_CLKS, host->clks);
+ if (err)
+ return dev_err_probe(dev, err, "failed to enable clocks\n");
+
+ host->hba = hba;
+
+ ufshcd_set_variant(hba, host);
+
+ return 0;
+}
+
+static int ufs_rockchip_rk3576_init(struct ufs_hba *hba)
+{
+ struct device *dev = hba->dev;
+ struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
+ int ret;
+
+ hba->quirks = UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING |
+ UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE;
+
+ /* Enable BKOPS when suspend */
+ hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
+ /* Enable putting device into deep sleep */
+ hba->caps |= UFSHCD_CAP_DEEPSLEEP;
+ /* Enable devfreq of UFS */
+ hba->caps |= UFSHCD_CAP_CLK_SCALING;
+ /* Enable WriteBooster */
+ hba->caps |= UFSHCD_CAP_WB_EN;
+
+ host->pd_id = RK3576_PD_UFS;
+
+ ret = ufs_rockchip_common_init(hba);
+ if (ret)
+ return dev_err_probe(dev, ret, "ufs common init fail\n");
+
+ return 0;
+}
+
+static int ufs_rockchip_device_reset(struct ufs_hba *hba)
+{
+ struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
+
+ /* Active the reset-gpios */
+ gpiod_set_value_cansleep(host->rst_gpio, 1);
+ usleep_range(20, 25);
+
+ /* Inactive the reset-gpios */
+ gpiod_set_value_cansleep(host->rst_gpio, 0);
+ usleep_range(20, 25);
+
+ return 0;
+}
+
+static const struct ufs_hba_variant_ops ufs_hba_rk3576_vops = {
+ .name = "rk3576",
+ .init = ufs_rockchip_rk3576_init,
+ .device_reset = ufs_rockchip_device_reset,
+ .hce_enable_notify = ufs_rockchip_hce_enable_notify,
+ .phy_initialization = ufs_rockchip_rk3576_phy_init,
+};
+
+static const struct of_device_id ufs_rockchip_of_match[] = {
+ { .compatible = "rockchip,rk3576-ufshc", .data = &ufs_hba_rk3576_vops },
+};
+MODULE_DEVICE_TABLE(of, ufs_rockchip_of_match);
+
+static int ufs_rockchip_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct ufs_hba_variant_ops *vops;
+ struct ufs_hba *hba;
+ int err;
+
+ vops = device_get_match_data(dev);
+ if (!vops)
+ return dev_err_probe(dev, -EINVAL, "ufs_hba_variant_ops not defined.\n");
+
+ err = ufshcd_pltfrm_init(pdev, vops);
+ if (err)
+ return dev_err_probe(dev, err, "ufshcd_pltfrm_init failed\n");
+
+ hba = platform_get_drvdata(pdev);
+ /* Set the default desired pm level in case no users set via sysfs */
+ ufs_rockchip_set_pm_lvl(hba);
+
+ return 0;
+}
+
+static void ufs_rockchip_remove(struct platform_device *pdev)
+{
+ struct ufs_hba *hba = platform_get_drvdata(pdev);
+ struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
+
+ pm_runtime_forbid(&pdev->dev);
+ pm_runtime_get_noresume(&pdev->dev);
+ ufshcd_remove(hba);
+ ufshcd_dealloc_host(hba);
+ clk_bulk_disable_unprepare(UFS_MAX_CLKS, host->clks);
+}
+
+#ifdef CONFIG_PM
+static int ufs_rockchip_runtime_suspend(struct device *dev)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+ struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
+
+ clk_disable_unprepare(host->ref_out_clk);
+
+ /* Shouldn't power down if rpm_lvl is less than level 5. */
+ dev_pm_genpd_rpm_always_on(dev, hba->rpm_lvl < UFS_PM_LVL_5 ? true : false);
+
+ return ufshcd_runtime_suspend(dev);
+}
+
+static int ufs_rockchip_runtime_resume(struct device *dev)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+ struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
+ int err;
+
+ err = clk_prepare_enable(host->ref_out_clk);
+ if (err) {
+ dev_err(hba->dev, "failed to enable ref out clock %d\n", err);
+ return err;
+ }
+
+ reset_control_assert(host->rst);
+ usleep_range(1, 2);
+ reset_control_deassert(host->rst);
+
+ return ufshcd_runtime_resume(dev);
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int ufs_rockchip_system_suspend(struct device *dev)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+
+ if (hba->spm_lvl < 5)
+ device_set_wakeup_path(dev);
+ else
+ device_clr_wakeup_path(dev);
+
+ return ufshcd_system_suspend(dev);
+}
+#endif
+
+static const struct dev_pm_ops ufs_rockchip_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(ufs_rockchip_system_suspend, ufshcd_system_resume)
+ SET_RUNTIME_PM_OPS(ufs_rockchip_runtime_suspend, ufs_rockchip_runtime_resume, NULL)
+ .prepare = ufshcd_suspend_prepare,
+ .complete = ufshcd_resume_complete,
+};
+
+static struct platform_driver ufs_rockchip_pltform = {
+ .probe = ufs_rockchip_probe,
+ .remove = ufs_rockchip_remove,
+ .driver = {
+ .name = "ufshcd-rockchip",
+ .pm = &ufs_rockchip_pm_ops,
+ .of_match_table = ufs_rockchip_of_match,
+ },
+};
+module_platform_driver(ufs_rockchip_pltform);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Rockchip UFS Host Driver");
diff --git a/drivers/ufs/host/ufs-rockchip.h b/drivers/ufs/host/ufs-rockchip.h
new file mode 100644
index 0000000..37c45a5
--- /dev/null
+++ b/drivers/ufs/host/ufs-rockchip.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Rockchip UFS Host Controller driver
+ *
+ * Copyright (C) 2024 Rockchip Electronics Co.Ltd.
+ */
+
+#ifndef _UFS_ROCKCHIP_H_
+#define _UFS_ROCKCHIP_H_
+
+#define UFS_MAX_CLKS 3
+
+#define SEL_TX_LANE0 0x0
+#define SEL_TX_LANE1 0x1
+#define SEL_TX_LANE2 0x2
+#define SEL_TX_LANE3 0x3
+#define SEL_RX_LANE0 0x4
+#define SEL_RX_LANE1 0x5
+#define SEL_RX_LANE2 0x6
+#define SEL_RX_LANE3 0x7
+
+#define MIB_T_DBG_CPORT_TX_ENDIAN 0xc022
+#define MIB_T_DBG_CPORT_RX_ENDIAN 0xc023
+
+#define RK3576_PD_UFS 0x7
+
+struct ufs_rockchip_host {
+ struct ufs_hba *hba;
+ void __iomem *ufs_phy_ctrl;
+ void __iomem *ufs_sys_ctrl;
+ void __iomem *mphy_base;
+ struct gpio_desc *rst_gpio;
+ struct reset_control *rst;
+ struct clk *ref_out_clk;
+ struct clk_bulk_data clks[UFS_MAX_CLKS];
+ uint64_t caps;
+ uint64_t pd_id;
+};
+
+#define ufs_sys_writel(base, val, reg) \
+ writel((val), (base) + (reg))
+#define ufs_sys_readl(base, reg) readl((base) + (reg))
+#define ufs_sys_set_bits(base, mask, reg) \
+ ufs_sys_writel( \
+ (base), ((mask) | (ufs_sys_readl((base), (reg)))), (reg))
+#define ufs_sys_ctrl_clr_bits(base, mask, reg) \
+ ufs_sys_writel((base), \
+ ((~(mask)) & (ufs_sys_readl((base), (reg)))), \
+ (reg))
+
+#endif /* _UFS_ROCKCHIP_H_ */
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v4 7/7] scsi: ufs: rockchip: initial support for UFS
2024-11-04 7:32 ` [PATCH v4 7/7] scsi: ufs: rockchip: initial support for UFS Shawn Lin
@ 2024-11-04 10:57 ` Ulf Hansson
2024-11-05 1:54 ` Shawn Lin
2024-11-09 12:12 ` Manivannan Sadhasivam
1 sibling, 1 reply; 20+ messages in thread
From: Ulf Hansson @ 2024-11-04 10:57 UTC (permalink / raw)
To: Shawn Lin
Cc: Rob Herring, James E . J . Bottomley, Martin K . Petersen,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Rafael J . Wysocki, Manivannan Sadhasivam, Alim Akhtar,
Avri Altman, Bart Van Assche, YiFeng Zhao, Liang Chen, linux-scsi,
linux-rockchip, devicetree, linux-pm
On Mon, 4 Nov 2024 at 08:34, Shawn Lin <shawn.lin@rock-chips.com> wrote:
>
> RK3576 SoC contains a UFS controller, add initial support for it.
> The features are:
> (1) support UFS 2.0 features
> (2) High speed up to HS-G3
> (3) 2RX-2TX lanes
> (4) auto H8 entry and exit
>
> Software limitation:
> (1) HCE procedure: enable controller->enable intr->dme_reset->dme_enable
> (2) disable unipro timeout values before power mode change
>
> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
> ---
>
> Changes in v4:
> - deal with power domain of rpm and spm suggested by Ulf
> - Fix typo and disable clks in ufs_rockchip_remove
> - remove clk_disable_unprepare(host->ref_out_clk) from
> ufs_rockchip_remove
>
[...]
> +#ifdef CONFIG_PM
> +static int ufs_rockchip_runtime_suspend(struct device *dev)
> +{
> + struct ufs_hba *hba = dev_get_drvdata(dev);
> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
> +
> + clk_disable_unprepare(host->ref_out_clk);
> +
> + /* Shouldn't power down if rpm_lvl is less than level 5. */
> + dev_pm_genpd_rpm_always_on(dev, hba->rpm_lvl < UFS_PM_LVL_5 ? true : false);
> +
> + return ufshcd_runtime_suspend(dev);
> +}
> +
> +static int ufs_rockchip_runtime_resume(struct device *dev)
> +{
> + struct ufs_hba *hba = dev_get_drvdata(dev);
> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
> + int err;
> +
> + err = clk_prepare_enable(host->ref_out_clk);
> + if (err) {
> + dev_err(hba->dev, "failed to enable ref out clock %d\n", err);
> + return err;
> + }
> +
> + reset_control_assert(host->rst);
> + usleep_range(1, 2);
> + reset_control_deassert(host->rst);
> +
> + return ufshcd_runtime_resume(dev);
> +}
> +#endif
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int ufs_rockchip_system_suspend(struct device *dev)
> +{
> + struct ufs_hba *hba = dev_get_drvdata(dev);
> +
> + if (hba->spm_lvl < 5)
> + device_set_wakeup_path(dev);
Please use device_set_awake_path() instead.
Ideally all users of device_set_wakeup_path() should convert into
device_set_awake_path(), it's just that we haven't been able to
complete the conversion yet.
> + else
> + device_clr_wakeup_path(dev);
This isn't needed. The flag is getting cleared in device_prepare().
> +
> + return ufshcd_system_suspend(dev);
Don't you want to disable the clock during system suspend too? If the
device is runtime resumed at this point, the clock will be left
enabled, no?
> +}
> +#endif
> +
> +static const struct dev_pm_ops ufs_rockchip_pm_ops = {
> + SET_SYSTEM_SLEEP_PM_OPS(ufs_rockchip_system_suspend, ufshcd_system_resume)
> + SET_RUNTIME_PM_OPS(ufs_rockchip_runtime_suspend, ufs_rockchip_runtime_resume, NULL)
> + .prepare = ufshcd_suspend_prepare,
> + .complete = ufshcd_resume_complete,
> +};
> +
[...]
Kind regards
Uffe
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v4 4/7] pmdomain: core: Introduce dev_pm_genpd_rpm_always_on()
2024-11-04 7:31 ` [PATCH v4 4/7] pmdomain: core: Introduce dev_pm_genpd_rpm_always_on() Shawn Lin
@ 2024-11-04 19:04 ` kernel test robot
2024-11-04 20:17 ` kernel test robot
2024-11-08 14:19 ` Dan Carpenter
2 siblings, 0 replies; 20+ messages in thread
From: kernel test robot @ 2024-11-04 19:04 UTC (permalink / raw)
To: Shawn Lin, Rob Herring, James E . J . Bottomley,
Martin K . Petersen, Krzysztof Kozlowski, Conor Dooley,
Ulf Hansson, Heiko Stuebner, Rafael J . Wysocki
Cc: oe-kbuild-all, Manivannan Sadhasivam, Alim Akhtar, Avri Altman,
Bart Van Assche, YiFeng Zhao, Liang Chen, linux-scsi,
linux-rockchip, devicetree, linux-pm
Hi Shawn,
kernel test robot noticed the following build warnings:
[auto build test WARNING on jejb-scsi/for-next]
[also build test WARNING on robh/for-next linus/master v6.12-rc6]
[cannot apply to mkp-scsi/for-next next-20241104]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Shawn-Lin/dt-bindings-ufs-Document-Rockchip-UFS-host-controller/20241104-191810
base: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
patch link: https://lore.kernel.org/r/1730705521-23081-5-git-send-email-shawn.lin%40rock-chips.com
patch subject: [PATCH v4 4/7] pmdomain: core: Introduce dev_pm_genpd_rpm_always_on()
config: x86_64-buildonly-randconfig-003-20241104 (https://download.01.org/0day-ci/archive/20241105/202411050203.kPDzy0bS-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-12) 11.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241105/202411050203.kPDzy0bS-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411050203.kPDzy0bS-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/pmdomain/core.c: In function 'genpd_power_off':
>> drivers/pmdomain/core.c:893:17: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
893 | if (!pm_runtime_suspended(pdd->dev) ||
| ^~
drivers/pmdomain/core.c:898:25: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
898 | if (to_gpd_data(pdd)->rpm_always_on)
| ^~
vim +/if +893 drivers/pmdomain/core.c
29e47e2173349e drivers/base/power/domain.c Ulf Hansson 2015-09-02 837
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 838 /**
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 839 * genpd_power_off - Remove power from a given PM domain.
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 840 * @genpd: PM domain to power down.
3c64649d1cf9f3 drivers/base/power/domain.c Ulf Hansson 2017-02-17 841 * @one_dev_on: If invoked from genpd's ->runtime_suspend|resume() callback, the
3c64649d1cf9f3 drivers/base/power/domain.c Ulf Hansson 2017-02-17 842 * RPM status of the releated device is in an intermediate state, not yet turned
3c64649d1cf9f3 drivers/base/power/domain.c Ulf Hansson 2017-02-17 843 * into RPM_SUSPENDED. This means genpd_power_off() must allow one device to not
3c64649d1cf9f3 drivers/base/power/domain.c Ulf Hansson 2017-02-17 844 * be RPM_SUSPENDED, while it tries to power off the PM domain.
763663c9715f5f drivers/base/power/domain.c Yang Yingliang 2021-05-12 845 * @depth: nesting count for lockdep.
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 846 *
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 847 * If all of the @genpd's devices have been suspended and all of its subdomains
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 848 * have been powered down, remove power from @genpd.
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 849 */
2da835452a0875 drivers/base/power/domain.c Ulf Hansson 2017-02-17 850 static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
2da835452a0875 drivers/base/power/domain.c Ulf Hansson 2017-02-17 851 unsigned int depth)
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 852 {
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 853 struct pm_domain_data *pdd;
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 854 struct gpd_link *link;
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 855 unsigned int not_suspended = 0;
f63816e43d9044 drivers/base/power/domain.c Ulf Hansson 2020-09-24 856 int ret;
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 857
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 858 /*
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 859 * Do not try to power off the domain in the following situations:
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 860 * (1) The domain is already in the "power off" state.
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 861 * (2) System suspend is in progress.
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 862 */
41e2c8e0060db2 drivers/base/power/domain.c Ulf Hansson 2017-03-20 863 if (!genpd_status_on(genpd) || genpd->prepared_count > 0)
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 864 return 0;
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 865
ffaa42e8a40b7f drivers/base/power/domain.c Ulf Hansson 2017-03-20 866 /*
ffaa42e8a40b7f drivers/base/power/domain.c Ulf Hansson 2017-03-20 867 * Abort power off for the PM domain in the following situations:
ffaa42e8a40b7f drivers/base/power/domain.c Ulf Hansson 2017-03-20 868 * (1) The domain is configured as always on.
ffaa42e8a40b7f drivers/base/power/domain.c Ulf Hansson 2017-03-20 869 * (2) When the domain has a subdomain being powered on.
ffaa42e8a40b7f drivers/base/power/domain.c Ulf Hansson 2017-03-20 870 */
ed61e18a4b4e44 drivers/base/power/domain.c Leonard Crestez 2019-04-30 871 if (genpd_is_always_on(genpd) ||
ed61e18a4b4e44 drivers/base/power/domain.c Leonard Crestez 2019-04-30 872 genpd_is_rpm_always_on(genpd) ||
ed61e18a4b4e44 drivers/base/power/domain.c Leonard Crestez 2019-04-30 873 atomic_read(&genpd->sd_count) > 0)
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 874 return -EBUSY;
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 875
e7d90cfac5510f drivers/base/power/domain.c Ulf Hansson 2022-02-17 876 /*
e7d90cfac5510f drivers/base/power/domain.c Ulf Hansson 2022-02-17 877 * The children must be in their deepest (powered-off) states to allow
e7d90cfac5510f drivers/base/power/domain.c Ulf Hansson 2022-02-17 878 * the parent to be powered off. Note that, there's no need for
e7d90cfac5510f drivers/base/power/domain.c Ulf Hansson 2022-02-17 879 * additional locking, as powering on a child, requires the parent's
e7d90cfac5510f drivers/base/power/domain.c Ulf Hansson 2022-02-17 880 * lock to be acquired first.
e7d90cfac5510f drivers/base/power/domain.c Ulf Hansson 2022-02-17 881 */
e7d90cfac5510f drivers/base/power/domain.c Ulf Hansson 2022-02-17 882 list_for_each_entry(link, &genpd->parent_links, parent_node) {
e7d90cfac5510f drivers/base/power/domain.c Ulf Hansson 2022-02-17 883 struct generic_pm_domain *child = link->child;
e7d90cfac5510f drivers/base/power/domain.c Ulf Hansson 2022-02-17 884 if (child->state_idx < child->state_count - 1)
e7d90cfac5510f drivers/base/power/domain.c Ulf Hansson 2022-02-17 885 return -EBUSY;
e7d90cfac5510f drivers/base/power/domain.c Ulf Hansson 2022-02-17 886 }
e7d90cfac5510f drivers/base/power/domain.c Ulf Hansson 2022-02-17 887
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 888 list_for_each_entry(pdd, &genpd->dev_list, list_node) {
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 889 /*
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 890 * Do not allow PM domain to be powered off, when an IRQ safe
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 891 * device is part of a non-IRQ safe domain.
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 892 */
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 @893 if (!pm_runtime_suspended(pdd->dev) ||
7a02444b8fc25a drivers/base/power/domain.c Ulf Hansson 2022-05-11 894 irq_safe_dev_in_sleep_domain(pdd->dev, genpd))
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 895 not_suspended++;
f0f6da10152fb8 drivers/pmdomain/core.c Ulf Hansson 2024-11-04 896
f0f6da10152fb8 drivers/pmdomain/core.c Ulf Hansson 2024-11-04 897 /* The device may need its PM domain to stay powered on. */
f0f6da10152fb8 drivers/pmdomain/core.c Ulf Hansson 2024-11-04 898 if (to_gpd_data(pdd)->rpm_always_on)
f0f6da10152fb8 drivers/pmdomain/core.c Ulf Hansson 2024-11-04 899 return -EBUSY;
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 900 }
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 901
3c64649d1cf9f3 drivers/base/power/domain.c Ulf Hansson 2017-02-17 902 if (not_suspended > 1 || (not_suspended == 1 && !one_dev_on))
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 903 return -EBUSY;
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 904
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 905 if (genpd->gov && genpd->gov->power_down_ok) {
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 906 if (!genpd->gov->power_down_ok(&genpd->domain))
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 907 return -EAGAIN;
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 908 }
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 909
2c9b7f8772033c drivers/base/power/domain.c Ulf Hansson 2018-10-03 910 /* Default to shallowest state. */
2c9b7f8772033c drivers/base/power/domain.c Ulf Hansson 2018-10-03 911 if (!genpd->gov)
2c9b7f8772033c drivers/base/power/domain.c Ulf Hansson 2018-10-03 912 genpd->state_idx = 0;
2c9b7f8772033c drivers/base/power/domain.c Ulf Hansson 2018-10-03 913
f63816e43d9044 drivers/base/power/domain.c Ulf Hansson 2020-09-24 914 /* Don't power off, if a child domain is waiting to power on. */
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 915 if (atomic_read(&genpd->sd_count) > 0)
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 916 return -EBUSY;
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 917
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 918 ret = _genpd_power_off(genpd, true);
c6a113b52302ad drivers/base/power/domain.c Lina Iyer 2020-10-15 919 if (ret) {
c6a113b52302ad drivers/base/power/domain.c Lina Iyer 2020-10-15 920 genpd->states[genpd->state_idx].rejected++;
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 921 return ret;
c6a113b52302ad drivers/base/power/domain.c Lina Iyer 2020-10-15 922 }
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 923
49f618e1b669ef drivers/base/power/domain.c Ulf Hansson 2020-09-24 924 genpd->status = GENPD_STATE_OFF;
afece3ab9a3640 drivers/base/power/domain.c Thara Gopinath 2017-07-14 925 genpd_update_accounting(genpd);
c6a113b52302ad drivers/base/power/domain.c Lina Iyer 2020-10-15 926 genpd->states[genpd->state_idx].usage++;
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 927
8d87ae48ced2df drivers/base/power/domain.c Kees Cook 2020-07-08 928 list_for_each_entry(link, &genpd->child_links, child_node) {
8d87ae48ced2df drivers/base/power/domain.c Kees Cook 2020-07-08 929 genpd_sd_counter_dec(link->parent);
8d87ae48ced2df drivers/base/power/domain.c Kees Cook 2020-07-08 930 genpd_lock_nested(link->parent, depth + 1);
8d87ae48ced2df drivers/base/power/domain.c Kees Cook 2020-07-08 931 genpd_power_off(link->parent, false, depth + 1);
8d87ae48ced2df drivers/base/power/domain.c Kees Cook 2020-07-08 932 genpd_unlock(link->parent);
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 933 }
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 934
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 935 return 0;
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 936 }
1f8728b7adc4c2 drivers/base/power/domain.c Ulf Hansson 2017-02-17 937
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v4 4/7] pmdomain: core: Introduce dev_pm_genpd_rpm_always_on()
2024-11-04 7:31 ` [PATCH v4 4/7] pmdomain: core: Introduce dev_pm_genpd_rpm_always_on() Shawn Lin
2024-11-04 19:04 ` kernel test robot
@ 2024-11-04 20:17 ` kernel test robot
2024-11-08 14:19 ` Dan Carpenter
2 siblings, 0 replies; 20+ messages in thread
From: kernel test robot @ 2024-11-04 20:17 UTC (permalink / raw)
To: Shawn Lin, Rob Herring, James E . J . Bottomley,
Martin K . Petersen, Krzysztof Kozlowski, Conor Dooley,
Ulf Hansson, Heiko Stuebner, Rafael J . Wysocki
Cc: llvm, oe-kbuild-all, Manivannan Sadhasivam, Alim Akhtar,
Avri Altman, Bart Van Assche, YiFeng Zhao, Liang Chen, linux-scsi,
linux-rockchip, devicetree, linux-pm
Hi Shawn,
kernel test robot noticed the following build warnings:
[auto build test WARNING on jejb-scsi/for-next]
[also build test WARNING on robh/for-next linus/master v6.12-rc6]
[cannot apply to mkp-scsi/for-next next-20241104]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Shawn-Lin/dt-bindings-ufs-Document-Rockchip-UFS-host-controller/20241104-191810
base: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
patch link: https://lore.kernel.org/r/1730705521-23081-5-git-send-email-shawn.lin%40rock-chips.com
patch subject: [PATCH v4 4/7] pmdomain: core: Introduce dev_pm_genpd_rpm_always_on()
config: x86_64-buildonly-randconfig-002-20241104 (https://download.01.org/0day-ci/archive/20241105/202411050317.abJatSkD-lkp@intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241105/202411050317.abJatSkD-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411050317.abJatSkD-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from drivers/pmdomain/core.c:21:
In file included from include/linux/suspend.h:5:
In file included from include/linux/swap.h:9:
In file included from include/linux/memcontrol.h:21:
In file included from include/linux/mm.h:2213:
include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
518 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
| ~~~~~~~~~~~ ^ ~~~
>> drivers/pmdomain/core.c:898:4: warning: misleading indentation; statement is not part of the previous 'if' [-Wmisleading-indentation]
898 | if (to_gpd_data(pdd)->rpm_always_on)
| ^
drivers/pmdomain/core.c:893:3: note: previous statement is here
893 | if (!pm_runtime_suspended(pdd->dev) ||
| ^
2 warnings generated.
vim +/if +898 drivers/pmdomain/core.c
837
838 /**
839 * genpd_power_off - Remove power from a given PM domain.
840 * @genpd: PM domain to power down.
841 * @one_dev_on: If invoked from genpd's ->runtime_suspend|resume() callback, the
842 * RPM status of the releated device is in an intermediate state, not yet turned
843 * into RPM_SUSPENDED. This means genpd_power_off() must allow one device to not
844 * be RPM_SUSPENDED, while it tries to power off the PM domain.
845 * @depth: nesting count for lockdep.
846 *
847 * If all of the @genpd's devices have been suspended and all of its subdomains
848 * have been powered down, remove power from @genpd.
849 */
850 static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
851 unsigned int depth)
852 {
853 struct pm_domain_data *pdd;
854 struct gpd_link *link;
855 unsigned int not_suspended = 0;
856 int ret;
857
858 /*
859 * Do not try to power off the domain in the following situations:
860 * (1) The domain is already in the "power off" state.
861 * (2) System suspend is in progress.
862 */
863 if (!genpd_status_on(genpd) || genpd->prepared_count > 0)
864 return 0;
865
866 /*
867 * Abort power off for the PM domain in the following situations:
868 * (1) The domain is configured as always on.
869 * (2) When the domain has a subdomain being powered on.
870 */
871 if (genpd_is_always_on(genpd) ||
872 genpd_is_rpm_always_on(genpd) ||
873 atomic_read(&genpd->sd_count) > 0)
874 return -EBUSY;
875
876 /*
877 * The children must be in their deepest (powered-off) states to allow
878 * the parent to be powered off. Note that, there's no need for
879 * additional locking, as powering on a child, requires the parent's
880 * lock to be acquired first.
881 */
882 list_for_each_entry(link, &genpd->parent_links, parent_node) {
883 struct generic_pm_domain *child = link->child;
884 if (child->state_idx < child->state_count - 1)
885 return -EBUSY;
886 }
887
888 list_for_each_entry(pdd, &genpd->dev_list, list_node) {
889 /*
890 * Do not allow PM domain to be powered off, when an IRQ safe
891 * device is part of a non-IRQ safe domain.
892 */
893 if (!pm_runtime_suspended(pdd->dev) ||
894 irq_safe_dev_in_sleep_domain(pdd->dev, genpd))
895 not_suspended++;
896
897 /* The device may need its PM domain to stay powered on. */
> 898 if (to_gpd_data(pdd)->rpm_always_on)
899 return -EBUSY;
900 }
901
902 if (not_suspended > 1 || (not_suspended == 1 && !one_dev_on))
903 return -EBUSY;
904
905 if (genpd->gov && genpd->gov->power_down_ok) {
906 if (!genpd->gov->power_down_ok(&genpd->domain))
907 return -EAGAIN;
908 }
909
910 /* Default to shallowest state. */
911 if (!genpd->gov)
912 genpd->state_idx = 0;
913
914 /* Don't power off, if a child domain is waiting to power on. */
915 if (atomic_read(&genpd->sd_count) > 0)
916 return -EBUSY;
917
918 ret = _genpd_power_off(genpd, true);
919 if (ret) {
920 genpd->states[genpd->state_idx].rejected++;
921 return ret;
922 }
923
924 genpd->status = GENPD_STATE_OFF;
925 genpd_update_accounting(genpd);
926 genpd->states[genpd->state_idx].usage++;
927
928 list_for_each_entry(link, &genpd->child_links, child_node) {
929 genpd_sd_counter_dec(link->parent);
930 genpd_lock_nested(link->parent, depth + 1);
931 genpd_power_off(link->parent, false, depth + 1);
932 genpd_unlock(link->parent);
933 }
934
935 return 0;
936 }
937
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v4 7/7] scsi: ufs: rockchip: initial support for UFS
2024-11-04 10:57 ` Ulf Hansson
@ 2024-11-05 1:54 ` Shawn Lin
0 siblings, 0 replies; 20+ messages in thread
From: Shawn Lin @ 2024-11-05 1:54 UTC (permalink / raw)
To: Ulf Hansson
Cc: shawn.lin, Rob Herring, James E . J . Bottomley,
Martin K . Petersen, Krzysztof Kozlowski, Conor Dooley,
Heiko Stuebner, Rafael J . Wysocki, Manivannan Sadhasivam,
Alim Akhtar, Avri Altman, Bart Van Assche, YiFeng Zhao,
Liang Chen, linux-scsi, linux-rockchip, devicetree, linux-pm
在 2024/11/4 18:57, Ulf Hansson 写道:
> On Mon, 4 Nov 2024 at 08:34, Shawn Lin <shawn.lin@rock-chips.com> wrote:
>>
>> RK3576 SoC contains a UFS controller, add initial support for it.
>> The features are:
>> (1) support UFS 2.0 features
>> (2) High speed up to HS-G3
>> (3) 2RX-2TX lanes
>> (4) auto H8 entry and exit
>>
>> Software limitation:
>> (1) HCE procedure: enable controller->enable intr->dme_reset->dme_enable
>> (2) disable unipro timeout values before power mode change
>>
>> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
>> ---
>>
>> Changes in v4:
>> - deal with power domain of rpm and spm suggested by Ulf
>> - Fix typo and disable clks in ufs_rockchip_remove
>> - remove clk_disable_unprepare(host->ref_out_clk) from
>> ufs_rockchip_remove
>>
>
> [...]
>
>> +#ifdef CONFIG_PM
>> +static int ufs_rockchip_runtime_suspend(struct device *dev)
>> +{
>> + struct ufs_hba *hba = dev_get_drvdata(dev);
>> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
>> +
>> + clk_disable_unprepare(host->ref_out_clk);
>> +
>> + /* Shouldn't power down if rpm_lvl is less than level 5. */
>> + dev_pm_genpd_rpm_always_on(dev, hba->rpm_lvl < UFS_PM_LVL_5 ? true : false);
>> +
>> + return ufshcd_runtime_suspend(dev);
>> +}
>> +
>> +static int ufs_rockchip_runtime_resume(struct device *dev)
>> +{
>> + struct ufs_hba *hba = dev_get_drvdata(dev);
>> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
>> + int err;
>> +
>> + err = clk_prepare_enable(host->ref_out_clk);
>> + if (err) {
>> + dev_err(hba->dev, "failed to enable ref out clock %d\n", err);
>> + return err;
>> + }
>> +
>> + reset_control_assert(host->rst);
>> + usleep_range(1, 2);
>> + reset_control_deassert(host->rst);
>> +
>> + return ufshcd_runtime_resume(dev);
>> +}
>> +#endif
>> +
>> +#ifdef CONFIG_PM_SLEEP
>> +static int ufs_rockchip_system_suspend(struct device *dev)
>> +{
>> + struct ufs_hba *hba = dev_get_drvdata(dev);
>> +
>> + if (hba->spm_lvl < 5)
>> + device_set_wakeup_path(dev);
>
> Please use device_set_awake_path() instead.
>
> Ideally all users of device_set_wakeup_path() should convert into
> device_set_awake_path(), it's just that we haven't been able to
> complete the conversion yet.
Will use device_set_awake_path().
>
>> + else
>> + device_clr_wakeup_path(dev);
>
> This isn't needed. The flag is getting cleared in device_prepare().
>
>> +
>> + return ufshcd_system_suspend(dev);
>
> Don't you want to disable the clock during system suspend too? If the
> device is runtime resumed at this point, the clock will be left
> enabled, no?
Good point. Will fix it.
>
>> +}
>> +#endif
>> +
>> +static const struct dev_pm_ops ufs_rockchip_pm_ops = {
>> + SET_SYSTEM_SLEEP_PM_OPS(ufs_rockchip_system_suspend, ufshcd_system_resume)
>> + SET_RUNTIME_PM_OPS(ufs_rockchip_runtime_suspend, ufs_rockchip_runtime_resume, NULL)
>> + .prepare = ufshcd_suspend_prepare,
>> + .complete = ufshcd_resume_complete,
>> +};
>> +
>
> [...]
>
> Kind regards
> Uffe
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v4 2/7] dt-bindings: ufs: Document Rockchip UFS host controller
2024-11-04 7:31 ` [PATCH v4 2/7] dt-bindings: ufs: Document Rockchip UFS host controller Shawn Lin
@ 2024-11-07 15:42 ` Manivannan Sadhasivam
0 siblings, 0 replies; 20+ messages in thread
From: Manivannan Sadhasivam @ 2024-11-07 15:42 UTC (permalink / raw)
To: Shawn Lin
Cc: Rob Herring, James E . J . Bottomley, Martin K . Petersen,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Heiko Stuebner,
Rafael J . Wysocki, Alim Akhtar, Avri Altman, Bart Van Assche,
YiFeng Zhao, Liang Chen, linux-scsi, linux-rockchip, devicetree,
linux-pm
On Mon, Nov 04, 2024 at 03:31:56PM +0800, Shawn Lin wrote:
> Document Rockchip UFS host controller for RK3576 SoC.
>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
> ---
>
> Changes in v4:
> - properly describe reset-gpios
>
> Changes in v3:
> - rename the file to rockchip,rk3576-ufshc.yaml
> - add description for reset-gpios
> - use rockchip,rk3576-ufshc as compatible
>
> Changes in v2:
> - rename the file
> - add reset-gpios
>
> .../bindings/ufs/rockchip,rk3576-ufshc.yaml | 105 +++++++++++++++++++++
> 1 file changed, 105 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/ufs/rockchip,rk3576-ufshc.yaml
>
> diff --git a/Documentation/devicetree/bindings/ufs/rockchip,rk3576-ufshc.yaml b/Documentation/devicetree/bindings/ufs/rockchip,rk3576-ufshc.yaml
> new file mode 100644
> index 0000000..bc4c3de
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/ufs/rockchip,rk3576-ufshc.yaml
> @@ -0,0 +1,105 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/ufs/rockchip,rk3576-ufshc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip UFS Host Controller
> +
> +maintainers:
> + - Shawn Lin <shawn.lin@rock-chips.com>
> +
> +allOf:
> + - $ref: ufs-common.yaml
> +
> +properties:
> + compatible:
> + const: rockchip,rk3576-ufshc
> +
> + reg:
> + maxItems: 5
> +
> + reg-names:
> + items:
> + - const: hci
> + - const: mphy
> + - const: hci_grf
> + - const: mphy_grf
> + - const: hci_apb
> +
> + clocks:
> + maxItems: 4
> +
> + clock-names:
> + items:
> + - const: core
> + - const: pclk
> + - const: pclk_mphy
> + - const: ref_out
> +
> + power-domains:
> + maxItems: 1
> +
> + resets:
> + maxItems: 4
> +
> + reset-names:
> + items:
> + - const: biu
> + - const: sys
> + - const: ufs
> + - const: grf
> +
> + reset-gpios:
> + maxItems: 1
> + description: |
> + GPIO specifiers for host to reset the whole UFS device including PHY and
> + memory. This gpio is active low and should choose the one whose high output
> + voltage is lower than 1.5V based on the UFS spec.
> +
> +required:
> + - compatible
> + - reg
> + - reg-names
> + - clocks
> + - clock-names
> + - interrupts
> + - power-domains
> + - resets
> + - reset-names
> + - reset-gpios
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/rockchip,rk3576-cru.h>
> + #include <dt-bindings/reset/rockchip,rk3576-cru.h>
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> + #include <dt-bindings/power/rockchip,rk3576-power.h>
> + #include <dt-bindings/pinctrl/rockchip.h>
> + #include <dt-bindings/gpio/gpio.h>
> +
> + soc {
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + ufs: ufs@2a2d0000 {
Could you please use 'ufshc' as the node name as documented in the devicetree
spec?
- Mani
> + compatible = "rockchip,rk3576-ufshc";
> + reg = <0x0 0x2a2d0000 0x0 0x10000>,
> + <0x0 0x2b040000 0x0 0x10000>,
> + <0x0 0x2601f000 0x0 0x1000>,
> + <0x0 0x2603c000 0x0 0x1000>,
> + <0x0 0x2a2e0000 0x0 0x10000>;
> + reg-names = "hci", "mphy", "hci_grf", "mphy_grf", "hci_apb";
> + clocks = <&cru ACLK_UFS_SYS>, <&cru PCLK_USB_ROOT>, <&cru PCLK_MPHY>,
> + <&cru CLK_REF_UFS_CLKOUT>;
> + clock-names = "core", "pclk", "pclk_mphy", "ref_out";
> + interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
> + power-domains = <&power RK3576_PD_USB>;
> + resets = <&cru SRST_A_UFS_BIU>, <&cru SRST_A_UFS_SYS>, <&cru SRST_A_UFS>,
> + <&cru SRST_P_UFS_GRF>;
> + reset-names = "biu", "sys", "ufs", "grf";
> + reset-gpios = <&gpio4 RK_PD0 GPIO_ACTIVE_LOW>;
> + };
> + };
> --
> 2.7.4
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v4 1/7] scsi: ufs: core: Add UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE
2024-11-04 7:31 ` [PATCH v4 1/7] scsi: ufs: core: Add UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE Shawn Lin
@ 2024-11-07 15:51 ` Manivannan Sadhasivam
2024-11-08 1:04 ` Shawn Lin
0 siblings, 1 reply; 20+ messages in thread
From: Manivannan Sadhasivam @ 2024-11-07 15:51 UTC (permalink / raw)
To: Shawn Lin
Cc: Rob Herring, James E . J . Bottomley, Martin K . Petersen,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Heiko Stuebner,
Rafael J . Wysocki, Alim Akhtar, Avri Altman, Bart Van Assche,
YiFeng Zhao, Liang Chen, linux-scsi, linux-rockchip, devicetree,
linux-pm
On Mon, Nov 04, 2024 at 03:31:55PM +0800, Shawn Lin wrote:
> HCE on Rockchip SoC is different from both of ufshcd_hba_execute_hce()
> and UFSHCI_QUIRK_BROKEN_HCE case. It need to do dme_reset and dme_enable
> after enabling HCE. So in order not to abuse UFSHCI_QUIRK_BROKEN_HCE, add
> a new quirk UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE, to deal with that
> limitation.
>
> Suggested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
> ---
>
> Changes in v4:
> - fix typo
>
> Changes in v3: None
> Changes in v2: None
>
> drivers/ufs/core/ufshcd.c | 17 +++++++++++++++++
> include/ufs/ufshcd.h | 6 ++++++
> 2 files changed, 23 insertions(+)
>
> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
> index 7cab1031..4084bf9 100644
> --- a/drivers/ufs/core/ufshcd.c
> +++ b/drivers/ufs/core/ufshcd.c
> @@ -4819,6 +4819,7 @@ static int ufshcd_hba_execute_hce(struct ufs_hba *hba)
> {
> int retry_outer = 3;
> int retry_inner;
> + int ret;
>
> start:
> if (ufshcd_is_hba_active(hba))
> @@ -4865,6 +4866,22 @@ static int ufshcd_hba_execute_hce(struct ufs_hba *hba)
> /* enable UIC related interrupts */
> ufshcd_enable_intr(hba, UFSHCD_UIC_MASK);
>
> + /*
> + * Do dme_reset and dme_enable if a UFS host controller needs
> + * this procedure to actually finish HCE.
> + */
> + if (hba->quirks & UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE) {
> + ret = ufshcd_dme_reset(hba);
> + if (!ret) {
> + ret = ufshcd_dme_enable(hba);
> + if (ret)
> + dev_err(hba->dev,
> + "Failed to do dme_enable after HCE.\n");
Don't you need to return failure for this and below error paths? Probably you
need to skip post change notification as well in the case of failure.
> + } else {
> + dev_err(hba->dev, "Failed to do dme_reset after HCE.\n");
> + }
> + }
> +
> ufshcd_vops_hce_enable_notify(hba, POST_CHANGE);
Is it possible for you to carry out dme_reset() and dme_enable() in the post
change notifier of the rockchip glue driver? I'm trying to see if we can avoid
having the quirk which is only specific to Rockchip.
- Mani
>
> return 0;
> diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
> index a95282b..e939af8 100644
> --- a/include/ufs/ufshcd.h
> +++ b/include/ufs/ufshcd.h
> @@ -685,6 +685,12 @@ enum ufshcd_quirks {
> * single doorbell mode.
> */
> UFSHCD_QUIRK_BROKEN_LSDBS_CAP = 1 << 25,
> +
> + /*
> + * This quirk needs to be enabled if host controller need to
> + * do dme_reset and dme_enable after hce.
> + */
> + UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE = 1 << 26,
> };
>
> enum ufshcd_caps {
> --
> 2.7.4
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v4 1/7] scsi: ufs: core: Add UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE
2024-11-07 15:51 ` Manivannan Sadhasivam
@ 2024-11-08 1:04 ` Shawn Lin
0 siblings, 0 replies; 20+ messages in thread
From: Shawn Lin @ 2024-11-08 1:04 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: shawn.lin, Rob Herring, James E . J . Bottomley,
Martin K . Petersen, Krzysztof Kozlowski, Conor Dooley,
Ulf Hansson, Heiko Stuebner, Rafael J . Wysocki, Alim Akhtar,
Avri Altman, Bart Van Assche, YiFeng Zhao, Liang Chen, linux-scsi,
linux-rockchip, devicetree, linux-pm
Hi Mani,
在 2024/11/7 23:51, Manivannan Sadhasivam 写道:
> On Mon, Nov 04, 2024 at 03:31:55PM +0800, Shawn Lin wrote:
>> HCE on Rockchip SoC is different from both of ufshcd_hba_execute_hce()
>> and UFSHCI_QUIRK_BROKEN_HCE case. It need to do dme_reset and dme_enable
>> after enabling HCE. So in order not to abuse UFSHCI_QUIRK_BROKEN_HCE, add
>> a new quirk UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE, to deal with that
>> limitation.
>>
>> Suggested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
>> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
>> ---
>>
>> Changes in v4:
>> - fix typo
>>
>> Changes in v3: None
>> Changes in v2: None
>>
>> drivers/ufs/core/ufshcd.c | 17 +++++++++++++++++
>> include/ufs/ufshcd.h | 6 ++++++
>> 2 files changed, 23 insertions(+)
>>
>> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
>> index 7cab1031..4084bf9 100644
>> --- a/drivers/ufs/core/ufshcd.c
>> +++ b/drivers/ufs/core/ufshcd.c
>> @@ -4819,6 +4819,7 @@ static int ufshcd_hba_execute_hce(struct ufs_hba *hba)
>> {
>> int retry_outer = 3;
>> int retry_inner;
>> + int ret;
>>
>> start:
>> if (ufshcd_is_hba_active(hba))
>> @@ -4865,6 +4866,22 @@ static int ufshcd_hba_execute_hce(struct ufs_hba *hba)
>> /* enable UIC related interrupts */
>> ufshcd_enable_intr(hba, UFSHCD_UIC_MASK);
>>
>> + /*
>> + * Do dme_reset and dme_enable if a UFS host controller needs
>> + * this procedure to actually finish HCE.
>> + */
>> + if (hba->quirks & UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE) {
>> + ret = ufshcd_dme_reset(hba);
>> + if (!ret) {
>> + ret = ufshcd_dme_enable(hba);
>> + if (ret)
>> + dev_err(hba->dev,
>> + "Failed to do dme_enable after HCE.\n");
>
> Don't you need to return failure for this and below error paths? Probably you
> need to skip post change notification as well in the case of failure.
Oops, my bad.
>
>> + } else {
>> + dev_err(hba->dev, "Failed to do dme_reset after HCE.\n");
>> + }
>> + }
>> +
>> ufshcd_vops_hce_enable_notify(hba, POST_CHANGE);
>
> Is it possible for you to carry out dme_reset() and dme_enable() in the post
> change notifier of the rockchip glue driver? I'm trying to see if we can avoid
> having the quirk which is only specific to Rockchip.
>
I will check and test this approach. Thanks.
> - Mani
>
>>
>> return 0;
>> diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
>> index a95282b..e939af8 100644
>> --- a/include/ufs/ufshcd.h
>> +++ b/include/ufs/ufshcd.h
>> @@ -685,6 +685,12 @@ enum ufshcd_quirks {
>> * single doorbell mode.
>> */
>> UFSHCD_QUIRK_BROKEN_LSDBS_CAP = 1 << 25,
>> +
>> + /*
>> + * This quirk needs to be enabled if host controller need to
>> + * do dme_reset and dme_enable after hce.
>> + */
>> + UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE = 1 << 26,
>> };
>>
>> enum ufshcd_caps {
>> --
>> 2.7.4
>>
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v4 4/7] pmdomain: core: Introduce dev_pm_genpd_rpm_always_on()
2024-11-04 7:31 ` [PATCH v4 4/7] pmdomain: core: Introduce dev_pm_genpd_rpm_always_on() Shawn Lin
2024-11-04 19:04 ` kernel test robot
2024-11-04 20:17 ` kernel test robot
@ 2024-11-08 14:19 ` Dan Carpenter
2 siblings, 0 replies; 20+ messages in thread
From: Dan Carpenter @ 2024-11-08 14:19 UTC (permalink / raw)
To: oe-kbuild, Shawn Lin, Rob Herring, James E . J . Bottomley,
Martin K . Petersen, Krzysztof Kozlowski, Conor Dooley,
Ulf Hansson, Heiko Stuebner, Rafael J . Wysocki
Cc: lkp, oe-kbuild-all, Manivannan Sadhasivam, Alim Akhtar,
Avri Altman, Bart Van Assche, YiFeng Zhao, Liang Chen, linux-scsi,
linux-rockchip, devicetree, linux-pm
Hi Shawn,
kernel test robot noticed the following build warnings:
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Shawn-Lin/dt-bindings-ufs-Document-Rockchip-UFS-host-controller/20241104-191810
base: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
patch link: https://lore.kernel.org/r/1730705521-23081-5-git-send-email-shawn.lin%40rock-chips.com
patch subject: [PATCH v4 4/7] pmdomain: core: Introduce dev_pm_genpd_rpm_always_on()
config: loongarch-randconfig-r073-20241107 (https://download.01.org/0day-ci/archive/20241108/202411080432.5dWP6wRt-lkp@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 14.2.0
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202411080432.5dWP6wRt-lkp@intel.com/
New smatch warnings:
drivers/pmdomain/core.c:898 genpd_power_off() warn: curly braces intended?
vim +898 drivers/pmdomain/core.c
2da835452a08758 drivers/base/power/domain.c Ulf Hansson 2017-02-17 850 static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
2da835452a08758 drivers/base/power/domain.c Ulf Hansson 2017-02-17 851 unsigned int depth)
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 852 {
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 853 struct pm_domain_data *pdd;
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 854 struct gpd_link *link;
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 855 unsigned int not_suspended = 0;
f63816e43d90442 drivers/base/power/domain.c Ulf Hansson 2020-09-24 856 int ret;
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 857
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 858 /*
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 859 * Do not try to power off the domain in the following situations:
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 860 * (1) The domain is already in the "power off" state.
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 861 * (2) System suspend is in progress.
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 862 */
41e2c8e0060db25 drivers/base/power/domain.c Ulf Hansson 2017-03-20 863 if (!genpd_status_on(genpd) || genpd->prepared_count > 0)
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 864 return 0;
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 865
ffaa42e8a40b7f1 drivers/base/power/domain.c Ulf Hansson 2017-03-20 866 /*
ffaa42e8a40b7f1 drivers/base/power/domain.c Ulf Hansson 2017-03-20 867 * Abort power off for the PM domain in the following situations:
ffaa42e8a40b7f1 drivers/base/power/domain.c Ulf Hansson 2017-03-20 868 * (1) The domain is configured as always on.
ffaa42e8a40b7f1 drivers/base/power/domain.c Ulf Hansson 2017-03-20 869 * (2) When the domain has a subdomain being powered on.
ffaa42e8a40b7f1 drivers/base/power/domain.c Ulf Hansson 2017-03-20 870 */
ed61e18a4b4e445 drivers/base/power/domain.c Leonard Crestez 2019-04-30 871 if (genpd_is_always_on(genpd) ||
ed61e18a4b4e445 drivers/base/power/domain.c Leonard Crestez 2019-04-30 872 genpd_is_rpm_always_on(genpd) ||
ed61e18a4b4e445 drivers/base/power/domain.c Leonard Crestez 2019-04-30 873 atomic_read(&genpd->sd_count) > 0)
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 874 return -EBUSY;
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 875
e7d90cfac5510f8 drivers/base/power/domain.c Ulf Hansson 2022-02-17 876 /*
e7d90cfac5510f8 drivers/base/power/domain.c Ulf Hansson 2022-02-17 877 * The children must be in their deepest (powered-off) states to allow
e7d90cfac5510f8 drivers/base/power/domain.c Ulf Hansson 2022-02-17 878 * the parent to be powered off. Note that, there's no need for
e7d90cfac5510f8 drivers/base/power/domain.c Ulf Hansson 2022-02-17 879 * additional locking, as powering on a child, requires the parent's
e7d90cfac5510f8 drivers/base/power/domain.c Ulf Hansson 2022-02-17 880 * lock to be acquired first.
e7d90cfac5510f8 drivers/base/power/domain.c Ulf Hansson 2022-02-17 881 */
e7d90cfac5510f8 drivers/base/power/domain.c Ulf Hansson 2022-02-17 882 list_for_each_entry(link, &genpd->parent_links, parent_node) {
e7d90cfac5510f8 drivers/base/power/domain.c Ulf Hansson 2022-02-17 883 struct generic_pm_domain *child = link->child;
e7d90cfac5510f8 drivers/base/power/domain.c Ulf Hansson 2022-02-17 884 if (child->state_idx < child->state_count - 1)
e7d90cfac5510f8 drivers/base/power/domain.c Ulf Hansson 2022-02-17 885 return -EBUSY;
e7d90cfac5510f8 drivers/base/power/domain.c Ulf Hansson 2022-02-17 886 }
e7d90cfac5510f8 drivers/base/power/domain.c Ulf Hansson 2022-02-17 887
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 888 list_for_each_entry(pdd, &genpd->dev_list, list_node) {
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 889 /*
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 890 * Do not allow PM domain to be powered off, when an IRQ safe
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 891 * device is part of a non-IRQ safe domain.
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 892 */
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 893 if (!pm_runtime_suspended(pdd->dev) ||
7a02444b8fc25ac drivers/base/power/domain.c Ulf Hansson 2022-05-11 894 irq_safe_dev_in_sleep_domain(pdd->dev, genpd))
{
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 895 not_suspended++;
f0f6da10152fb8f drivers/pmdomain/core.c Ulf Hansson 2024-11-04 896
f0f6da10152fb8f drivers/pmdomain/core.c Ulf Hansson 2024-11-04 897 /* The device may need its PM domain to stay powered on. */
f0f6da10152fb8f drivers/pmdomain/core.c Ulf Hansson 2024-11-04 @898 if (to_gpd_data(pdd)->rpm_always_on)
f0f6da10152fb8f drivers/pmdomain/core.c Ulf Hansson 2024-11-04 899 return -EBUSY;
}
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 900 }
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 901
3c64649d1cf9f32 drivers/base/power/domain.c Ulf Hansson 2017-02-17 902 if (not_suspended > 1 || (not_suspended == 1 && !one_dev_on))
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 903 return -EBUSY;
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 904
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 905 if (genpd->gov && genpd->gov->power_down_ok) {
1f8728b7adc4c2b drivers/base/power/domain.c Ulf Hansson 2017-02-17 906 if (!genpd->gov->power_down_ok(&genpd->domain))
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v4 7/7] scsi: ufs: rockchip: initial support for UFS
2024-11-04 7:32 ` [PATCH v4 7/7] scsi: ufs: rockchip: initial support for UFS Shawn Lin
2024-11-04 10:57 ` Ulf Hansson
@ 2024-11-09 12:12 ` Manivannan Sadhasivam
2024-11-11 1:10 ` Shawn Lin
1 sibling, 1 reply; 20+ messages in thread
From: Manivannan Sadhasivam @ 2024-11-09 12:12 UTC (permalink / raw)
To: Shawn Lin
Cc: Rob Herring, James E . J . Bottomley, Martin K . Petersen,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Heiko Stuebner,
Rafael J . Wysocki, Alim Akhtar, Avri Altman, Bart Van Assche,
YiFeng Zhao, Liang Chen, linux-scsi, linux-rockchip, devicetree,
linux-pm
On Mon, Nov 04, 2024 at 03:32:01PM +0800, Shawn Lin wrote:
> RK3576 SoC contains a UFS controller, add initial support for it.
> The features are:
> (1) support UFS 2.0 features
> (2) High speed up to HS-G3
> (3) 2RX-2TX lanes
> (4) auto H8 entry and exit
>
> Software limitation:
> (1) HCE procedure: enable controller->enable intr->dme_reset->dme_enable
> (2) disable unipro timeout values before power mode change
>
> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
> ---
>
> Changes in v4:
> - deal with power domain of rpm and spm suggested by Ulf
> - Fix typo and disable clks in ufs_rockchip_remove
> - remove clk_disable_unprepare(host->ref_out_clk) from
> ufs_rockchip_remove
>
> Changes in v3:
> - reword Kconfig description
> - elaborate more about controller in commit msg
> - use rockchip,rk3576-ufshc for compatible
> - remove useless header file
> - remove inline for ufshcd_is_device_present
> - use usleep_range instead
> - remove initialization, reverse Xmas order
> - remove useless varibles
> - check vops for null
> - other small fixes for err path
> - remove pm_runtime_set_active
> - fix the active and inactive reset-gpios logic
> - fix rpm_lvl and spm_lvl to 5 and move to end of probe path
> - remove unnecessary system PM callbacks
> - use UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE instead
> of UFSHCI_QUIRK_BROKEN_HCE
>
> Changes in v2: None
>
> drivers/ufs/host/Kconfig | 12 ++
> drivers/ufs/host/Makefile | 1 +
> drivers/ufs/host/ufs-rockchip.c | 340 ++++++++++++++++++++++++++++++++++++++++
> drivers/ufs/host/ufs-rockchip.h | 51 ++++++
> 4 files changed, 404 insertions(+)
> create mode 100644 drivers/ufs/host/ufs-rockchip.c
> create mode 100644 drivers/ufs/host/ufs-rockchip.h
>
> diff --git a/drivers/ufs/host/Kconfig b/drivers/ufs/host/Kconfig
> index 580c8d0..191fbd7 100644
> --- a/drivers/ufs/host/Kconfig
> +++ b/drivers/ufs/host/Kconfig
> @@ -142,3 +142,15 @@ config SCSI_UFS_SPRD
>
> Select this if you have UFS controller on Unisoc chipset.
> If unsure, say N.
> +
> +config SCSI_UFS_ROCKCHIP
> + tristate "Rockchip UFS host controller driver"
> + depends on SCSI_UFSHCD_PLATFORM && (ARCH_ROCKCHIP || COMPILE_TEST)
> + help
> + This selects the Rockchip specific additions to UFSHCD platform driver.
> + UFS host on Rockchip needs some vendor specific configuration before
> + accessing the hardware which includes PHY configuration and vendor
> + specific registers.
> +
> + Select this if you have UFS controller on Rockchip chipset.
> + If unsure, say N.
> diff --git a/drivers/ufs/host/Makefile b/drivers/ufs/host/Makefile
> index 4573aea..2f97feb 100644
> --- a/drivers/ufs/host/Makefile
> +++ b/drivers/ufs/host/Makefile
> @@ -10,5 +10,6 @@ obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
> obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o
> obj-$(CONFIG_SCSI_UFS_MEDIATEK) += ufs-mediatek.o
> obj-$(CONFIG_SCSI_UFS_RENESAS) += ufs-renesas.o
> +obj-$(CONFIG_SCSI_UFS_ROCKCHIP) += ufs-rockchip.o
> obj-$(CONFIG_SCSI_UFS_SPRD) += ufs-sprd.o
> obj-$(CONFIG_SCSI_UFS_TI_J721E) += ti-j721e-ufs.o
> diff --git a/drivers/ufs/host/ufs-rockchip.c b/drivers/ufs/host/ufs-rockchip.c
> new file mode 100644
> index 0000000..9c277bc
> --- /dev/null
> +++ b/drivers/ufs/host/ufs-rockchip.c
> @@ -0,0 +1,340 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Rockchip UFS Host Controller driver
> + *
> + * Copyright (C) 2024 Rockchip Electronics Co.Ltd.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/gpio.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_domain.h>
> +#include <linux/pm_wakeup.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +#include <ufs/ufshcd.h>
> +#include <ufs/unipro.h>
> +#include "ufshcd-pltfrm.h"
> +#include "ufs-rockchip.h"
> +
> +static int ufs_rockchip_hce_enable_notify(struct ufs_hba *hba,
> + enum ufs_notify_change_status status)
> +{
> + int err = 0;
> +
> + if (status == POST_CHANGE)
> + err = ufshcd_vops_phy_initialization(hba);
return ufshcd_vops_phy_initialization()
> +
> + return err;
return 0
> +}
> +
> +static void ufs_rockchip_set_pm_lvl(struct ufs_hba *hba)
> +{
> + hba->rpm_lvl = UFS_PM_LVL_5;
Are you sure that you want to power down both the device and link during runtime
suspend?
> + hba->spm_lvl = UFS_PM_LVL_5;
> +}
> +
> +static int ufs_rockchip_rk3576_phy_init(struct ufs_hba *hba)
> +{
> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
> +
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(PA_LOCAL_TX_LCC_ENABLE, 0x0), 0x0);
> + /* enable the mphy DME_SET cfg */
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x200, 0x0), 0x40);
> + for (int i = 0; i < 2; i++) {
> + /* Configuration M-TX */
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xaa, SEL_TX_LANE0 + i), 0x06);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xa9, SEL_TX_LANE0 + i), 0x02);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xad, SEL_TX_LANE0 + i), 0x44);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xac, SEL_TX_LANE0 + i), 0xe6);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xab, SEL_TX_LANE0 + i), 0x07);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x94, SEL_TX_LANE0 + i), 0x93);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x93, SEL_TX_LANE0 + i), 0xc9);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x7f, SEL_TX_LANE0 + i), 0x00);
> + /* Configuration M-RX */
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x12, SEL_RX_LANE0 + i), 0x06);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x11, SEL_RX_LANE0 + i), 0x00);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1d, SEL_RX_LANE0 + i), 0x58);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1c, SEL_RX_LANE0 + i), 0x8c);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1b, SEL_RX_LANE0 + i), 0x02);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x25, SEL_RX_LANE0 + i), 0xf6);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x2f, SEL_RX_LANE0 + i), 0x69);
> + }
> + /* disable the mphy DME_SET cfg */
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x200, 0x0), 0x00);
> +
> + ufs_sys_writel(host->mphy_base, 0x80, 0x08C);
> + ufs_sys_writel(host->mphy_base, 0xB5, 0x110);
> + ufs_sys_writel(host->mphy_base, 0xB5, 0x250);
> +
> + ufs_sys_writel(host->mphy_base, 0x03, 0x134);
> + ufs_sys_writel(host->mphy_base, 0x03, 0x274);
> +
> + ufs_sys_writel(host->mphy_base, 0x38, 0x0E0);
> + ufs_sys_writel(host->mphy_base, 0x38, 0x220);
> +
> + ufs_sys_writel(host->mphy_base, 0x50, 0x164);
> + ufs_sys_writel(host->mphy_base, 0x50, 0x2A4);
> +
> + ufs_sys_writel(host->mphy_base, 0x80, 0x178);
> + ufs_sys_writel(host->mphy_base, 0x80, 0x2B8);
> +
> + ufs_sys_writel(host->mphy_base, 0x18, 0x1B0);
> + ufs_sys_writel(host->mphy_base, 0x18, 0x2F0);
> +
> + ufs_sys_writel(host->mphy_base, 0x03, 0x128);
> + ufs_sys_writel(host->mphy_base, 0x03, 0x268);
> +
> + ufs_sys_writel(host->mphy_base, 0x20, 0x12C);
> + ufs_sys_writel(host->mphy_base, 0x20, 0x26C);
> +
> + ufs_sys_writel(host->mphy_base, 0xC0, 0x120);
> + ufs_sys_writel(host->mphy_base, 0xC0, 0x260);
> +
> + ufs_sys_writel(host->mphy_base, 0x03, 0x094);
> +
> + ufs_sys_writel(host->mphy_base, 0x03, 0x1B4);
> + ufs_sys_writel(host->mphy_base, 0x03, 0x2F4);
> +
> + ufs_sys_writel(host->mphy_base, 0xC0, 0x08C);
> + usleep_range(1, 2);
> + ufs_sys_writel(host->mphy_base, 0x00, 0x08C);
> +
> + usleep_range(200, 250);
> + /* start link up */
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(MIB_T_DBG_CPORT_TX_ENDIAN, 0), 0x0);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(MIB_T_DBG_CPORT_RX_ENDIAN, 0), 0x0);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(N_DEVICEID, 0), 0x0);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(N_DEVICEID_VALID, 0), 0x1);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(T_PEERDEVICEID, 0), 0x1);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(T_CONNECTIONSTATE, 0), 0x1);
I assume that the PHY doesn't have any separate resources like clocks and you
just need to write these registers.
> +
> + return 0;
> +}
> +
> +static int ufs_rockchip_common_init(struct ufs_hba *hba)
> +{
> + struct device *dev = hba->dev;
> + struct platform_device *pdev = to_platform_device(dev);
> + struct ufs_rockchip_host *host;
> + int err;
Reverse Xmas tree please (but I don't insist).
> +
> + host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
> + if (!host)
> + return -ENOMEM;
> +
> + /* system control register for hci */
> + host->ufs_sys_ctrl = devm_platform_ioremap_resource_byname(pdev, "hci_grf");
> + if (IS_ERR(host->ufs_sys_ctrl))
> + return dev_err_probe(dev, PTR_ERR(host->ufs_sys_ctrl),
> + "cannot ioremap for hci system control register\n");
"Failed to map HCI system control registers"
Similar for other messages below.
> +
> + /* system control register for mphy */
> + host->ufs_phy_ctrl = devm_platform_ioremap_resource_byname(pdev, "mphy_grf");
> + if (IS_ERR(host->ufs_phy_ctrl))
> + return dev_err_probe(dev, PTR_ERR(host->ufs_phy_ctrl),
> + "cannot ioremap for mphy system control register\n");
> +
> + /* mphy base register */
> + host->mphy_base = devm_platform_ioremap_resource_byname(pdev, "mphy");
> + if (IS_ERR(host->mphy_base))
> + return dev_err_probe(dev, PTR_ERR(host->mphy_base),
> + "cannot ioremap for mphy base register\n");
> +
> + host->rst = devm_reset_control_array_get_exclusive(dev);
> + if (IS_ERR(host->rst))
> + return dev_err_probe(dev, PTR_ERR(host->rst),
> + "failed to get reset control\n");
> +
> + reset_control_assert(host->rst);
> + usleep_range(1, 2);
> + reset_control_deassert(host->rst);
> +
> + host->ref_out_clk = devm_clk_get_enabled(dev, "ref_out");
> + if (IS_ERR(host->ref_out_clk))
> + return dev_err_probe(dev, PTR_ERR(host->ref_out_clk),
> + "ref_out unavailable\n");
> +
> + host->rst_gpio = devm_gpiod_get(&pdev->dev, "reset", GPIOD_OUT_LOW);
> + if (IS_ERR(host->rst_gpio))
> + return dev_err_probe(&pdev->dev, PTR_ERR(host->rst_gpio),
> + "invalid reset-gpios property in node\n");
> +
> + host->clks[0].id = "core";
> + host->clks[1].id = "pclk";
> + host->clks[2].id = "pclk_mphy";
No need to hardcode clocks in the driver. You can just use clk_bulk_get_all() to
get the clocks from DT. DT binding should make sure that the clocks are present
in DT.
> + err = devm_clk_bulk_get_optional(dev, UFS_MAX_CLKS, host->clks);
> + if (err)
> + return dev_err_probe(dev, err, "failed to get clocks\n");
> +
> + err = clk_bulk_prepare_enable(UFS_MAX_CLKS, host->clks);
> + if (err)
> + return dev_err_probe(dev, err, "failed to enable clocks\n");
> +
> + host->hba = hba;
> +
> + ufshcd_set_variant(hba, host);
> +
> + return 0;
> +}
> +
> +static int ufs_rockchip_rk3576_init(struct ufs_hba *hba)
> +{
> + struct device *dev = hba->dev;
> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
> + int ret;
> +
> + hba->quirks = UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING |
> + UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE;
> +
> + /* Enable BKOPS when suspend */
> + hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
> + /* Enable putting device into deep sleep */
> + hba->caps |= UFSHCD_CAP_DEEPSLEEP;
> + /* Enable devfreq of UFS */
> + hba->caps |= UFSHCD_CAP_CLK_SCALING;
> + /* Enable WriteBooster */
> + hba->caps |= UFSHCD_CAP_WB_EN;
> +
> + host->pd_id = RK3576_PD_UFS;
> +
> + ret = ufs_rockchip_common_init(hba);
> + if (ret)
> + return dev_err_probe(dev, ret, "ufs common init fail\n");
> +
> + return 0;
> +}
> +
> +static int ufs_rockchip_device_reset(struct ufs_hba *hba)
> +{
> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
> +
> + /* Active the reset-gpios */
No need of this and below comment.
> + gpiod_set_value_cansleep(host->rst_gpio, 1);
> + usleep_range(20, 25);
> +
> + /* Inactive the reset-gpios */
> + gpiod_set_value_cansleep(host->rst_gpio, 0);
> + usleep_range(20, 25);
> +
> + return 0;
> +}
> +
> +static const struct ufs_hba_variant_ops ufs_hba_rk3576_vops = {
> + .name = "rk3576",
Unless you expect different variant ops for each chipset, you can just use
"rockchip".
> + .init = ufs_rockchip_rk3576_init,
> + .device_reset = ufs_rockchip_device_reset,
> + .hce_enable_notify = ufs_rockchip_hce_enable_notify,
> + .phy_initialization = ufs_rockchip_rk3576_phy_init,
> +};
> +
> +static const struct of_device_id ufs_rockchip_of_match[] = {
> + { .compatible = "rockchip,rk3576-ufshc", .data = &ufs_hba_rk3576_vops },
> +};
> +MODULE_DEVICE_TABLE(of, ufs_rockchip_of_match);
> +
> +static int ufs_rockchip_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + const struct ufs_hba_variant_ops *vops;
> + struct ufs_hba *hba;
> + int err;
> +
> + vops = device_get_match_data(dev);
> + if (!vops)
> + return dev_err_probe(dev, -EINVAL, "ufs_hba_variant_ops not defined.\n");
> +
> + err = ufshcd_pltfrm_init(pdev, vops);
> + if (err)
> + return dev_err_probe(dev, err, "ufshcd_pltfrm_init failed\n");
> +
> + hba = platform_get_drvdata(pdev);
> + /* Set the default desired pm level in case no users set via sysfs */
> + ufs_rockchip_set_pm_lvl(hba);
> +
> + return 0;
> +}
> +
> +static void ufs_rockchip_remove(struct platform_device *pdev)
> +{
> + struct ufs_hba *hba = platform_get_drvdata(pdev);
> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
> +
> + pm_runtime_forbid(&pdev->dev);
> + pm_runtime_get_noresume(&pdev->dev);
Why do you need these? You are not incrementing the refcount in probe() and
there is no auto PM involved.
> + ufshcd_remove(hba);
> + ufshcd_dealloc_host(hba);
> + clk_bulk_disable_unprepare(UFS_MAX_CLKS, host->clks);
> +}
> +
> +#ifdef CONFIG_PM
> +static int ufs_rockchip_runtime_suspend(struct device *dev)
> +{
> + struct ufs_hba *hba = dev_get_drvdata(dev);
> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
> +
> + clk_disable_unprepare(host->ref_out_clk);
> +
> + /* Shouldn't power down if rpm_lvl is less than level 5. */
> + dev_pm_genpd_rpm_always_on(dev, hba->rpm_lvl < UFS_PM_LVL_5 ? true : false);
> +
> + return ufshcd_runtime_suspend(dev);
> +}
> +
> +static int ufs_rockchip_runtime_resume(struct device *dev)
> +{
> + struct ufs_hba *hba = dev_get_drvdata(dev);
> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
> + int err;
> +
> + err = clk_prepare_enable(host->ref_out_clk);
> + if (err) {
> + dev_err(hba->dev, "failed to enable ref out clock %d\n", err);
> + return err;
> + }
> +
> + reset_control_assert(host->rst);
> + usleep_range(1, 2);
> + reset_control_deassert(host->rst);
> +
> + return ufshcd_runtime_resume(dev);
> +}
> +#endif
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int ufs_rockchip_system_suspend(struct device *dev)
> +{
> + struct ufs_hba *hba = dev_get_drvdata(dev);
> +
> + if (hba->spm_lvl < 5)
> + device_set_wakeup_path(dev);
> + else
> + device_clr_wakeup_path(dev);
This should be taken care by driver core.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v4 7/7] scsi: ufs: rockchip: initial support for UFS
2024-11-09 12:12 ` Manivannan Sadhasivam
@ 2024-11-11 1:10 ` Shawn Lin
2024-11-12 6:43 ` Manivannan Sadhasivam
0 siblings, 1 reply; 20+ messages in thread
From: Shawn Lin @ 2024-11-11 1:10 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: shawn.lin, Rob Herring, James E . J . Bottomley,
Martin K . Petersen, Krzysztof Kozlowski, Conor Dooley,
Ulf Hansson, Heiko Stuebner, Rafael J . Wysocki, Alim Akhtar,
Avri Altman, Bart Van Assche, YiFeng Zhao, Liang Chen, linux-scsi,
linux-rockchip, devicetree, linux-pm
Hi Mani,
在 2024/11/9 20:12, Manivannan Sadhasivam 写道:
> On Mon, Nov 04, 2024 at 03:32:01PM +0800, Shawn Lin wrote:
>> RK3576 SoC contains a UFS controller, add initial support for it.
>> The features are:
>> (1) support UFS 2.0 features
>> (2) High speed up to HS-G3
>> (3) 2RX-2TX lanes
>> (4) auto H8 entry and exit
>>
>> Software limitation:
>> (1) HCE procedure: enable controller->enable intr->dme_reset->dme_enable
>> (2) disable unipro timeout values before power mode change
>>
>> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
>> ---
>>
>> Changes in v4:
>> - deal with power domain of rpm and spm suggested by Ulf
>> - Fix typo and disable clks in ufs_rockchip_remove
>> - remove clk_disable_unprepare(host->ref_out_clk) from
>> ufs_rockchip_remove
>>
>> Changes in v3:
>> - reword Kconfig description
>> - elaborate more about controller in commit msg
>> - use rockchip,rk3576-ufshc for compatible
>> - remove useless header file
>> - remove inline for ufshcd_is_device_present
>> - use usleep_range instead
>> - remove initialization, reverse Xmas order
>> - remove useless varibles
>> - check vops for null
>> - other small fixes for err path
>> - remove pm_runtime_set_active
>> - fix the active and inactive reset-gpios logic
>> - fix rpm_lvl and spm_lvl to 5 and move to end of probe path
>> - remove unnecessary system PM callbacks
>> - use UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE instead
>> of UFSHCI_QUIRK_BROKEN_HCE
>>
>> Changes in v2: None
>>
>> drivers/ufs/host/Kconfig | 12 ++
>> drivers/ufs/host/Makefile | 1 +
>> drivers/ufs/host/ufs-rockchip.c | 340 ++++++++++++++++++++++++++++++++++++++++
>> drivers/ufs/host/ufs-rockchip.h | 51 ++++++
>> 4 files changed, 404 insertions(+)
>> create mode 100644 drivers/ufs/host/ufs-rockchip.c
>> create mode 100644 drivers/ufs/host/ufs-rockchip.h
>>
>> diff --git a/drivers/ufs/host/Kconfig b/drivers/ufs/host/Kconfig
>> index 580c8d0..191fbd7 100644
>> --- a/drivers/ufs/host/Kconfig
>> +++ b/drivers/ufs/host/Kconfig
>> @@ -142,3 +142,15 @@ config SCSI_UFS_SPRD
>>
>> Select this if you have UFS controller on Unisoc chipset.
>> If unsure, say N.
>> +
>> +config SCSI_UFS_ROCKCHIP
>> + tristate "Rockchip UFS host controller driver"
>> + depends on SCSI_UFSHCD_PLATFORM && (ARCH_ROCKCHIP || COMPILE_TEST)
>> + help
>> + This selects the Rockchip specific additions to UFSHCD platform driver.
>> + UFS host on Rockchip needs some vendor specific configuration before
>> + accessing the hardware which includes PHY configuration and vendor
>> + specific registers.
>> +
>> + Select this if you have UFS controller on Rockchip chipset.
>> + If unsure, say N.
>> diff --git a/drivers/ufs/host/Makefile b/drivers/ufs/host/Makefile
>> index 4573aea..2f97feb 100644
>> --- a/drivers/ufs/host/Makefile
>> +++ b/drivers/ufs/host/Makefile
>> @@ -10,5 +10,6 @@ obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
>> obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o
>> obj-$(CONFIG_SCSI_UFS_MEDIATEK) += ufs-mediatek.o
>> obj-$(CONFIG_SCSI_UFS_RENESAS) += ufs-renesas.o
>> +obj-$(CONFIG_SCSI_UFS_ROCKCHIP) += ufs-rockchip.o
>> obj-$(CONFIG_SCSI_UFS_SPRD) += ufs-sprd.o
>> obj-$(CONFIG_SCSI_UFS_TI_J721E) += ti-j721e-ufs.o
>> diff --git a/drivers/ufs/host/ufs-rockchip.c b/drivers/ufs/host/ufs-rockchip.c
>> new file mode 100644
>> index 0000000..9c277bc
>> --- /dev/null
>> +++ b/drivers/ufs/host/ufs-rockchip.c
>> @@ -0,0 +1,340 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Rockchip UFS Host Controller driver
>> + *
>> + * Copyright (C) 2024 Rockchip Electronics Co.Ltd.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/gpio.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/of.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm_domain.h>
>> +#include <linux/pm_wakeup.h>
>> +#include <linux/regmap.h>
>> +#include <linux/reset.h>
>> +
>> +#include <ufs/ufshcd.h>
>> +#include <ufs/unipro.h>
>> +#include "ufshcd-pltfrm.h"
>> +#include "ufs-rockchip.h"
>> +
>> +static int ufs_rockchip_hce_enable_notify(struct ufs_hba *hba,
>> + enum ufs_notify_change_status status)
>> +{
>> + int err = 0;
>> +
>> + if (status == POST_CHANGE)
>> + err = ufshcd_vops_phy_initialization(hba);
>
> return ufshcd_vops_phy_initialization()
>
>> +
>> + return err;
>
> return 0
Will fix this.
>
>> +}
>> +
>> +static void ufs_rockchip_set_pm_lvl(struct ufs_hba *hba)
>> +{
>> + hba->rpm_lvl = UFS_PM_LVL_5;
>
> Are you sure that you want to power down both the device and link during runtime
> suspend?
>
Yes, this is what we need for our product by default.
>> + hba->spm_lvl = UFS_PM_LVL_5;
>> +}
>> +
>> +static int ufs_rockchip_rk3576_phy_init(struct ufs_hba *hba)
>> +{
>> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
>> +
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(PA_LOCAL_TX_LCC_ENABLE, 0x0), 0x0);
>> + /* enable the mphy DME_SET cfg */
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x200, 0x0), 0x40);
>> + for (int i = 0; i < 2; i++) {
>> + /* Configuration M-TX */
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xaa, SEL_TX_LANE0 + i), 0x06);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xa9, SEL_TX_LANE0 + i), 0x02);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xad, SEL_TX_LANE0 + i), 0x44);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xac, SEL_TX_LANE0 + i), 0xe6);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xab, SEL_TX_LANE0 + i), 0x07);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x94, SEL_TX_LANE0 + i), 0x93);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x93, SEL_TX_LANE0 + i), 0xc9);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x7f, SEL_TX_LANE0 + i), 0x00);
>> + /* Configuration M-RX */
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x12, SEL_RX_LANE0 + i), 0x06);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x11, SEL_RX_LANE0 + i), 0x00);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1d, SEL_RX_LANE0 + i), 0x58);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1c, SEL_RX_LANE0 + i), 0x8c);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1b, SEL_RX_LANE0 + i), 0x02);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x25, SEL_RX_LANE0 + i), 0xf6);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x2f, SEL_RX_LANE0 + i), 0x69);
>> + }
>> + /* disable the mphy DME_SET cfg */
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x200, 0x0), 0x00);
>> +
>> + ufs_sys_writel(host->mphy_base, 0x80, 0x08C);
>> + ufs_sys_writel(host->mphy_base, 0xB5, 0x110);
>> + ufs_sys_writel(host->mphy_base, 0xB5, 0x250);
>> +
>> + ufs_sys_writel(host->mphy_base, 0x03, 0x134);
>> + ufs_sys_writel(host->mphy_base, 0x03, 0x274);
>> +
>> + ufs_sys_writel(host->mphy_base, 0x38, 0x0E0);
>> + ufs_sys_writel(host->mphy_base, 0x38, 0x220);
>> +
>> + ufs_sys_writel(host->mphy_base, 0x50, 0x164);
>> + ufs_sys_writel(host->mphy_base, 0x50, 0x2A4);
>> +
>> + ufs_sys_writel(host->mphy_base, 0x80, 0x178);
>> + ufs_sys_writel(host->mphy_base, 0x80, 0x2B8);
>> +
>> + ufs_sys_writel(host->mphy_base, 0x18, 0x1B0);
>> + ufs_sys_writel(host->mphy_base, 0x18, 0x2F0);
>> +
>> + ufs_sys_writel(host->mphy_base, 0x03, 0x128);
>> + ufs_sys_writel(host->mphy_base, 0x03, 0x268);
>> +
>> + ufs_sys_writel(host->mphy_base, 0x20, 0x12C);
>> + ufs_sys_writel(host->mphy_base, 0x20, 0x26C);
>> +
>> + ufs_sys_writel(host->mphy_base, 0xC0, 0x120);
>> + ufs_sys_writel(host->mphy_base, 0xC0, 0x260);
>> +
>> + ufs_sys_writel(host->mphy_base, 0x03, 0x094);
>> +
>> + ufs_sys_writel(host->mphy_base, 0x03, 0x1B4);
>> + ufs_sys_writel(host->mphy_base, 0x03, 0x2F4);
>> +
>> + ufs_sys_writel(host->mphy_base, 0xC0, 0x08C);
>> + usleep_range(1, 2);
>> + ufs_sys_writel(host->mphy_base, 0x00, 0x08C);
>> +
>> + usleep_range(200, 250);
>> + /* start link up */
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(MIB_T_DBG_CPORT_TX_ENDIAN, 0), 0x0);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(MIB_T_DBG_CPORT_RX_ENDIAN, 0), 0x0);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(N_DEVICEID, 0), 0x0);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(N_DEVICEID_VALID, 0), 0x1);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(T_PEERDEVICEID, 0), 0x1);
>> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(T_CONNECTIONSTATE, 0), 0x1);
>
> I assume that the PHY doesn't have any separate resources like clocks and you
> just need to write these registers.
>
yes.
>> +
>> + return 0;
>> +}
>> +
>> +static int ufs_rockchip_common_init(struct ufs_hba *hba)
>> +{
>> + struct device *dev = hba->dev;
>> + struct platform_device *pdev = to_platform_device(dev);
>> + struct ufs_rockchip_host *host;
>> + int err;
>
> Reverse Xmas tree please (but I don't insist).
Will fix.
>
>> +
>> + host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
>> + if (!host)
>> + return -ENOMEM;
>> +
>> + /* system control register for hci */
>> + host->ufs_sys_ctrl = devm_platform_ioremap_resource_byname(pdev, "hci_grf");
>> + if (IS_ERR(host->ufs_sys_ctrl))
>> + return dev_err_probe(dev, PTR_ERR(host->ufs_sys_ctrl),
>> + "cannot ioremap for hci system control register\n");
>
> "Failed to map HCI system control registers"
>
> Similar for other messages below.
>
>> +
>> + /* system control register for mphy */
>> + host->ufs_phy_ctrl = devm_platform_ioremap_resource_byname(pdev, "mphy_grf");
>> + if (IS_ERR(host->ufs_phy_ctrl))
>> + return dev_err_probe(dev, PTR_ERR(host->ufs_phy_ctrl),
>> + "cannot ioremap for mphy system control register\n");
>> +
>> + /* mphy base register */
>> + host->mphy_base = devm_platform_ioremap_resource_byname(pdev, "mphy");
>> + if (IS_ERR(host->mphy_base))
>> + return dev_err_probe(dev, PTR_ERR(host->mphy_base),
>> + "cannot ioremap for mphy base register\n");
>> +
>> + host->rst = devm_reset_control_array_get_exclusive(dev);
>> + if (IS_ERR(host->rst))
>> + return dev_err_probe(dev, PTR_ERR(host->rst),
>> + "failed to get reset control\n");
>> +
>> + reset_control_assert(host->rst);
>> + usleep_range(1, 2);
>> + reset_control_deassert(host->rst);
>> +
>> + host->ref_out_clk = devm_clk_get_enabled(dev, "ref_out");
>> + if (IS_ERR(host->ref_out_clk))
>> + return dev_err_probe(dev, PTR_ERR(host->ref_out_clk),
>> + "ref_out unavailable\n");
>> +
>> + host->rst_gpio = devm_gpiod_get(&pdev->dev, "reset", GPIOD_OUT_LOW);
>> + if (IS_ERR(host->rst_gpio))
>> + return dev_err_probe(&pdev->dev, PTR_ERR(host->rst_gpio),
>> + "invalid reset-gpios property in node\n");
>> +
>> + host->clks[0].id = "core";
>> + host->clks[1].id = "pclk";
>> + host->clks[2].id = "pclk_mphy";
>
> No need to hardcode clocks in the driver. You can just use clk_bulk_get_all() to
> get the clocks from DT. DT binding should make sure that the clocks are present
> in DT.
Good idea, will fix.
>
>> + err = devm_clk_bulk_get_optional(dev, UFS_MAX_CLKS, host->clks);
>> + if (err)
>> + return dev_err_probe(dev, err, "failed to get clocks\n");
>> +
>> + err = clk_bulk_prepare_enable(UFS_MAX_CLKS, host->clks);
>> + if (err)
>> + return dev_err_probe(dev, err, "failed to enable clocks\n");
>> +
>> + host->hba = hba;
>> +
>> + ufshcd_set_variant(hba, host);
>> +
>> + return 0;
>> +}
>> +
>> +static int ufs_rockchip_rk3576_init(struct ufs_hba *hba)
>> +{
>> + struct device *dev = hba->dev;
>> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
>> + int ret;
>> +
>> + hba->quirks = UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING |
>> + UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE;
>> +
>> + /* Enable BKOPS when suspend */
>> + hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
>> + /* Enable putting device into deep sleep */
>> + hba->caps |= UFSHCD_CAP_DEEPSLEEP;
>> + /* Enable devfreq of UFS */
>> + hba->caps |= UFSHCD_CAP_CLK_SCALING;
>> + /* Enable WriteBooster */
>> + hba->caps |= UFSHCD_CAP_WB_EN;
>> +
>> + host->pd_id = RK3576_PD_UFS;
>> +
>> + ret = ufs_rockchip_common_init(hba);
>> + if (ret)
>> + return dev_err_probe(dev, ret, "ufs common init fail\n");
>> +
>> + return 0;
>> +}
>> +
>> +static int ufs_rockchip_device_reset(struct ufs_hba *hba)
>> +{
>> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
>> +
>> + /* Active the reset-gpios */
>
> No need of this and below comment.
Will remove.
>
>> + gpiod_set_value_cansleep(host->rst_gpio, 1);
>> + usleep_range(20, 25);
>> +
>> + /* Inactive the reset-gpios */
>> + gpiod_set_value_cansleep(host->rst_gpio, 0);
>> + usleep_range(20, 25);
>> +
>> + return 0;
>> +}
>> +
>> +static const struct ufs_hba_variant_ops ufs_hba_rk3576_vops = {
>> + .name = "rk3576",
>
> Unless you expect different variant ops for each chipset, you can just use
> "rockchip".
Probably we need a different variant ops, for insatnce, we may seek to
fix the hce process problem, also we probably need a different .init
process.
>
>> + .init = ufs_rockchip_rk3576_init,
>> + .device_reset = ufs_rockchip_device_reset,
>> + .hce_enable_notify = ufs_rockchip_hce_enable_notify,
>> + .phy_initialization = ufs_rockchip_rk3576_phy_init,
>> +};
>> +
>> +static const struct of_device_id ufs_rockchip_of_match[] = {
>> + { .compatible = "rockchip,rk3576-ufshc", .data = &ufs_hba_rk3576_vops },
>> +};
>> +MODULE_DEVICE_TABLE(of, ufs_rockchip_of_match);
>> +
>> +static int ufs_rockchip_probe(struct platform_device *pdev)
>> +{
>> + struct device *dev = &pdev->dev;
>> + const struct ufs_hba_variant_ops *vops;
>> + struct ufs_hba *hba;
>> + int err;
>> +
>> + vops = device_get_match_data(dev);
>> + if (!vops)
>> + return dev_err_probe(dev, -EINVAL, "ufs_hba_variant_ops not defined.\n");
>> +
>> + err = ufshcd_pltfrm_init(pdev, vops);
>> + if (err)
>> + return dev_err_probe(dev, err, "ufshcd_pltfrm_init failed\n");
>> +
>> + hba = platform_get_drvdata(pdev);
>> + /* Set the default desired pm level in case no users set via sysfs */
>> + ufs_rockchip_set_pm_lvl(hba);
>> +
>> + return 0;
>> +}
>> +
>> +static void ufs_rockchip_remove(struct platform_device *pdev)
>> +{
>> + struct ufs_hba *hba = platform_get_drvdata(pdev);
>> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
>> +
>> + pm_runtime_forbid(&pdev->dev);
>> + pm_runtime_get_noresume(&pdev->dev);
>
> Why do you need these? You are not incrementing the refcount in probe() and
> there is no auto PM involved.
Oh, it was a leftover from former version I haven't noticed. Will
remove.
>
>> + ufshcd_remove(hba);
>> + ufshcd_dealloc_host(hba);
>> + clk_bulk_disable_unprepare(UFS_MAX_CLKS, host->clks);
>> +}
>> +
>> +#ifdef CONFIG_PM
>> +static int ufs_rockchip_runtime_suspend(struct device *dev)
>> +{
>> + struct ufs_hba *hba = dev_get_drvdata(dev);
>> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
>> +
>> + clk_disable_unprepare(host->ref_out_clk);
>> +
>> + /* Shouldn't power down if rpm_lvl is less than level 5. */
>> + dev_pm_genpd_rpm_always_on(dev, hba->rpm_lvl < UFS_PM_LVL_5 ? true : false);
>> +
>> + return ufshcd_runtime_suspend(dev);
>> +}
>> +
>> +static int ufs_rockchip_runtime_resume(struct device *dev)
>> +{
>> + struct ufs_hba *hba = dev_get_drvdata(dev);
>> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
>> + int err;
>> +
>> + err = clk_prepare_enable(host->ref_out_clk);
>> + if (err) {
>> + dev_err(hba->dev, "failed to enable ref out clock %d\n", err);
>> + return err;
>> + }
>> +
>> + reset_control_assert(host->rst);
>> + usleep_range(1, 2);
>> + reset_control_deassert(host->rst);
>> +
>> + return ufshcd_runtime_resume(dev);
>> +}
>> +#endif
>> +
>> +#ifdef CONFIG_PM_SLEEP
>> +static int ufs_rockchip_system_suspend(struct device *dev)
>> +{
>> + struct ufs_hba *hba = dev_get_drvdata(dev);
>> +
>> + if (hba->spm_lvl < 5)
>> + device_set_wakeup_path(dev);
>> + else
>> + device_clr_wakeup_path(dev);
>
> This should be taken care by driver core.
>
> - Mani
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v4 7/7] scsi: ufs: rockchip: initial support for UFS
2024-11-11 1:10 ` Shawn Lin
@ 2024-11-12 6:43 ` Manivannan Sadhasivam
2024-11-12 6:51 ` Shawn Lin
0 siblings, 1 reply; 20+ messages in thread
From: Manivannan Sadhasivam @ 2024-11-12 6:43 UTC (permalink / raw)
To: Shawn Lin
Cc: Rob Herring, James E . J . Bottomley, Martin K . Petersen,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Heiko Stuebner,
Rafael J . Wysocki, Alim Akhtar, Avri Altman, Bart Van Assche,
YiFeng Zhao, Liang Chen, linux-scsi, linux-rockchip, devicetree,
linux-pm
On Mon, Nov 11, 2024 at 09:10:39AM +0800, Shawn Lin wrote:
[...]
> > > +static void ufs_rockchip_remove(struct platform_device *pdev)
> > > +{
> > > + struct ufs_hba *hba = platform_get_drvdata(pdev);
> > > + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
> > > +
> > > + pm_runtime_forbid(&pdev->dev);
> > > + pm_runtime_get_noresume(&pdev->dev);
> >
> > Why do you need these? You are not incrementing the refcount in probe() and
> > there is no auto PM involved.
>
> Oh, it was a leftover from former version I haven't noticed. Will
> remove.
>
I've sent a series [1] that addresses the runtime PM issues. Could you please
give it a try and give your tested-by maybe?
- Mani
[1] https://lore.kernel.org/linux-scsi/20241111-ufs_bug_fix-v1-0-45ad8b62f02e@linaro.org/
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v4 7/7] scsi: ufs: rockchip: initial support for UFS
2024-11-12 6:43 ` Manivannan Sadhasivam
@ 2024-11-12 6:51 ` Shawn Lin
0 siblings, 0 replies; 20+ messages in thread
From: Shawn Lin @ 2024-11-12 6:51 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: shawn.lin, Rob Herring, James E . J . Bottomley,
Martin K . Petersen, Krzysztof Kozlowski, Conor Dooley,
Ulf Hansson, Heiko Stuebner, Rafael J . Wysocki, Alim Akhtar,
Avri Altman, Bart Van Assche, YiFeng Zhao, Liang Chen, linux-scsi,
linux-rockchip, devicetree, linux-pm
在 2024/11/12 14:43, Manivannan Sadhasivam 写道:
> On Mon, Nov 11, 2024 at 09:10:39AM +0800, Shawn Lin wrote:
>
> [...]
>
>>>> +static void ufs_rockchip_remove(struct platform_device *pdev)
>>>> +{
>>>> + struct ufs_hba *hba = platform_get_drvdata(pdev);
>>>> + struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
>>>> +
>>>> + pm_runtime_forbid(&pdev->dev);
>>>> + pm_runtime_get_noresume(&pdev->dev);
>>>
>>> Why do you need these? You are not incrementing the refcount in probe() and
>>> there is no auto PM involved.
>>
>> Oh, it was a leftover from former version I haven't noticed. Will
>> remove.
>>
>
> I've sent a series [1] that addresses the runtime PM issues. Could you please
> give it a try and give your tested-by maybe?
Sure, I will give it a try, thanks.
>
> - Mani
>
> [1] https://lore.kernel.org/linux-scsi/20241111-ufs_bug_fix-v1-0-45ad8b62f02e@linaro.org/
>
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2024-11-12 7:26 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-04 7:31 [PATCH v4 0/7] Initial support for RK3576 UFS controller Shawn Lin
2024-11-04 7:31 ` [PATCH v4 1/7] scsi: ufs: core: Add UFSHCI_QUIRK_DME_RESET_ENABLE_AFTER_HCE Shawn Lin
2024-11-07 15:51 ` Manivannan Sadhasivam
2024-11-08 1:04 ` Shawn Lin
2024-11-04 7:31 ` [PATCH v4 2/7] dt-bindings: ufs: Document Rockchip UFS host controller Shawn Lin
2024-11-07 15:42 ` Manivannan Sadhasivam
2024-11-04 7:31 ` [PATCH v4 3/7] soc: rockchip: add header for suspend mode SIP interface Shawn Lin
2024-11-04 7:31 ` [PATCH v4 4/7] pmdomain: core: Introduce dev_pm_genpd_rpm_always_on() Shawn Lin
2024-11-04 19:04 ` kernel test robot
2024-11-04 20:17 ` kernel test robot
2024-11-08 14:19 ` Dan Carpenter
2024-11-04 7:31 ` [PATCH v4 5/7] pmdomain: rockchip: Add smc call to inform firmware Shawn Lin
2024-11-04 7:32 ` [PATCH v4 6/7] PM: wakeup: Add device_clr_wakeup_path() Shawn Lin
2024-11-04 7:32 ` [PATCH v4 7/7] scsi: ufs: rockchip: initial support for UFS Shawn Lin
2024-11-04 10:57 ` Ulf Hansson
2024-11-05 1:54 ` Shawn Lin
2024-11-09 12:12 ` Manivannan Sadhasivam
2024-11-11 1:10 ` Shawn Lin
2024-11-12 6:43 ` Manivannan Sadhasivam
2024-11-12 6:51 ` Shawn Lin
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).