Re: [PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer

2018-03-05 Thread Adrian Hunter
On 19/02/18 08:35, Adrian Hunter wrote:
> On 18/02/18 11:45, Avri Altman wrote:
>>
>>
>>> -Original Message-
>>> From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi-
>>> ow...@vger.kernel.org] On Behalf Of Adrian Hunter
>>> Sent: Friday, February 16, 2018 2:01 PM
>>> To: Vinayak Holikatti <vinholika...@gmail.com>; Martin K. Petersen
>>> <martin.peter...@oracle.com>; James E.J. Bottomley
>>> <j...@linux.vnet.ibm.com>
>>> Cc: Stanislav Nijnikov <stanislav.nijni...@wdc.com>; Jaegeuk Kim
>>> <jaeg...@kernel.org>; Bart Van Assche <bart.vanass...@wdc.com>; linux-
>>> s...@vger.kernel.org; linux-kernel@vger.kernel.org; Michal Potomski
>>> <michalx.potom...@intel.com>; Szymon Mielczarek
>>> <szymonx.mielcza...@intel.com>
>>> Subject: [PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer
>>>
>>> UFS host controllers may support an autonomous power management
>>> feature called the Auto-Hibernate Idle Timer. The timer is set to the number
>>> of microseconds of idle time before the UFS host controller will
>>> autonomously put the link into Hibernate state. That will save power at the
>>> expense of increased latency. Any access to the host controller interface
>>> registers will automatically put the link out of Hibernate state. So once
>>> configured, the feature is transparent to the driver.
>>>
>>> Expose the Auto-Hibernate Idle Timer value via SysFS to allow users to
>>> choose between power efficiency or lower latency. Set a default value of
>>> 150 ms.
>>>
>>> Signed-off-by: Adrian Hunter <adrian.hun...@intel.com>
>>> ---
>>>  Documentation/ABI/testing/sysfs-driver-ufs | 15 ++
>>>  drivers/scsi/ufs/ufs-sysfs.c   | 77 
>>> ++
>>>  drivers/scsi/ufs/ufshcd.c  | 26 ++
>>>  drivers/scsi/ufs/ufshcd.h  |  3 ++
>>>  drivers/scsi/ufs/ufshci.h  |  7 +++
>>>  5 files changed, 128 insertions(+)
>>>
>>> diff --git a/Documentation/ABI/testing/sysfs-driver-ufs
>>> b/Documentation/ABI/testing/sysfs-driver-ufs
>>> index 07f1c2f8dbfc..c7f9441079eb 100644
>>> --- a/Documentation/ABI/testing/sysfs-driver-ufs
>>> +++ b/Documentation/ABI/testing/sysfs-driver-ufs
>>> @@ -1,3 +1,18 @@
>>> +What:  /sys/bus/*/drivers/ufshcd/*/auto_hibern8
>>> +Date:  February 2018
>>> +Contact:   linux-s...@vger.kernel.org
>>> +Description:
>>> +   This file contains the auto-hibernate idle timer setting of a
>>> +   UFS host controller. A value of '-1' means auto-hibernate is
>>> not
>>> +   supported. A value of '0' means auto-hibernate is not
>>> enabled.
>>> +   Otherwise the value is the number of microseconds of idle
>>> time
>>> +   before the UFS host controller will autonomously put the link
>>> +   into hibernate state. That will save power at the expense of
>>> +   increased latency. Note that the hardware supports 10-bit
>>> values
>>> +   with a power-of-ten multiplier which allows a maximum
>>> value of
>>> +   10230. Refer to the UFS Host Controller Interface
>>> +   specification for more details.
>>> +
>>>  What:
>>> /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
>>>  Date:  February 2018
>>>  Contact:   Stanislav Nijnikov <stanislav.nijni...@wdc.com>
>>> diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c 
>>> index
>>> cd7174d2d225..a0e38776dc92 100644

SNIP

>>> @@ -7843,6 +7863,12 @@ int ufshcd_init(struct ufs_hba *hba, void
>>> __iomem *mmio_base, unsigned int irq)
>>> UFS_SLEEP_PWR_MODE,
>>> UIC_LINK_HIBERN8_STATE);
>>>
>>> +   /* Set the default auto-hiberate idle timer value to 150 ms */
>> Your commit said you are setting an idle timer in microseconds,  Better use 
>> usec to avoid confusion? 
> 
> As the SysFS documentation says "Note that the hardware supports 10-bit
> values with a power-of-ten multiplier ... Refer to the UFS Host Controller
> Interface specification for more details.", so 150,000 us is still a value
> of 150 with a power-of-ten multiplier of 3.

