* [PATCH v3 0/3] Add UFS RTC support
@ 2023-12-02 16:02 Bean Huo
2023-12-02 16:02 ` [PATCH v3 1/3] scsi: ufs: core: Add ufshcd_is_ufs_dev_busy() Bean Huo
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Bean Huo @ 2023-12-02 16:02 UTC (permalink / raw)
To: avri.altman, bvanassche, alim.akhtar, jejb, martin.petersen,
mani, quic_cang, quic_asutoshd, beanhuo, thomas
Cc: linux-scsi, linux-kernel, mikebi, lporzio, Bean Huo
Adding RTC support for embedded storage device UFS in its driver, it is
important for a few key reasons:
1. Helps with Regular Maintenance:
The RTC provides a basic way to keep track of time, making it useful for
scheduling routine maintenance tasks in the storage device. This includes
things like making sure data is spread
evenly across the storage to extend its life.
2. Figuring Out How Old Data Is:
The RTC helps the device estimate how long ago certain parts of the storage
were last used. This is handy for deciding when to do maintenance tasks to
keep the storage working well over time.
3. Making Devices Last Longer:
By using the RTC for regular upkeep, we can make sure the storage device lasts
longer and stays reliable. This is especially important for devices that need
to work well for a long time.
4.Fitting In with Other Devices:
The inclusion of RTC support aligns with existing UFS specifications (starting
from UFS Spec 2.0) and is consistent with the prevalent industry practice. Many
UFS devices currently on the market utilize RTC for internal timekeeping. By
ensuring compatibility with this widely adopted standard, the embedded storage
device becomes seamlessly integrable with existing hardware and software
ecosystems, reducing the risk of compatibility issues.
In short, adding RTC support to embedded storage device UFS helps with regular
upkeep, extends the device's life, ensures compatibility, and keeps everything
running smoothly with the rest of the system.
Changelog:
v2--v3:
1. Move ufshcd_is_ufs_dev_busy() to the source file ufshcd.c in patch 1/3.
2. Format commit statement in patch 2/3.
v1--v2:
1. Add a new patch "scsi: ufs: core: Add ufshcd_is_ufs_dev_busy()"
2. RTC periodic update work is disabled by default
3. Address several issues raised by Avri, Bart, and Thomas.
Bean Huo (3):
scsi: ufs: core: Add ufshcd_is_ufs_dev_busy()
scsi: ufs: core: Add UFS RTC support
scsi: ufs: core: Add sysfs node for UFS RTC update
Documentation/ABI/testing/sysfs-driver-ufs | 7 ++
drivers/ufs/core/ufs-sysfs.c | 31 +++++++
drivers/ufs/core/ufshcd.c | 96 +++++++++++++++++++++-
include/ufs/ufs.h | 15 ++++
include/ufs/ufshcd.h | 4 +
5 files changed, 149 insertions(+), 4 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 1/3] scsi: ufs: core: Add ufshcd_is_ufs_dev_busy()
2023-12-02 16:02 [PATCH v3 0/3] Add UFS RTC support Bean Huo
@ 2023-12-02 16:02 ` Bean Huo
2023-12-06 19:36 ` Avri Altman
2023-12-02 16:02 ` [PATCH v3 2/3] scsi: ufs: core: Add UFS RTC support Bean Huo
` (2 subsequent siblings)
3 siblings, 1 reply; 12+ messages in thread
From: Bean Huo @ 2023-12-02 16:02 UTC (permalink / raw)
To: avri.altman, bvanassche, alim.akhtar, jejb, martin.petersen,
mani, quic_cang, quic_asutoshd, beanhuo, thomas
Cc: linux-scsi, linux-kernel, mikebi, lporzio
From: Bean Huo <beanhuo@micron.com>
Add helper inline for retrieving whether UFS device is busy or not.
Signed-off-by: Bean Huo <beanhuo@micron.com>
---
drivers/ufs/core/ufshcd.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 68d7da02944f..f88f20f27f93 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -235,6 +235,13 @@ ufs_get_desired_pm_lvl_for_dev_link_state(enum ufs_dev_pwr_mode dev_state,
return UFS_PM_LVL_0;
}
+static inline bool ufshcd_is_ufs_dev_busy(struct ufs_hba *hba)
+{
+ return (hba->clk_gating.active_reqs || hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL ||
+ hba->outstanding_reqs || hba->outstanding_tasks || hba->active_uic_cmd ||
+ hba->uic_async_done);
+}
+
static const struct ufs_dev_quirk ufs_fixups[] = {
/* UFS cards deviations table */
{ .wmanufacturerid = UFS_VENDOR_MICRON,
@@ -1917,10 +1924,7 @@ static void ufshcd_gate_work(struct work_struct *work)
goto rel_lock;
}
- if (hba->clk_gating.active_reqs
- || hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL
- || hba->outstanding_reqs || hba->outstanding_tasks
- || hba->active_uic_cmd || hba->uic_async_done)
+ if (ufshcd_is_ufs_dev_busy(hba))
goto rel_lock;
spin_unlock_irqrestore(hba->host->host_lock, flags);
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 2/3] scsi: ufs: core: Add UFS RTC support
2023-12-02 16:02 [PATCH v3 0/3] Add UFS RTC support Bean Huo
2023-12-02 16:02 ` [PATCH v3 1/3] scsi: ufs: core: Add ufshcd_is_ufs_dev_busy() Bean Huo
@ 2023-12-02 16:02 ` Bean Huo
2023-12-04 12:13 ` Avri Altman
` (2 more replies)
2023-12-02 16:02 ` [PATCH v3 3/3] scsi: ufs: core: Add sysfs node for UFS RTC update Bean Huo
2023-12-06 17:08 ` [PATCH v3 0/3] Add UFS RTC support Bean Huo
3 siblings, 3 replies; 12+ messages in thread
From: Bean Huo @ 2023-12-02 16:02 UTC (permalink / raw)
To: avri.altman, bvanassche, alim.akhtar, jejb, martin.petersen,
mani, quic_cang, quic_asutoshd, beanhuo, thomas
Cc: linux-scsi, linux-kernel, mikebi, lporzio
From: Bean Huo <beanhuo@micron.com>
Add Real Time Clock (RTC) support for UFS device. This enhancement is crucial
for the internal maintenance operations of the UFS device. The patch enables
the device to handle both absolute and relative time information. Furthermore,
it includes periodic task to update the RTC in accordance with the UFS Spec,
ensuring the accuracy of RTC information for the device's internal processes.
RTC and qTimestamp serve distinct purposes. The RTC provides a coarse level
of granularity with, at best, approximate single-second resolution. This makes
the RTC well-suited for the device to determine the approximate age of programmed
blocks after being updated by the host. On the other hand, qTimestamp offers
nanosecond granularity and is specifically designed for synchronizing Device
Error Log entries with corresponding host-side logs.
Given that the RTC has been a standard feature since UFS Spec 2.0, and qTimestamp
was introduced in UFS Spec 4.0, the majority of UFS devices currently on the
market rely on RTC. Therefore, it is advisable to continue supporting RTC in
the Linux kernel. This ensures compatibility with the prevailing UFS device
implementations and facilitates seamless integration with existing hardware.
By maintaining support for RTC, we ensure broad compatibility and avoid potential
issues arising from deviations in device specifications across different UFS
versions.
Signed-off-by: Bean Huo <beanhuo@micron.com>
Signed-off-by: Mike Bi <mikebi@micron.com>
Signed-off-by: Luca Porzio <lporzio@micron.com>
---
drivers/ufs/core/ufshcd.c | 77 +++++++++++++++++++++++++++++++++++++++
include/ufs/ufs.h | 14 +++++++
include/ufs/ufshcd.h | 4 ++
3 files changed, 95 insertions(+)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index f88f20f27f93..dfc660de656f 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -99,6 +99,9 @@
/* Polling time to wait for fDeviceInit */
#define FDEVICEINIT_COMPL_TIMEOUT 1500 /* millisecs */
+/* Default RTC update every 10 seconds */
+#define UFS_RTC_UPDATE_INTERVAL_MS (10 * MSEC_PER_SEC)
+
/* UFSHC 4.0 compliant HC support this mode. */
static bool use_mcq_mode = true;
@@ -684,6 +687,8 @@ static void ufshcd_device_reset(struct ufs_hba *hba)
hba->dev_info.wb_enabled = false;
hba->dev_info.wb_buf_flush_enabled = false;
}
+ if (hba->dev_info.rtc_type == UFS_RTC_RELATIVE)
+ hba->dev_info.rtc_time_baseline = 0;
}
if (err != -EOPNOTSUPP)
ufshcd_update_evt_hist(hba, UFS_EVT_DEV_RESET, err);
@@ -8189,6 +8194,70 @@ static void ufs_fixup_device_setup(struct ufs_hba *hba)
ufshcd_vops_fixup_dev_quirks(hba);
}
+static int ufshcd_update_rtc(struct ufs_hba *hba)
+{
+ int err;
+ u32 val;
+ struct timespec64 ts64;
+
+ ktime_get_real_ts64(&ts64);
+ val = ts64.tv_sec - hba->dev_info.rtc_time_baseline;
+
+ ufshcd_rpm_get_sync(hba);
+ err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_SECONDS_PASSED,
+ 0, 0, &val);
+ ufshcd_rpm_put_sync(hba);
+
+ if (err)
+ dev_err(hba->dev, "%s: Failed to update rtc %d\n", __func__, err);
+ else if (hba->dev_info.rtc_type == UFS_RTC_RELATIVE)
+ hba->dev_info.rtc_time_baseline = ts64.tv_sec;
+
+ return err;
+}
+
+static void ufshcd_rtc_work(struct work_struct *work)
+{
+ struct ufs_hba *hba;
+ bool is_busy;
+
+ hba = container_of(to_delayed_work(work), struct ufs_hba, ufs_rtc_update_work);
+
+ is_busy = ufshcd_is_ufs_dev_busy(hba);
+ /*
+ * RTC updates should not interfere with normal IO requests; we should only update the RTC
+ * when there are no ongoing requests.
+ */
+ if (!is_busy)
+ ufshcd_update_rtc(hba);
+
+ if (ufshcd_is_ufs_dev_active(hba))
+ schedule_delayed_work(&hba->ufs_rtc_update_work,
+ msecs_to_jiffies(UFS_RTC_UPDATE_INTERVAL_MS));
+}
+
+static void ufs_init_rtc(struct ufs_hba *hba, u8 *desc_buf)
+{
+ struct ufs_dev_info *dev_info = &hba->dev_info;
+ u16 periodic_rtc_update = get_unaligned_be16(&desc_buf[DEVICE_DESC_PARAM_FRQ_RTC]);
+
+ if (periodic_rtc_update & UFS_RTC_TIME_BASELINE) {
+ dev_info->rtc_type = UFS_RTC_ABSOLUTE;
+ /*
+ * The concept of measuring time in Linux as the number of seconds elapsed since
+ * 00:00:00 UTC on January 1, 1970, and UFS ABS RTC is elapsed from January 1st
+ * 2010 00:00, here we need to adjust ABS baseline.
+ */
+ dev_info->rtc_time_baseline = mktime64(2010, 1, 1, 0, 0, 0) -
+ mktime64(1970, 1, 1, 0, 0, 0);
+ } else {
+ dev_info->rtc_type = UFS_RTC_RELATIVE;
+ dev_info->rtc_time_baseline = 0;
+ }
+
+ INIT_DELAYED_WORK(&hba->ufs_rtc_update_work, ufshcd_rtc_work);
+}
+
static int ufs_get_device_desc(struct ufs_hba *hba)
{
int err;
@@ -8241,6 +8310,8 @@ static int ufs_get_device_desc(struct ufs_hba *hba)
ufshcd_temp_notif_probe(hba, desc_buf);
+ ufs_init_rtc(hba, desc_buf);
+
if (hba->ext_iid_sup)
ufshcd_ext_iid_probe(hba, desc_buf);
@@ -8794,6 +8865,8 @@ static int ufshcd_device_init(struct ufs_hba *hba, bool init_dev_params)
ufshcd_force_reset_auto_bkops(hba);
ufshcd_set_timestamp_attr(hba);
+ schedule_delayed_work(&hba->ufs_rtc_update_work,
+ msecs_to_jiffies(UFS_RTC_UPDATE_INTERVAL_MS));
/* Gear up to HS gear if supported */
if (hba->max_pwr_info.is_valid) {
@@ -9750,6 +9823,8 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
ret = ufshcd_vops_suspend(hba, pm_op, POST_CHANGE);
if (ret)
goto set_link_active;
+
+ cancel_delayed_work_sync(&hba->ufs_rtc_update_work);
goto out;
set_link_active:
@@ -9844,6 +9919,8 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
if (ret)
goto set_old_link_state;
ufshcd_set_timestamp_attr(hba);
+ schedule_delayed_work(&hba->ufs_rtc_update_work,
+ msecs_to_jiffies(UFS_RTC_UPDATE_INTERVAL_MS));
}
if (ufshcd_keep_autobkops_enabled_except_suspend(hba))
diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h
index e77ab1786856..8022d267fe8a 100644
--- a/include/ufs/ufs.h
+++ b/include/ufs/ufs.h
@@ -14,6 +14,7 @@
#include <linux/bitops.h>
#include <linux/types.h>
#include <uapi/scsi/scsi_bsg_ufs.h>
+#include <linux/time64.h>
/*
* Using static_assert() is not allowed in UAPI header files. Hence the check
@@ -551,6 +552,15 @@ struct ufs_vreg_info {
struct ufs_vreg *vdd_hba;
};
+/*
+ * UFS device descriptor wPeriodicRTCUpdate bit9 defines RTC time baseline.
+ */
+#define UFS_RTC_TIME_BASELINE BIT(9)
+enum ufs_rtc_time {
+ UFS_RTC_RELATIVE,
+ UFS_RTC_ABSOLUTE
+};
+
struct ufs_dev_info {
bool f_power_on_wp_en;
/* Keeps information if any of the LU is power on write protected */
@@ -578,6 +588,10 @@ struct ufs_dev_info {
/* UFS EXT_IID Enable */
bool b_ext_iid_en;
+
+ /* UFS RTC */
+ enum ufs_rtc_time rtc_type;
+ time64_t rtc_time_baseline;
};
/*
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index 7f0b2c5599cd..7bdda92fcb1c 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -911,6 +911,8 @@ enum ufshcd_mcq_opr {
* @mcq_base: Multi circular queue registers base address
* @uhq: array of supported hardware queues
* @dev_cmd_queue: Queue for issuing device management commands
+ * @mcq_opr: MCQ operation and runtime registers
+ * @ufs_rtc_update_work: A work for UFS RTC periodic update
*/
struct ufs_hba {
void __iomem *mmio_base;
@@ -1071,6 +1073,8 @@ struct ufs_hba {
struct ufs_hw_queue *uhq;
struct ufs_hw_queue *dev_cmd_queue;
struct ufshcd_mcq_opr_info_t mcq_opr[OPR_MAX];
+
+ struct delayed_work ufs_rtc_update_work;
};
/**
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 3/3] scsi: ufs: core: Add sysfs node for UFS RTC update
2023-12-02 16:02 [PATCH v3 0/3] Add UFS RTC support Bean Huo
2023-12-02 16:02 ` [PATCH v3 1/3] scsi: ufs: core: Add ufshcd_is_ufs_dev_busy() Bean Huo
2023-12-02 16:02 ` [PATCH v3 2/3] scsi: ufs: core: Add UFS RTC support Bean Huo
@ 2023-12-02 16:02 ` Bean Huo
2023-12-06 19:39 ` Avri Altman
2023-12-06 17:08 ` [PATCH v3 0/3] Add UFS RTC support Bean Huo
3 siblings, 1 reply; 12+ messages in thread
From: Bean Huo @ 2023-12-02 16:02 UTC (permalink / raw)
To: avri.altman, bvanassche, alim.akhtar, jejb, martin.petersen,
mani, quic_cang, quic_asutoshd, beanhuo, thomas
Cc: linux-scsi, linux-kernel, mikebi, lporzio
From: Bean Huo <beanhuo@micron.com>
Introduce a sysfs node named 'rtc_update_ms' within the kernel, enabling
user to adjust the RTC periodic update frequency to suit the specific
requirements of the system and UFS. Also, this patch allows the user to
disable/enable periodic update RTC in the UFS idle time.
Signed-off-by: Bean Huo <beanhuo@micron.com>
---
Documentation/ABI/testing/sysfs-driver-ufs | 7 +++++
drivers/ufs/core/ufs-sysfs.c | 31 ++++++++++++++++++++++
drivers/ufs/core/ufshcd.c | 11 ++++++--
include/ufs/ufs.h | 1 +
4 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
index 0c7efaf62de0..ef1e27584fff 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -1474,3 +1474,10 @@ Description: Indicates status of Write Booster.
The file is read only.
+What: /sys/bus/platform/drivers/ufshcd/*/rtc_update_ms
+What: /sys/bus/platform/devices/*.ufs/rtc_update_ms
+Date: November 2023
+Contact: Bean Huo <beanhuo@micron.com>
+Description:
+ rtc_update_ms indicates how often the host should synchronize or update the
+ UFS RTC. If set to 0, this will disable UFS RTC periodic update.
diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c
index c95906443d5f..bb6b540ccd8e 100644
--- a/drivers/ufs/core/ufs-sysfs.c
+++ b/drivers/ufs/core/ufs-sysfs.c
@@ -255,6 +255,35 @@ static ssize_t wb_on_store(struct device *dev, struct device_attribute *attr,
return res < 0 ? res : count;
}
+static ssize_t rtc_update_ms_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%d\n", hba->dev_info.rtc_update_period);
+}
+
+static ssize_t rtc_update_ms_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+ unsigned int ms;
+ bool resume_period_update = false;
+
+ if (kstrtouint(buf, 0, &ms))
+ return -EINVAL;
+
+ if (!hba->dev_info.rtc_update_period && ms > 0)
+ resume_period_update = true;
+ /* Minimum and maximum update frequency should be synchronized with all UFS vendors */
+ hba->dev_info.rtc_update_period = ms;
+
+ if (resume_period_update)
+ schedule_delayed_work(&hba->ufs_rtc_update_work,
+ msecs_to_jiffies(hba->dev_info.rtc_update_period));
+ return count;
+}
+
static ssize_t enable_wb_buf_flush_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -339,6 +368,7 @@ static DEVICE_ATTR_RW(auto_hibern8);
static DEVICE_ATTR_RW(wb_on);
static DEVICE_ATTR_RW(enable_wb_buf_flush);
static DEVICE_ATTR_RW(wb_flush_threshold);
+static DEVICE_ATTR_RW(rtc_update_ms);
static struct attribute *ufs_sysfs_ufshcd_attrs[] = {
&dev_attr_rpm_lvl.attr,
@@ -351,6 +381,7 @@ static struct attribute *ufs_sysfs_ufshcd_attrs[] = {
&dev_attr_wb_on.attr,
&dev_attr_enable_wb_buf_flush.attr,
&dev_attr_wb_flush_threshold.attr,
+ &dev_attr_rtc_update_ms.attr,
NULL
};
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index dfc660de656f..4864d213d5d9 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -8231,9 +8231,9 @@ static void ufshcd_rtc_work(struct work_struct *work)
if (!is_busy)
ufshcd_update_rtc(hba);
- if (ufshcd_is_ufs_dev_active(hba))
+ if (ufshcd_is_ufs_dev_active(hba) && hba->dev_info.rtc_update_period)
schedule_delayed_work(&hba->ufs_rtc_update_work,
- msecs_to_jiffies(UFS_RTC_UPDATE_INTERVAL_MS));
+ msecs_to_jiffies(hba->dev_info.rtc_update_period));
}
static void ufs_init_rtc(struct ufs_hba *hba, u8 *desc_buf)
@@ -8255,6 +8255,13 @@ static void ufs_init_rtc(struct ufs_hba *hba, u8 *desc_buf)
dev_info->rtc_time_baseline = 0;
}
+ /*
+ * We ignore TIME_PERIOD defined in wPeriodicRTCUpdate because Spec does not clearly state
+ * how to calculate the specific update period for each time unit. Here we disable periodic
+ * update work, and let user configure by sysfs node according to specific circumstance.
+ */
+ hba->dev_info.rtc_update_period = 0;
+
INIT_DELAYED_WORK(&hba->ufs_rtc_update_work, ufshcd_rtc_work);
}
diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h
index 8022d267fe8a..288724d3be90 100644
--- a/include/ufs/ufs.h
+++ b/include/ufs/ufs.h
@@ -592,6 +592,7 @@ struct ufs_dev_info {
/* UFS RTC */
enum ufs_rtc_time rtc_type;
time64_t rtc_time_baseline;
+ u32 rtc_update_period;
};
/*
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v3 2/3] scsi: ufs: core: Add UFS RTC support
2023-12-02 16:02 ` [PATCH v3 2/3] scsi: ufs: core: Add UFS RTC support Bean Huo
@ 2023-12-04 12:13 ` Avri Altman
2023-12-04 12:23 ` Avri Altman
2023-12-06 19:38 ` Avri Altman
2023-12-07 0:59 ` Bart Van Assche
2 siblings, 1 reply; 12+ messages in thread
From: Avri Altman @ 2023-12-04 12:13 UTC (permalink / raw)
To: Bean Huo, bvanassche, alim.akhtar, jejb, martin.petersen, mani,
quic_cang, quic_asutoshd, beanhuo, thomas
Cc: linux-scsi, linux-kernel, mikebi, lporzio
> +static void ufs_init_rtc(struct ufs_hba *hba, u8 *desc_buf) {
> + struct ufs_dev_info *dev_info = &hba->dev_info;
> + u16 periodic_rtc_update =
> +get_unaligned_be16(&desc_buf[DEVICE_DESC_PARAM_FRQ_RTC]);
> +
> + if (periodic_rtc_update & UFS_RTC_TIME_BASELINE) {
Is it allowed to ignore the update period as depicted by wPeriodicRTCUpdate?
And choose a different update period, e.g. 10 seconds instead?
If yes - then It deserve a comment IMO.
Thanks,
Avri
> + dev_info->rtc_type = UFS_RTC_ABSOLUTE;
> + /*
> + * The concept of measuring time in Linux as the number of seconds
> elapsed since
> + * 00:00:00 UTC on January 1, 1970, and UFS ABS RTC is elapsed
> from January 1st
> + * 2010 00:00, here we need to adjust ABS baseline.
> + */
> + dev_info->rtc_time_baseline = mktime64(2010, 1, 1, 0, 0, 0) -
> + mktime64(1970, 1, 1, 0, 0, 0);
> + } else {
> + dev_info->rtc_type = UFS_RTC_RELATIVE;
> + dev_info->rtc_time_baseline = 0;
> + }
> +
> + INIT_DELAYED_WORK(&hba->ufs_rtc_update_work, ufshcd_rtc_work);
> }
> +
> static int ufs_get_device_desc(struct ufs_hba *hba) {
> int err;
> @@ -8241,6 +8310,8 @@ static int ufs_get_device_desc(struct ufs_hba
> *hba)
>
> ufshcd_temp_notif_probe(hba, desc_buf);
>
> + ufs_init_rtc(hba, desc_buf);
> +
> if (hba->ext_iid_sup)
> ufshcd_ext_iid_probe(hba, desc_buf);
>
> @@ -8794,6 +8865,8 @@ static int ufshcd_device_init(struct ufs_hba *hba,
> bool init_dev_params)
> ufshcd_force_reset_auto_bkops(hba);
>
> ufshcd_set_timestamp_attr(hba);
> + schedule_delayed_work(&hba->ufs_rtc_update_work,
> +
> + msecs_to_jiffies(UFS_RTC_UPDATE_INTERVAL_MS));
>
> /* Gear up to HS gear if supported */
> if (hba->max_pwr_info.is_valid) { @@ -9750,6 +9823,8 @@ static int
> __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
> ret = ufshcd_vops_suspend(hba, pm_op, POST_CHANGE);
> if (ret)
> goto set_link_active;
> +
> + cancel_delayed_work_sync(&hba->ufs_rtc_update_work);
> goto out;
>
> set_link_active:
> @@ -9844,6 +9919,8 @@ static int __ufshcd_wl_resume(struct ufs_hba
> *hba, enum ufs_pm_op pm_op)
> if (ret)
> goto set_old_link_state;
> ufshcd_set_timestamp_attr(hba);
> + schedule_delayed_work(&hba->ufs_rtc_update_work,
> +
> + msecs_to_jiffies(UFS_RTC_UPDATE_INTERVAL_MS));
> }
>
> if (ufshcd_keep_autobkops_enabled_except_suspend(hba))
> diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h index
> e77ab1786856..8022d267fe8a 100644
> --- a/include/ufs/ufs.h
> +++ b/include/ufs/ufs.h
> @@ -14,6 +14,7 @@
> #include <linux/bitops.h>
> #include <linux/types.h>
> #include <uapi/scsi/scsi_bsg_ufs.h>
> +#include <linux/time64.h>
>
> /*
> * Using static_assert() is not allowed in UAPI header files. Hence the check
> @@ -551,6 +552,15 @@ struct ufs_vreg_info {
> struct ufs_vreg *vdd_hba;
> };
>
> +/*
> + * UFS device descriptor wPeriodicRTCUpdate bit9 defines RTC time
> baseline.
> + */
> +#define UFS_RTC_TIME_BASELINE BIT(9)
> +enum ufs_rtc_time {
> + UFS_RTC_RELATIVE,
> + UFS_RTC_ABSOLUTE
> +};
> +
> struct ufs_dev_info {
> bool f_power_on_wp_en;
> /* Keeps information if any of the LU is power on write protected */ @@
> -578,6 +588,10 @@ struct ufs_dev_info {
>
> /* UFS EXT_IID Enable */
> bool b_ext_iid_en;
> +
> + /* UFS RTC */
> + enum ufs_rtc_time rtc_type;
> + time64_t rtc_time_baseline;
> };
>
> /*
> diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index
> 7f0b2c5599cd..7bdda92fcb1c 100644
> --- a/include/ufs/ufshcd.h
> +++ b/include/ufs/ufshcd.h
> @@ -911,6 +911,8 @@ enum ufshcd_mcq_opr {
> * @mcq_base: Multi circular queue registers base address
> * @uhq: array of supported hardware queues
> * @dev_cmd_queue: Queue for issuing device management commands
> + * @mcq_opr: MCQ operation and runtime registers
> + * @ufs_rtc_update_work: A work for UFS RTC periodic update
> */
> struct ufs_hba {
> void __iomem *mmio_base;
> @@ -1071,6 +1073,8 @@ struct ufs_hba {
> struct ufs_hw_queue *uhq;
> struct ufs_hw_queue *dev_cmd_queue;
> struct ufshcd_mcq_opr_info_t mcq_opr[OPR_MAX];
> +
> + struct delayed_work ufs_rtc_update_work;
> };
>
> /**
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v3 2/3] scsi: ufs: core: Add UFS RTC support
2023-12-04 12:13 ` Avri Altman
@ 2023-12-04 12:23 ` Avri Altman
0 siblings, 0 replies; 12+ messages in thread
From: Avri Altman @ 2023-12-04 12:23 UTC (permalink / raw)
To: Bean Huo, bvanassche, alim.akhtar, jejb, martin.petersen, mani,
quic_cang, quic_asutoshd, beanhuo, thomas
Cc: linux-scsi, linux-kernel, mikebi, lporzio
>
> > +static void ufs_init_rtc(struct ufs_hba *hba, u8 *desc_buf) {
> > + struct ufs_dev_info *dev_info = &hba->dev_info;
> > + u16 periodic_rtc_update =
> > +get_unaligned_be16(&desc_buf[DEVICE_DESC_PARAM_FRQ_RTC]);
> > +
> > + if (periodic_rtc_update & UFS_RTC_TIME_BASELINE) {
> Is it allowed to ignore the update period as depicted by
> wPeriodicRTCUpdate?
> And choose a different update period, e.g. 10 seconds instead?
> If yes - then It deserve a comment IMO.
Oh - the comment is in the 3rd patch.
Sorry - please ignore.
Thanks,
Avri
>
> Thanks,
> Avri
>
> > + dev_info->rtc_type = UFS_RTC_ABSOLUTE;
> > + /*
> > + * The concept of measuring time in Linux as the
> > + number of seconds
> > elapsed since
> > + * 00:00:00 UTC on January 1, 1970, and UFS ABS RTC is
> > + elapsed
> > from January 1st
> > + * 2010 00:00, here we need to adjust ABS baseline.
> > + */
> > + dev_info->rtc_time_baseline = mktime64(2010, 1, 1, 0, 0, 0) -
> > + mktime64(1970, 1, 1, 0, 0, 0);
> > + } else {
> > + dev_info->rtc_type = UFS_RTC_RELATIVE;
> > + dev_info->rtc_time_baseline = 0;
> > + }
> > +
> > + INIT_DELAYED_WORK(&hba->ufs_rtc_update_work,
> ufshcd_rtc_work);
> > }
> > +
> > static int ufs_get_device_desc(struct ufs_hba *hba) {
> > int err;
> > @@ -8241,6 +8310,8 @@ static int ufs_get_device_desc(struct ufs_hba
> > *hba)
> >
> > ufshcd_temp_notif_probe(hba, desc_buf);
> >
> > + ufs_init_rtc(hba, desc_buf);
> > +
> > if (hba->ext_iid_sup)
> > ufshcd_ext_iid_probe(hba, desc_buf);
> >
> > @@ -8794,6 +8865,8 @@ static int ufshcd_device_init(struct ufs_hba
> > *hba, bool init_dev_params)
> > ufshcd_force_reset_auto_bkops(hba);
> >
> > ufshcd_set_timestamp_attr(hba);
> > + schedule_delayed_work(&hba->ufs_rtc_update_work,
> > +
> > + msecs_to_jiffies(UFS_RTC_UPDATE_INTERVAL_MS));
> >
> > /* Gear up to HS gear if supported */
> > if (hba->max_pwr_info.is_valid) { @@ -9750,6 +9823,8 @@ static
> > int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
> > ret = ufshcd_vops_suspend(hba, pm_op, POST_CHANGE);
> > if (ret)
> > goto set_link_active;
> > +
> > + cancel_delayed_work_sync(&hba->ufs_rtc_update_work);
> > goto out;
> >
> > set_link_active:
> > @@ -9844,6 +9919,8 @@ static int __ufshcd_wl_resume(struct ufs_hba
> > *hba, enum ufs_pm_op pm_op)
> > if (ret)
> > goto set_old_link_state;
> > ufshcd_set_timestamp_attr(hba);
> > + schedule_delayed_work(&hba->ufs_rtc_update_work,
> > +
> > + msecs_to_jiffies(UFS_RTC_UPDATE_INTERVAL_MS));
> > }
> >
> > if (ufshcd_keep_autobkops_enabled_except_suspend(hba))
> > diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h index
> > e77ab1786856..8022d267fe8a 100644
> > --- a/include/ufs/ufs.h
> > +++ b/include/ufs/ufs.h
> > @@ -14,6 +14,7 @@
> > #include <linux/bitops.h>
> > #include <linux/types.h>
> > #include <uapi/scsi/scsi_bsg_ufs.h>
> > +#include <linux/time64.h>
> >
> > /*
> > * Using static_assert() is not allowed in UAPI header files. Hence
> > the check @@ -551,6 +552,15 @@ struct ufs_vreg_info {
> > struct ufs_vreg *vdd_hba;
> > };
> >
> > +/*
> > + * UFS device descriptor wPeriodicRTCUpdate bit9 defines RTC time
> > baseline.
> > + */
> > +#define UFS_RTC_TIME_BASELINE BIT(9)
> > +enum ufs_rtc_time {
> > + UFS_RTC_RELATIVE,
> > + UFS_RTC_ABSOLUTE
> > +};
> > +
> > struct ufs_dev_info {
> > bool f_power_on_wp_en;
> > /* Keeps information if any of the LU is power on write
> > protected */ @@
> > -578,6 +588,10 @@ struct ufs_dev_info {
> >
> > /* UFS EXT_IID Enable */
> > bool b_ext_iid_en;
> > +
> > + /* UFS RTC */
> > + enum ufs_rtc_time rtc_type;
> > + time64_t rtc_time_baseline;
> > };
> >
> > /*
> > diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index
> > 7f0b2c5599cd..7bdda92fcb1c 100644
> > --- a/include/ufs/ufshcd.h
> > +++ b/include/ufs/ufshcd.h
> > @@ -911,6 +911,8 @@ enum ufshcd_mcq_opr {
> > * @mcq_base: Multi circular queue registers base address
> > * @uhq: array of supported hardware queues
> > * @dev_cmd_queue: Queue for issuing device management commands
> > + * @mcq_opr: MCQ operation and runtime registers
> > + * @ufs_rtc_update_work: A work for UFS RTC periodic update
> > */
> > struct ufs_hba {
> > void __iomem *mmio_base;
> > @@ -1071,6 +1073,8 @@ struct ufs_hba {
> > struct ufs_hw_queue *uhq;
> > struct ufs_hw_queue *dev_cmd_queue;
> > struct ufshcd_mcq_opr_info_t mcq_opr[OPR_MAX];
> > +
> > + struct delayed_work ufs_rtc_update_work;
> > };
> >
> > /**
> > --
> > 2.34.1
> >
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 0/3] Add UFS RTC support
2023-12-02 16:02 [PATCH v3 0/3] Add UFS RTC support Bean Huo
` (2 preceding siblings ...)
2023-12-02 16:02 ` [PATCH v3 3/3] scsi: ufs: core: Add sysfs node for UFS RTC update Bean Huo
@ 2023-12-06 17:08 ` Bean Huo
3 siblings, 0 replies; 12+ messages in thread
From: Bean Huo @ 2023-12-06 17:08 UTC (permalink / raw)
To: avri.altman, bvanassche, alim.akhtar, jejb, martin.petersen,
mani, quic_cang, quic_asutoshd, beanhuo, thomas
Cc: linux-scsi, linux-kernel, mikebi, lporzio
Hi Bart, Avri and all UFS developers,
do you have any new comments and change I should?
Kind regards,
Bean
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v3 1/3] scsi: ufs: core: Add ufshcd_is_ufs_dev_busy()
2023-12-02 16:02 ` [PATCH v3 1/3] scsi: ufs: core: Add ufshcd_is_ufs_dev_busy() Bean Huo
@ 2023-12-06 19:36 ` Avri Altman
0 siblings, 0 replies; 12+ messages in thread
From: Avri Altman @ 2023-12-06 19:36 UTC (permalink / raw)
To: Bean Huo, bvanassche, alim.akhtar, jejb, martin.petersen, mani,
quic_cang, quic_asutoshd, beanhuo, thomas
Cc: linux-scsi, linux-kernel, mikebi, lporzio
>
> From: Bean Huo <beanhuo@micron.com>
>
> Add helper inline for retrieving whether UFS device is busy or not.
>
> Signed-off-by: Bean Huo <beanhuo@micron.com>
Reviewed-by: Avri Altman <avri.altman@wdc.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v3 2/3] scsi: ufs: core: Add UFS RTC support
2023-12-02 16:02 ` [PATCH v3 2/3] scsi: ufs: core: Add UFS RTC support Bean Huo
2023-12-04 12:13 ` Avri Altman
@ 2023-12-06 19:38 ` Avri Altman
2023-12-07 0:59 ` Bart Van Assche
2 siblings, 0 replies; 12+ messages in thread
From: Avri Altman @ 2023-12-06 19:38 UTC (permalink / raw)
To: Bean Huo, bvanassche, alim.akhtar, jejb, martin.petersen, mani,
quic_cang, quic_asutoshd, beanhuo, thomas
Cc: linux-scsi, linux-kernel, mikebi, lporzio
> From: Bean Huo <beanhuo@micron.com>
>
> Add Real Time Clock (RTC) support for UFS device. This enhancement is
> crucial for the internal maintenance operations of the UFS device. The patch
> enables the device to handle both absolute and relative time information.
> Furthermore, it includes periodic task to update the RTC in accordance with
> the UFS Spec, ensuring the accuracy of RTC information for the device's
> internal processes.
>
> RTC and qTimestamp serve distinct purposes. The RTC provides a coarse
> level of granularity with, at best, approximate single-second resolution. This
> makes the RTC well-suited for the device to determine the approximate age
> of programmed blocks after being updated by the host. On the other hand,
> qTimestamp offers nanosecond granularity and is specifically designed for
> synchronizing Device Error Log entries with corresponding host-side logs.
>
> Given that the RTC has been a standard feature since UFS Spec 2.0, and
> qTimestamp was introduced in UFS Spec 4.0, the majority of UFS devices
> currently on the market rely on RTC. Therefore, it is advisable to continue
> supporting RTC in the Linux kernel. This ensures compatibility with the
> prevailing UFS device implementations and facilitates seamless integration
> with existing hardware.
> By maintaining support for RTC, we ensure broad compatibility and avoid
> potential issues arising from deviations in device specifications across
> different UFS versions.
>
> Signed-off-by: Bean Huo <beanhuo@micron.com>
> Signed-off-by: Mike Bi <mikebi@micron.com>
> Signed-off-by: Luca Porzio <lporzio@micron.com>
Acked-by: Avri Altman <avri.altman@wdc.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v3 3/3] scsi: ufs: core: Add sysfs node for UFS RTC update
2023-12-02 16:02 ` [PATCH v3 3/3] scsi: ufs: core: Add sysfs node for UFS RTC update Bean Huo
@ 2023-12-06 19:39 ` Avri Altman
0 siblings, 0 replies; 12+ messages in thread
From: Avri Altman @ 2023-12-06 19:39 UTC (permalink / raw)
To: Bean Huo, bvanassche, alim.akhtar, jejb, martin.petersen, mani,
quic_cang, quic_asutoshd, beanhuo, thomas
Cc: linux-scsi, linux-kernel, mikebi, lporzio
> From: Bean Huo <beanhuo@micron.com>
>
> Introduce a sysfs node named 'rtc_update_ms' within the kernel, enabling
> user to adjust the RTC periodic update frequency to suit the specific
> requirements of the system and UFS. Also, this patch allows the user to
> disable/enable periodic update RTC in the UFS idle time.
>
> Signed-off-by: Bean Huo <beanhuo@micron.com>
Acked-by: Avri Altman <avri.altman@wdc.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 2/3] scsi: ufs: core: Add UFS RTC support
2023-12-02 16:02 ` [PATCH v3 2/3] scsi: ufs: core: Add UFS RTC support Bean Huo
2023-12-04 12:13 ` Avri Altman
2023-12-06 19:38 ` Avri Altman
@ 2023-12-07 0:59 ` Bart Van Assche
2023-12-07 23:02 ` Bean Huo
2 siblings, 1 reply; 12+ messages in thread
From: Bart Van Assche @ 2023-12-07 0:59 UTC (permalink / raw)
To: Bean Huo, avri.altman, alim.akhtar, jejb, martin.petersen, mani,
quic_cang, quic_asutoshd, beanhuo, thomas
Cc: linux-scsi, linux-kernel, mikebi, lporzio
On 12/2/23 06:02, Bean Huo wrote:
> +static int ufshcd_update_rtc(struct ufs_hba *hba)
> +{
> + int err;
> + u32 val;
> + struct timespec64 ts64;
> +
> + ktime_get_real_ts64(&ts64);
> + val = ts64.tv_sec - hba->dev_info.rtc_time_baseline;
A 64-bit value is truncated to a 32-bit value. What should happen if the
right hand side is larger than what fits into a 32-bit integer? Should
a comment perhaps be added that uptimes of more than 136 years are not
supported and also for absolute times that the above code fails after
the year 2010 + 136 = 2146?
Thanks,
Bart.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 2/3] scsi: ufs: core: Add UFS RTC support
2023-12-07 0:59 ` Bart Van Assche
@ 2023-12-07 23:02 ` Bean Huo
0 siblings, 0 replies; 12+ messages in thread
From: Bean Huo @ 2023-12-07 23:02 UTC (permalink / raw)
To: Bart Van Assche, avri.altman, alim.akhtar, jejb, martin.petersen,
mani, quic_cang, quic_asutoshd, beanhuo, thomas
Cc: linux-scsi, linux-kernel, mikebi, lporzio
On Wed, 2023-12-06 at 14:59 -1000, Bart Van Assche wrote:
> A 64-bit value is truncated to a 32-bit value. What should happen if
> the
> right hand side is larger than what fits into a 32-bit integer?
> Should
> a comment perhaps be added that uptimes of more than 136 years are
> not
> supported and also for absolute times that the above code fails after
> the year 2010 + 136 = 2146?
>
> Thanks,
>
> Bart.
Bart,
you are taking into account a broader perspective. thanks for your
review!
I will add below code in the next version:
+ if (ts64.tv_sec < hba->dev_info.rtc_time_baseline) {
+ dev_warn(hba->dev, "%s: Current time precedes previous
setting!\n", __func__);
+ return;
+ }
+ /*
+ * Absolute RTC mode has 136-year limit as of 2010. Modify UFS
Spec or choosing relative
+ * RTC mode for longer (beyond year 2146) time spans.
+ */
Kind regards,
Bean
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2023-12-07 23:02 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-02 16:02 [PATCH v3 0/3] Add UFS RTC support Bean Huo
2023-12-02 16:02 ` [PATCH v3 1/3] scsi: ufs: core: Add ufshcd_is_ufs_dev_busy() Bean Huo
2023-12-06 19:36 ` Avri Altman
2023-12-02 16:02 ` [PATCH v3 2/3] scsi: ufs: core: Add UFS RTC support Bean Huo
2023-12-04 12:13 ` Avri Altman
2023-12-04 12:23 ` Avri Altman
2023-12-06 19:38 ` Avri Altman
2023-12-07 0:59 ` Bart Van Assche
2023-12-07 23:02 ` Bean Huo
2023-12-02 16:02 ` [PATCH v3 3/3] scsi: ufs: core: Add sysfs node for UFS RTC update Bean Huo
2023-12-06 19:39 ` Avri Altman
2023-12-06 17:08 ` [PATCH v3 0/3] Add UFS RTC support Bean Huo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®