diff options
-rw-r--r-- | Documentation/scsi/ufs.rst | 15 | ||||
-rw-r--r-- | drivers/ufs/core/ufshcd.c | 16 |
2 files changed, 31 insertions, 0 deletions
diff --git a/Documentation/scsi/ufs.rst b/Documentation/scsi/ufs.rst index fbac745b783c..885b1a736e3f 100644 --- a/Documentation/scsi/ufs.rst +++ b/Documentation/scsi/ufs.rst @@ -17,6 +17,8 @@ Universal Flash Storage 3.2 UTP Transfer requests 3.3 UFS error handling 3.4 SCSI Error handling + 4. BSG Support + 5. UFS Reference Clock Frequency configuration 1. Overview @@ -193,3 +195,16 @@ UFS specifications can be found at: - UFS - http://www.jedec.org/sites/default/files/docs/JESD220.pdf - UFSHCI - http://www.jedec.org/sites/default/files/docs/JESD223.pdf + +5. UFS Reference Clock Frequency configuration +============================================== + +Devicetree can define a clock named "ref_clk" under the UFS controller node +to specify the intended reference clock frequency for the UFS storage +parts. ACPI-based system can specify the frequency using ACPI +Device-Specific Data property named "ref-clk-freq". In both ways the value +is interpreted as frequency in Hz and must match one of the values given in +the UFS specification. UFS subsystem will attempt to read the value when +executing common controller initialization. If the value is available, UFS +subsytem will ensure the bRefClkFreq attribute of the UFS storage device is +set accordingly and will modify it if there is a mismatch. diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index b92d4fb82bca..8f11f118c30e 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -8544,6 +8544,19 @@ out: return ret; } +static enum ufs_ref_clk_freq ufshcd_parse_ref_clk_property(struct ufs_hba *hba) +{ + u32 freq; + int ret = device_property_read_u32(hba->dev, "ref-clk-freq", &freq); + + if (ret) { + dev_dbg(hba->dev, "Cannnot query 'ref-clk-freq' property = %d", ret); + return REF_CLK_FREQ_INVAL; + } + + return ufs_get_bref_clk_from_hz(freq); +} + static int ufshcd_init_clocks(struct ufs_hba *hba) { int ret = 0; @@ -8637,6 +8650,9 @@ static int ufshcd_hba_init(struct ufs_hba *hba) if (err) goto out_disable_hba_vreg; + if (hba->dev_ref_clk_freq == REF_CLK_FREQ_INVAL) + hba->dev_ref_clk_freq = ufshcd_parse_ref_clk_property(hba); + err = ufshcd_setup_clocks(hba, true); if (err) goto out_disable_hba_vreg; |