Are there any other comments?


Re: [PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer

2018-03-05 Thread Adrian Hunter
On 19/02/18 08:35, Adrian Hunter wrote:
> On 18/02/18 11:45, Avri Altman wrote:
>>
>>
>>> -Original Message-
>>> From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi-
>>> ow...@vger.kernel.org] On Behalf Of Adrian Hunter
>>> Sent: Friday, February 16, 2018 2:01 PM
>>> To: Vinayak Holikatti ; Martin K. Petersen
>>> ; James E.J. Bottomley
>>> 
>>> Cc: Stanislav Nijnikov ; Jaegeuk Kim
>>> ; Bart Van Assche ; linux-
>>> s...@vger.kernel.org; linux-kernel@vger.kernel.org; Michal Potomski
>>> ; Szymon Mielczarek
>>> 
>>> Subject: [PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer
>>>
>>> UFS host controllers may support an autonomous power management
>>> feature called the Auto-Hibernate Idle Timer. The timer is set to the number
>>> of microseconds of idle time before the UFS host controller will
>>> autonomously put the link into Hibernate state. That will save power at the
>>> expense of increased latency. Any access to the host controller interface
>>> registers will automatically put the link out of Hibernate state. So once
>>> configured, the feature is transparent to the driver.
>>>
>>> Expose the Auto-Hibernate Idle Timer value via SysFS to allow users to
>>> choose between power efficiency or lower latency. Set a default value of
>>> 150 ms.
>>>
>>> Signed-off-by: Adrian Hunter 
>>> ---
>>>  Documentation/ABI/testing/sysfs-driver-ufs | 15 ++
>>>  drivers/scsi/ufs/ufs-sysfs.c   | 77 
>>> ++
>>>  drivers/scsi/ufs/ufshcd.c  | 26 ++
>>>  drivers/scsi/ufs/ufshcd.h  |  3 ++
>>>  drivers/scsi/ufs/ufshci.h  |  7 +++
>>>  5 files changed, 128 insertions(+)
>>>
>>> diff --git a/Documentation/ABI/testing/sysfs-driver-ufs
>>> b/Documentation/ABI/testing/sysfs-driver-ufs
>>> index 07f1c2f8dbfc..c7f9441079eb 100644
>>> --- a/Documentation/ABI/testing/sysfs-driver-ufs
>>> +++ b/Documentation/ABI/testing/sysfs-driver-ufs
>>> @@ -1,3 +1,18 @@
>>> +What:  /sys/bus/*/drivers/ufshcd/*/auto_hibern8
>>> +Date:  February 2018
>>> +Contact:   linux-s...@vger.kernel.org
>>> +Description:
>>> +   This file contains the auto-hibernate idle timer setting of a
>>> +   UFS host controller. A value of '-1' means auto-hibernate is
>>> not
>>> +   supported. A value of '0' means auto-hibernate is not
>>> enabled.
>>> +   Otherwise the value is the number of microseconds of idle
>>> time
>>> +   before the UFS host controller will autonomously put the link
>>> +   into hibernate state. That will save power at the expense of
>>> +   increased latency. Note that the hardware supports 10-bit
>>> values
>>> +   with a power-of-ten multiplier which allows a maximum
>>> value of
>>> +   10230. Refer to the UFS Host Controller Interface
>>> +   specification for more details.
>>> +
>>>  What:
>>> /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
>>>  Date:  February 2018
>>>  Contact:   Stanislav Nijnikov 
>>> diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c 
>>> index
>>> cd7174d2d225..a0e38776dc92 100644

SNIP

>>> @@ -7843,6 +7863,12 @@ int ufshcd_init(struct ufs_hba *hba, void
>>> __iomem *mmio_base, unsigned int irq)
>>> UFS_SLEEP_PWR_MODE,
>>> UIC_LINK_HIBERN8_STATE);
>>>
>>> +   /* Set the default auto-hiberate idle timer value to 150 ms */
>> Your commit said you are setting an idle timer in microseconds,  Better use 
>> usec to avoid confusion? 
> 
> As the SysFS documentation says "Note that the hardware supports 10-bit
> values with a power-of-ten multiplier ... Refer to the UFS Host Controller
> Interface specification for more details.", so 150,000 us is still a value
> of 150 with a power-of-ten multiplier of 3.

Are there any other comments?


Re: [PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer

2018-02-18 Thread Adrian Hunter
On 18/02/18 11:45, Avri Altman wrote:
> 
> 
>> -Original Message-
>> From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi-
>> ow...@vger.kernel.org] On Behalf Of Adrian Hunter
>> Sent: Friday, February 16, 2018 2:01 PM
>> To: Vinayak Holikatti <vinholika...@gmail.com>; Martin K. Petersen
>> <martin.peter...@oracle.com>; James E.J. Bottomley
>> <j...@linux.vnet.ibm.com>
>> Cc: Stanislav Nijnikov <stanislav.nijni...@wdc.com>; Jaegeuk Kim
>> <jaeg...@kernel.org>; Bart Van Assche <bart.vanass...@wdc.com>; linux-
>> s...@vger.kernel.org; linux-kernel@vger.kernel.org; Michal Potomski
>> <michalx.potom...@intel.com>; Szymon Mielczarek
>> <szymonx.mielcza...@intel.com>
>> Subject: [PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer
>>
>> UFS host controllers may support an autonomous power management
>> feature called the Auto-Hibernate Idle Timer. The timer is set to the number
>> of microseconds of idle time before the UFS host controller will
>> autonomously put the link into Hibernate state. That will save power at the
>> expense of increased latency. Any access to the host controller interface
>> registers will automatically put the link out of Hibernate state. So once
>> configured, the feature is transparent to the driver.
>>
>> Expose the Auto-Hibernate Idle Timer value via SysFS to allow users to
>> choose between power efficiency or lower latency. Set a default value of
>> 150 ms.
>>
>> Signed-off-by: Adrian Hunter <adrian.hun...@intel.com>
>> ---
>>  Documentation/ABI/testing/sysfs-driver-ufs | 15 ++
>>  drivers/scsi/ufs/ufs-sysfs.c   | 77 
>> ++
>>  drivers/scsi/ufs/ufshcd.c  | 26 ++
>>  drivers/scsi/ufs/ufshcd.h  |  3 ++
>>  drivers/scsi/ufs/ufshci.h  |  7 +++
>>  5 files changed, 128 insertions(+)
>>
>> diff --git a/Documentation/ABI/testing/sysfs-driver-ufs
>> b/Documentation/ABI/testing/sysfs-driver-ufs
>> index 07f1c2f8dbfc..c7f9441079eb 100644
>> --- a/Documentation/ABI/testing/sysfs-driver-ufs
>> +++ b/Documentation/ABI/testing/sysfs-driver-ufs
>> @@ -1,3 +1,18 @@
>> +What:   /sys/bus/*/drivers/ufshcd/*/auto_hibern8
>> +Date:   February 2018
>> +Contact:linux-s...@vger.kernel.org
>> +Description:
>> +This file contains the auto-hibernate idle timer setting of a
>> +UFS host controller. A value of '-1' means auto-hibernate is
>> not
>> +supported. A value of '0' means auto-hibernate is not
>> enabled.
>> +Otherwise the value is the number of microseconds of idle
>> time
>> +before the UFS host controller will autonomously put the link
>> +into hibernate state. That will save power at the expense of
>> +increased latency. Note that the hardware supports 10-bit
>> values
>> +with a power-of-ten multiplier which allows a maximum
>> value of
>> +10230. Refer to the UFS Host Controller Interface
>> +specification for more details.
>> +
>>  What:
>>  /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
>>  Date:   February 2018
>>  Contact:Stanislav Nijnikov <stanislav.nijni...@wdc.com>
>> diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c 
>> index
>> cd7174d2d225..a0e38776dc92 100644
>> --- a/drivers/scsi/ufs/ufs-sysfs.c
>> +++ b/drivers/scsi/ufs/ufs-sysfs.c
>> @@ -3,6 +3,7 @@
>>
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>
>>  #include "ufs.h"
>> @@ -123,12 +124,88 @@ static ssize_t spm_lvl_store(struct device *dev,
>>  return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, false);  }
>>
>> +static void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) {
>> +unsigned long flags;
>> +
>> +if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT))
>> +return;
>> +
>> +spin_lock_irqsave(hba->host->host_lock, flags);
>> +if (hba->ahit == ahit)
>> +goto out_unlock;
>> +hba->ahit = ahit;
>> +if (!pm_runtime_suspended(hba->dev))
>> +ufshcd_writel(hba, hba->ahit,
>> REG_AUTO_HIBERNATE_IDLE_TIMER);
>> +out_unlock:
>> +spin_unlock_irqrestore(hba->host->host_lock, flags); }
>> +
>> +/* Convert Auto-Hibernate Idl

Re: [PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer

2018-02-18 Thread Adrian Hunter
On 18/02/18 11:45, Avri Altman wrote:
> 
> 
>> -Original Message-
>> From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi-
>> ow...@vger.kernel.org] On Behalf Of Adrian Hunter
>> Sent: Friday, February 16, 2018 2:01 PM
>> To: Vinayak Holikatti ; Martin K. Petersen
>> ; James E.J. Bottomley
>> 
>> Cc: Stanislav Nijnikov ; Jaegeuk Kim
>> ; Bart Van Assche ; linux-
>> s...@vger.kernel.org; linux-kernel@vger.kernel.org; Michal Potomski
>> ; Szymon Mielczarek
>> 
>> Subject: [PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer
>>
>> UFS host controllers may support an autonomous power management
>> feature called the Auto-Hibernate Idle Timer. The timer is set to the number
>> of microseconds of idle time before the UFS host controller will
>> autonomously put the link into Hibernate state. That will save power at the
>> expense of increased latency. Any access to the host controller interface
>> registers will automatically put the link out of Hibernate state. So once
>> configured, the feature is transparent to the driver.
>>
>> Expose the Auto-Hibernate Idle Timer value via SysFS to allow users to
>> choose between power efficiency or lower latency. Set a default value of
>> 150 ms.
>>
>> Signed-off-by: Adrian Hunter 
>> ---
>>  Documentation/ABI/testing/sysfs-driver-ufs | 15 ++
>>  drivers/scsi/ufs/ufs-sysfs.c   | 77 
>> ++
>>  drivers/scsi/ufs/ufshcd.c  | 26 ++
>>  drivers/scsi/ufs/ufshcd.h  |  3 ++
>>  drivers/scsi/ufs/ufshci.h  |  7 +++
>>  5 files changed, 128 insertions(+)
>>
>> diff --git a/Documentation/ABI/testing/sysfs-driver-ufs
>> b/Documentation/ABI/testing/sysfs-driver-ufs
>> index 07f1c2f8dbfc..c7f9441079eb 100644
>> --- a/Documentation/ABI/testing/sysfs-driver-ufs
>> +++ b/Documentation/ABI/testing/sysfs-driver-ufs
>> @@ -1,3 +1,18 @@
>> +What:   /sys/bus/*/drivers/ufshcd/*/auto_hibern8
>> +Date:   February 2018
>> +Contact:linux-s...@vger.kernel.org
>> +Description:
>> +This file contains the auto-hibernate idle timer setting of a
>> +UFS host controller. A value of '-1' means auto-hibernate is
>> not
>> +supported. A value of '0' means auto-hibernate is not
>> enabled.
>> +Otherwise the value is the number of microseconds of idle
>> time
>> +before the UFS host controller will autonomously put the link
>> +into hibernate state. That will save power at the expense of
>> +increased latency. Note that the hardware supports 10-bit
>> values
>> +with a power-of-ten multiplier which allows a maximum
>> value of
>> +10230. Refer to the UFS Host Controller Interface
>> +specification for more details.
>> +
>>  What:
>>  /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
>>  Date:   February 2018
>>  Contact:Stanislav Nijnikov 
>> diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c 
>> index
>> cd7174d2d225..a0e38776dc92 100644
>> --- a/drivers/scsi/ufs/ufs-sysfs.c
>> +++ b/drivers/scsi/ufs/ufs-sysfs.c
>> @@ -3,6 +3,7 @@
>>
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>
>>  #include "ufs.h"
>> @@ -123,12 +124,88 @@ static ssize_t spm_lvl_store(struct device *dev,
>>  return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, false);  }
>>
>> +static void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) {
>> +unsigned long flags;
>> +
>> +if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT))
>> +return;
>> +
>> +spin_lock_irqsave(hba->host->host_lock, flags);
>> +if (hba->ahit == ahit)
>> +goto out_unlock;
>> +hba->ahit = ahit;
>> +if (!pm_runtime_suspended(hba->dev))
>> +ufshcd_writel(hba, hba->ahit,
>> REG_AUTO_HIBERNATE_IDLE_TIMER);
>> +out_unlock:
>> +spin_unlock_irqrestore(hba->host->host_lock, flags); }
>> +
>> +/* Convert Auto-Hibernate Idle Timer register value to microseconds */
>> +static int ufshcd_ahit_to_us(u32 ahit) {
>> +int timer = FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK, ahit);
>> +int scale = FIELD_GET(UFSHCI_AHIBERN8_SCALE_MASK, ahit);
>> +
>> +for (; scale > 0; --scale)
>> +time

RE: [PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer

2018-02-18 Thread Avri Altman


> -Original Message-
> From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi-
> ow...@vger.kernel.org] On Behalf Of Adrian Hunter
> Sent: Friday, February 16, 2018 2:01 PM
> To: Vinayak Holikatti <vinholika...@gmail.com>; Martin K. Petersen
> <martin.peter...@oracle.com>; James E.J. Bottomley
> <j...@linux.vnet.ibm.com>
> Cc: Stanislav Nijnikov <stanislav.nijni...@wdc.com>; Jaegeuk Kim
> <jaeg...@kernel.org>; Bart Van Assche <bart.vanass...@wdc.com>; linux-
> s...@vger.kernel.org; linux-kernel@vger.kernel.org; Michal Potomski
> <michalx.potom...@intel.com>; Szymon Mielczarek
> <szymonx.mielcza...@intel.com>
> Subject: [PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer
> 
> UFS host controllers may support an autonomous power management
> feature called the Auto-Hibernate Idle Timer. The timer is set to the number
> of microseconds of idle time before the UFS host controller will
> autonomously put the link into Hibernate state. That will save power at the
> expense of increased latency. Any access to the host controller interface
> registers will automatically put the link out of Hibernate state. So once
> configured, the feature is transparent to the driver.
> 
> Expose the Auto-Hibernate Idle Timer value via SysFS to allow users to
> choose between power efficiency or lower latency. Set a default value of
> 150 ms.
> 
> Signed-off-by: Adrian Hunter <adrian.hun...@intel.com>
> ---
>  Documentation/ABI/testing/sysfs-driver-ufs | 15 ++
>  drivers/scsi/ufs/ufs-sysfs.c   | 77 
> ++
>  drivers/scsi/ufs/ufshcd.c  | 26 ++
>  drivers/scsi/ufs/ufshcd.h  |  3 ++
>  drivers/scsi/ufs/ufshci.h  |  7 +++
>  5 files changed, 128 insertions(+)
> 
> diff --git a/Documentation/ABI/testing/sysfs-driver-ufs
> b/Documentation/ABI/testing/sysfs-driver-ufs
> index 07f1c2f8dbfc..c7f9441079eb 100644
> --- a/Documentation/ABI/testing/sysfs-driver-ufs
> +++ b/Documentation/ABI/testing/sysfs-driver-ufs
> @@ -1,3 +1,18 @@
> +What:/sys/bus/*/drivers/ufshcd/*/auto_hibern8
> +Date:February 2018
> +Contact: linux-s...@vger.kernel.org
> +Description:
> + This file contains the auto-hibernate idle timer setting of a
> + UFS host controller. A value of '-1' means auto-hibernate is
> not
> + supported. A value of '0' means auto-hibernate is not
> enabled.
> + Otherwise the value is the number of microseconds of idle
> time
> + before the UFS host controller will autonomously put the link
> + into hibernate state. That will save power at the expense of
> + increased latency. Note that the hardware supports 10-bit
> values
> + with a power-of-ten multiplier which allows a maximum
> value of
> + 10230. Refer to the UFS Host Controller Interface
> + specification for more details.
> +
>  What:
>   /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
>  Date:February 2018
>  Contact: Stanislav Nijnikov <stanislav.nijni...@wdc.com>
> diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index
> cd7174d2d225..a0e38776dc92 100644
> --- a/drivers/scsi/ufs/ufs-sysfs.c
> +++ b/drivers/scsi/ufs/ufs-sysfs.c
> @@ -3,6 +3,7 @@
> 
>  #include 
>  #include 
> +#include 
>  #include 
> 
>  #include "ufs.h"
> @@ -123,12 +124,88 @@ static ssize_t spm_lvl_store(struct device *dev,
>   return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, false);  }
> 
> +static void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) {
> + unsigned long flags;
> +
> + if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT))
> + return;
> +
> + spin_lock_irqsave(hba->host->host_lock, flags);
> + if (hba->ahit == ahit)
> + goto out_unlock;
> + hba->ahit = ahit;
> + if (!pm_runtime_suspended(hba->dev))
> + ufshcd_writel(hba, hba->ahit,
> REG_AUTO_HIBERNATE_IDLE_TIMER);
> +out_unlock:
> + spin_unlock_irqrestore(hba->host->host_lock, flags); }
> +
> +/* Convert Auto-Hibernate Idle Timer register value to microseconds */
> +static int ufshcd_ahit_to_us(u32 ahit) {
> + int timer = FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK, ahit);
> + int scale = FIELD_GET(UFSHCI_AHIBERN8_SCALE_MASK, ahit);
> +
> + for (; scale > 0; --scale)
> + timer *= UFSHCI_AHIBERN8_SCALE_FACTOR;
> +
> + return timer;
> +}
> +
> +/* Convert microseconds to Auto-Hi

RE: [PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer

2018-02-18 Thread Avri Altman


> -Original Message-
> From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi-
> ow...@vger.kernel.org] On Behalf Of Adrian Hunter
> Sent: Friday, February 16, 2018 2:01 PM
> To: Vinayak Holikatti ; Martin K. Petersen
> ; James E.J. Bottomley
> 
> Cc: Stanislav Nijnikov ; Jaegeuk Kim
> ; Bart Van Assche ; linux-
> s...@vger.kernel.org; linux-kernel@vger.kernel.org; Michal Potomski
> ; Szymon Mielczarek
> 
> Subject: [PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer
> 
> UFS host controllers may support an autonomous power management
> feature called the Auto-Hibernate Idle Timer. The timer is set to the number
> of microseconds of idle time before the UFS host controller will
> autonomously put the link into Hibernate state. That will save power at the
> expense of increased latency. Any access to the host controller interface
> registers will automatically put the link out of Hibernate state. So once
> configured, the feature is transparent to the driver.
> 
> Expose the Auto-Hibernate Idle Timer value via SysFS to allow users to
> choose between power efficiency or lower latency. Set a default value of
> 150 ms.
> 
> Signed-off-by: Adrian Hunter 
> ---
>  Documentation/ABI/testing/sysfs-driver-ufs | 15 ++
>  drivers/scsi/ufs/ufs-sysfs.c   | 77 
> ++
>  drivers/scsi/ufs/ufshcd.c  | 26 ++
>  drivers/scsi/ufs/ufshcd.h  |  3 ++
>  drivers/scsi/ufs/ufshci.h  |  7 +++
>  5 files changed, 128 insertions(+)
> 
> diff --git a/Documentation/ABI/testing/sysfs-driver-ufs
> b/Documentation/ABI/testing/sysfs-driver-ufs
> index 07f1c2f8dbfc..c7f9441079eb 100644
> --- a/Documentation/ABI/testing/sysfs-driver-ufs
> +++ b/Documentation/ABI/testing/sysfs-driver-ufs
> @@ -1,3 +1,18 @@
> +What:/sys/bus/*/drivers/ufshcd/*/auto_hibern8
> +Date:February 2018
> +Contact: linux-s...@vger.kernel.org
> +Description:
> + This file contains the auto-hibernate idle timer setting of a
> + UFS host controller. A value of '-1' means auto-hibernate is
> not
> + supported. A value of '0' means auto-hibernate is not
> enabled.
> + Otherwise the value is the number of microseconds of idle
> time
> + before the UFS host controller will autonomously put the link
> + into hibernate state. That will save power at the expense of
> + increased latency. Note that the hardware supports 10-bit
> values
> + with a power-of-ten multiplier which allows a maximum
> value of
> + 10230. Refer to the UFS Host Controller Interface
> + specification for more details.
> +
>  What:
>   /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
>  Date:February 2018
>  Contact: Stanislav Nijnikov 
> diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index
> cd7174d2d225..a0e38776dc92 100644
> --- a/drivers/scsi/ufs/ufs-sysfs.c
> +++ b/drivers/scsi/ufs/ufs-sysfs.c
> @@ -3,6 +3,7 @@
> 
>  #include 
>  #include 
> +#include 
>  #include 
> 
>  #include "ufs.h"
> @@ -123,12 +124,88 @@ static ssize_t spm_lvl_store(struct device *dev,
>   return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, false);  }
> 
> +static void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) {
> + unsigned long flags;
> +
> + if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT))
> + return;
> +
> + spin_lock_irqsave(hba->host->host_lock, flags);
> + if (hba->ahit == ahit)
> + goto out_unlock;
> + hba->ahit = ahit;
> + if (!pm_runtime_suspended(hba->dev))
> + ufshcd_writel(hba, hba->ahit,
> REG_AUTO_HIBERNATE_IDLE_TIMER);
> +out_unlock:
> + spin_unlock_irqrestore(hba->host->host_lock, flags); }
> +
> +/* Convert Auto-Hibernate Idle Timer register value to microseconds */
> +static int ufshcd_ahit_to_us(u32 ahit) {
> + int timer = FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK, ahit);
> + int scale = FIELD_GET(UFSHCI_AHIBERN8_SCALE_MASK, ahit);
> +
> + for (; scale > 0; --scale)
> + timer *= UFSHCI_AHIBERN8_SCALE_FACTOR;
> +
> + return timer;
> +}
> +
> +/* Convert microseconds to Auto-Hibernate Idle Timer register value */
> +static u32 ufshcd_us_to_ahit(unsigned int timer) {
> + unsigned int scale;
> +
> + for (scale = 0; timer > UFSHCI_AHIBERN8_TIMER_MASK; ++scale)
> + timer /= UFSHCI_AHIBERN8_SCALE_FACTOR;
> +
> + return FIELD_PREP(UFS

[PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer

2018-02-16 Thread Adrian Hunter
UFS host controllers may support an autonomous power management feature
called the Auto-Hibernate Idle Timer. The timer is set to the number of
microseconds of idle time before the UFS host controller will autonomously
put the link into Hibernate state. That will save power at the expense of
increased latency. Any access to the host controller interface registers
will automatically put the link out of Hibernate state. So once configured,
the feature is transparent to the driver.

Expose the Auto-Hibernate Idle Timer value via SysFS to allow users to
choose between power efficiency or lower latency. Set a default value of
150 ms.

Signed-off-by: Adrian Hunter 
---
 Documentation/ABI/testing/sysfs-driver-ufs | 15 ++
 drivers/scsi/ufs/ufs-sysfs.c   | 77 ++
 drivers/scsi/ufs/ufshcd.c  | 26 ++
 drivers/scsi/ufs/ufshcd.h  |  3 ++
 drivers/scsi/ufs/ufshci.h  |  7 +++
 5 files changed, 128 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs 
b/Documentation/ABI/testing/sysfs-driver-ufs
index 07f1c2f8dbfc..c7f9441079eb 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -1,3 +1,18 @@
+What:  /sys/bus/*/drivers/ufshcd/*/auto_hibern8
+Date:  February 2018
+Contact:   linux-s...@vger.kernel.org
+Description:
+   This file contains the auto-hibernate idle timer setting of a
+   UFS host controller. A value of '-1' means auto-hibernate is not
+   supported. A value of '0' means auto-hibernate is not enabled.
+   Otherwise the value is the number of microseconds of idle time
+   before the UFS host controller will autonomously put the link
+   into hibernate state. That will save power at the expense of
+   increased latency. Note that the hardware supports 10-bit values
+   with a power-of-ten multiplier which allows a maximum value of
+   10230. Refer to the UFS Host Controller Interface
+   specification for more details.
+
 What:  /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
 Date:  February 2018
 Contact:   Stanislav Nijnikov 
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index cd7174d2d225..a0e38776dc92 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -3,6 +3,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 #include "ufs.h"
@@ -123,12 +124,88 @@ static ssize_t spm_lvl_store(struct device *dev,
return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, false);
 }
 
+static void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit)
+{
+   unsigned long flags;
+
+   if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT))
+   return;
+
+   spin_lock_irqsave(hba->host->host_lock, flags);
+   if (hba->ahit == ahit)
+   goto out_unlock;
+   hba->ahit = ahit;
+   if (!pm_runtime_suspended(hba->dev))
+   ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER);
+out_unlock:
+   spin_unlock_irqrestore(hba->host->host_lock, flags);
+}
+
+/* Convert Auto-Hibernate Idle Timer register value to microseconds */
+static int ufshcd_ahit_to_us(u32 ahit)
+{
+   int timer = FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK, ahit);
+   int scale = FIELD_GET(UFSHCI_AHIBERN8_SCALE_MASK, ahit);
+
+   for (; scale > 0; --scale)
+   timer *= UFSHCI_AHIBERN8_SCALE_FACTOR;
+
+   return timer;
+}
+
+/* Convert microseconds to Auto-Hibernate Idle Timer register value */
+static u32 ufshcd_us_to_ahit(unsigned int timer)
+{
+   unsigned int scale;
+
+   for (scale = 0; timer > UFSHCI_AHIBERN8_TIMER_MASK; ++scale)
+   timer /= UFSHCI_AHIBERN8_SCALE_FACTOR;
+
+   return FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, timer) |
+  FIELD_PREP(UFSHCI_AHIBERN8_SCALE_MASK, scale);
+}
+
+static ssize_t auto_hibern8_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   struct ufs_hba *hba = dev_get_drvdata(dev);
+   int timer = -1;
+
+   if (hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT)
+   timer = ufshcd_ahit_to_us(hba->ahit);
+
+   return snprintf(buf, PAGE_SIZE, "%d\n", timer);
+}
+
+static ssize_t auto_hibern8_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+   struct ufs_hba *hba = dev_get_drvdata(dev);
+   unsigned int timer;
+
+   if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT))
+   return -EOPNOTSUPP;
+
+   if (kstrtouint(buf, 0, ))
+   return -EINVAL;
+
+   if (timer > UFSHCI_AHIBERN8_MAX)
+   return -EINVAL;
+
+   

[PATCH 1/1] scsi: ufs: Add support for Auto-Hibernate Idle Timer

2018-02-16 Thread Adrian Hunter
UFS host controllers may support an autonomous power management feature
called the Auto-Hibernate Idle Timer. The timer is set to the number of
microseconds of idle time before the UFS host controller will autonomously
put the link into Hibernate state. That will save power at the expense of
increased latency. Any access to the host controller interface registers
will automatically put the link out of Hibernate state. So once configured,
the feature is transparent to the driver.

Expose the Auto-Hibernate Idle Timer value via SysFS to allow users to
choose between power efficiency or lower latency. Set a default value of
150 ms.

Signed-off-by: Adrian Hunter 
---
 Documentation/ABI/testing/sysfs-driver-ufs | 15 ++
 drivers/scsi/ufs/ufs-sysfs.c   | 77 ++
 drivers/scsi/ufs/ufshcd.c  | 26 ++
 drivers/scsi/ufs/ufshcd.h  |  3 ++
 drivers/scsi/ufs/ufshci.h  |  7 +++
 5 files changed, 128 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-driver-ufs 
b/Documentation/ABI/testing/sysfs-driver-ufs
index 07f1c2f8dbfc..c7f9441079eb 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -1,3 +1,18 @@
+What:  /sys/bus/*/drivers/ufshcd/*/auto_hibern8
+Date:  February 2018
+Contact:   linux-s...@vger.kernel.org
+Description:
+   This file contains the auto-hibernate idle timer setting of a
+   UFS host controller. A value of '-1' means auto-hibernate is not
+   supported. A value of '0' means auto-hibernate is not enabled.
+   Otherwise the value is the number of microseconds of idle time
+   before the UFS host controller will autonomously put the link
+   into hibernate state. That will save power at the expense of
+   increased latency. Note that the hardware supports 10-bit values
+   with a power-of-ten multiplier which allows a maximum value of
+   10230. Refer to the UFS Host Controller Interface
+   specification for more details.
+
 What:  /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type
 Date:  February 2018
 Contact:   Stanislav Nijnikov 
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index cd7174d2d225..a0e38776dc92 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -3,6 +3,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 #include "ufs.h"
@@ -123,12 +124,88 @@ static ssize_t spm_lvl_store(struct device *dev,
return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, false);
 }
 
+static void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit)
+{
+   unsigned long flags;
+
+   if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT))
+   return;
+
+   spin_lock_irqsave(hba->host->host_lock, flags);
+   if (hba->ahit == ahit)
+   goto out_unlock;
+   hba->ahit = ahit;
+   if (!pm_runtime_suspended(hba->dev))
+   ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER);
+out_unlock:
+   spin_unlock_irqrestore(hba->host->host_lock, flags);
+}
+
+/* Convert Auto-Hibernate Idle Timer register value to microseconds */
+static int ufshcd_ahit_to_us(u32 ahit)
+{
+   int timer = FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK, ahit);
+   int scale = FIELD_GET(UFSHCI_AHIBERN8_SCALE_MASK, ahit);
+
+   for (; scale > 0; --scale)
+   timer *= UFSHCI_AHIBERN8_SCALE_FACTOR;
+
+   return timer;
+}
+
+/* Convert microseconds to Auto-Hibernate Idle Timer register value */
+static u32 ufshcd_us_to_ahit(unsigned int timer)
+{
+   unsigned int scale;
+
+   for (scale = 0; timer > UFSHCI_AHIBERN8_TIMER_MASK; ++scale)
+   timer /= UFSHCI_AHIBERN8_SCALE_FACTOR;
+
+   return FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, timer) |
+  FIELD_PREP(UFSHCI_AHIBERN8_SCALE_MASK, scale);
+}
+
+static ssize_t auto_hibern8_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   struct ufs_hba *hba = dev_get_drvdata(dev);
+   int timer = -1;
+
+   if (hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT)
+   timer = ufshcd_ahit_to_us(hba->ahit);
+
+   return snprintf(buf, PAGE_SIZE, "%d\n", timer);
+}
+
+static ssize_t auto_hibern8_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+   struct ufs_hba *hba = dev_get_drvdata(dev);
+   unsigned int timer;
+
+   if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT))
+   return -EOPNOTSUPP;
+
+   if (kstrtouint(buf, 0, ))
+   return -EINVAL;
+
+   if (timer > UFSHCI_AHIBERN8_MAX)
+   return -EINVAL;
+
+   ufshcd_auto_hibern8_update(hba,