@@ -1833,6 +1833,186 @@ static int ti_sci_cmd_set_io_isolation(const struct ti_sci_handle *handle,
1833
1833
return ret ;
1834
1834
}
1835
1835
1836
+ /**
1837
+ * ti_sci_msg_cmd_lpm_wake_reason() - Get the wakeup source from LPM
1838
+ * @handle: Pointer to TI SCI handle
1839
+ * @source: The wakeup source that woke the SoC from LPM
1840
+ * @timestamp: Timestamp of the wakeup event
1841
+ * @pin: The pin that has triggered wake up
1842
+ * @mode: The last entered low power mode
1843
+ *
1844
+ * Return: 0 if all went well, else returns appropriate error value.
1845
+ */
1846
+ static int ti_sci_msg_cmd_lpm_wake_reason (const struct ti_sci_handle * handle ,
1847
+ u32 * source , u64 * timestamp , u8 * pin , u8 * mode )
1848
+ {
1849
+ struct ti_sci_info * info ;
1850
+ struct ti_sci_xfer * xfer ;
1851
+ struct ti_sci_msg_resp_lpm_wake_reason * resp ;
1852
+ struct device * dev ;
1853
+ int ret = 0 ;
1854
+
1855
+ if (IS_ERR (handle ))
1856
+ return PTR_ERR (handle );
1857
+ if (!handle )
1858
+ return - EINVAL ;
1859
+
1860
+ info = handle_to_ti_sci_info (handle );
1861
+ dev = info -> dev ;
1862
+
1863
+ xfer = ti_sci_get_one_xfer (info , TI_SCI_MSG_LPM_WAKE_REASON ,
1864
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED ,
1865
+ sizeof (struct ti_sci_msg_hdr ),
1866
+ sizeof (* resp ));
1867
+ if (IS_ERR (xfer )) {
1868
+ ret = PTR_ERR (xfer );
1869
+ dev_err (dev , "Message alloc failed(%d)\n" , ret );
1870
+ return ret ;
1871
+ }
1872
+
1873
+ ret = ti_sci_do_xfer (info , xfer );
1874
+ if (ret ) {
1875
+ dev_err (dev , "Mbox send fail %d\n" , ret );
1876
+ goto fail ;
1877
+ }
1878
+
1879
+ resp = (struct ti_sci_msg_resp_lpm_wake_reason * )xfer -> xfer_buf ;
1880
+
1881
+ if (!ti_sci_is_response_ack (resp )) {
1882
+ dev_err (dev , "Failed to get wake reason\n" );
1883
+ ret = - ENODEV ;
1884
+ goto fail ;
1885
+ }
1886
+
1887
+ if (source )
1888
+ * source = resp -> wake_source ;
1889
+ if (timestamp )
1890
+ * timestamp = resp -> wake_timestamp ;
1891
+ if (pin )
1892
+ * pin = resp -> wake_pin ;
1893
+ if (mode )
1894
+ * mode = resp -> mode ;
1895
+
1896
+ fail :
1897
+ ti_sci_put_one_xfer (& info -> minfo , xfer );
1898
+
1899
+ return ret ;
1900
+ }
1901
+
1902
+ /**
1903
+ * ti_sci_cmd_set_device_constraint() - Set LPM constraint on behalf of a device
1904
+ * @handle: pointer to TI SCI handle
1905
+ * @id: Device identifier
1906
+ * @state: The desired state of device constraint: set or clear
1907
+ *
1908
+ * Return: 0 if all went well, else returns appropriate error value.
1909
+ */
1910
+ static int ti_sci_cmd_set_device_constraint (const struct ti_sci_handle * handle ,
1911
+ u32 id , u8 state )
1912
+ {
1913
+ struct ti_sci_info * info ;
1914
+ struct ti_sci_msg_req_lpm_set_device_constraint * req ;
1915
+ struct ti_sci_msg_hdr * resp ;
1916
+ struct ti_sci_xfer * xfer ;
1917
+ struct device * dev ;
1918
+ int ret = 0 ;
1919
+
1920
+ if (IS_ERR (handle ))
1921
+ return PTR_ERR (handle );
1922
+ if (!handle )
1923
+ return - EINVAL ;
1924
+
1925
+ info = handle_to_ti_sci_info (handle );
1926
+ dev = info -> dev ;
1927
+
1928
+ xfer = ti_sci_get_one_xfer (info , TI_SCI_MSG_LPM_SET_DEVICE_CONSTRAINT ,
1929
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED ,
1930
+ sizeof (* req ), sizeof (* resp ));
1931
+ if (IS_ERR (xfer )) {
1932
+ ret = PTR_ERR (xfer );
1933
+ dev_err (dev , "Message alloc failed(%d)\n" , ret );
1934
+ return ret ;
1935
+ }
1936
+ req = (struct ti_sci_msg_req_lpm_set_device_constraint * )xfer -> xfer_buf ;
1937
+ req -> id = id ;
1938
+ req -> state = state ;
1939
+
1940
+ ret = ti_sci_do_xfer (info , xfer );
1941
+ if (ret ) {
1942
+ dev_err (dev , "Mbox send fail %d\n" , ret );
1943
+ goto fail ;
1944
+ }
1945
+
1946
+ resp = (struct ti_sci_msg_hdr * )xfer -> xfer_buf ;
1947
+
1948
+ if (!ti_sci_is_response_ack (resp )) {
1949
+ dev_err (dev , "Failed to set device constraint\n" );
1950
+ ret = - ENODEV ;
1951
+ }
1952
+
1953
+ fail :
1954
+ ti_sci_put_one_xfer (& info -> minfo , xfer );
1955
+
1956
+ return ret ;
1957
+ }
1958
+
1959
+ /**
1960
+ * ti_sci_cmd_set_latency_constraint() - Set LPM resume latency constraint
1961
+ * @handle: pointer to TI SCI handle
1962
+ * @latency: maximum acceptable latency (in ms) to wake up from LPM
1963
+ * @state: The desired state of latency constraint: set or clear
1964
+ *
1965
+ * Return: 0 if all went well, else returns appropriate error value.
1966
+ */
1967
+ static int ti_sci_cmd_set_latency_constraint (const struct ti_sci_handle * handle ,
1968
+ u16 latency , u8 state )
1969
+ {
1970
+ struct ti_sci_info * info ;
1971
+ struct ti_sci_msg_req_lpm_set_latency_constraint * req ;
1972
+ struct ti_sci_msg_hdr * resp ;
1973
+ struct ti_sci_xfer * xfer ;
1974
+ struct device * dev ;
1975
+ int ret = 0 ;
1976
+
1977
+ if (IS_ERR (handle ))
1978
+ return PTR_ERR (handle );
1979
+ if (!handle )
1980
+ return - EINVAL ;
1981
+
1982
+ info = handle_to_ti_sci_info (handle );
1983
+ dev = info -> dev ;
1984
+
1985
+ xfer = ti_sci_get_one_xfer (info , TI_SCI_MSG_LPM_SET_LATENCY_CONSTRAINT ,
1986
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED ,
1987
+ sizeof (* req ), sizeof (* resp ));
1988
+ if (IS_ERR (xfer )) {
1989
+ ret = PTR_ERR (xfer );
1990
+ dev_err (dev , "Message alloc failed(%d)\n" , ret );
1991
+ return ret ;
1992
+ }
1993
+ req = (struct ti_sci_msg_req_lpm_set_latency_constraint * )xfer -> xfer_buf ;
1994
+ req -> latency = latency ;
1995
+ req -> state = state ;
1996
+
1997
+ ret = ti_sci_do_xfer (info , xfer );
1998
+ if (ret ) {
1999
+ dev_err (dev , "Mbox send fail %d\n" , ret );
2000
+ goto fail ;
2001
+ }
2002
+
2003
+ resp = (struct ti_sci_msg_hdr * )xfer -> xfer_buf ;
2004
+
2005
+ if (!ti_sci_is_response_ack (resp )) {
2006
+ dev_err (dev , "Failed to set device constraint\n" );
2007
+ ret = - ENODEV ;
2008
+ }
2009
+
2010
+ fail :
2011
+ ti_sci_put_one_xfer (& info -> minfo , xfer );
2012
+
2013
+ return ret ;
2014
+ }
2015
+
1836
2016
static int ti_sci_cmd_core_reboot (const struct ti_sci_handle * handle )
1837
2017
{
1838
2018
struct ti_sci_info * info ;
@@ -2975,6 +3155,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
2975
3155
struct ti_sci_core_ops * core_ops = & ops -> core_ops ;
2976
3156
struct ti_sci_dev_ops * dops = & ops -> dev_ops ;
2977
3157
struct ti_sci_clk_ops * cops = & ops -> clk_ops ;
3158
+ struct ti_sci_pm_ops * pmops = & ops -> pm_ops ;
2978
3159
struct ti_sci_rm_core_ops * rm_core_ops = & ops -> rm_core_ops ;
2979
3160
struct ti_sci_rm_irq_ops * iops = & ops -> rm_irq_ops ;
2980
3161
struct ti_sci_rm_ringacc_ops * rops = & ops -> rm_ring_ops ;
@@ -3014,6 +3195,13 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
3014
3195
cops -> set_freq = ti_sci_cmd_clk_set_freq ;
3015
3196
cops -> get_freq = ti_sci_cmd_clk_get_freq ;
3016
3197
3198
+ if (info -> fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ) {
3199
+ pr_debug ("detected DM managed LPM in fw_caps\n" );
3200
+ pmops -> lpm_wake_reason = ti_sci_msg_cmd_lpm_wake_reason ;
3201
+ pmops -> set_device_constraint = ti_sci_cmd_set_device_constraint ;
3202
+ pmops -> set_latency_constraint = ti_sci_cmd_set_latency_constraint ;
3203
+ }
3204
+
3017
3205
rm_core_ops -> get_range = ti_sci_cmd_get_resource_range ;
3018
3206
rm_core_ops -> get_range_from_shost =
3019
3207
ti_sci_cmd_get_resource_range_from_shost ;
@@ -3503,11 +3691,21 @@ static int __maybe_unused ti_sci_resume_noirq(struct device *dev)
3503
3691
{
3504
3692
struct ti_sci_info * info = dev_get_drvdata (dev );
3505
3693
int ret = 0 ;
3694
+ u32 source ;
3695
+ u64 time ;
3696
+ u8 pin ;
3697
+ u8 mode ;
3506
3698
3507
3699
ret = ti_sci_cmd_set_io_isolation (& info -> handle , TISCI_MSG_VALUE_IO_DISABLE );
3508
3700
if (ret )
3509
3701
return ret ;
3510
3702
3703
+ ret = ti_sci_msg_cmd_lpm_wake_reason (& info -> handle , & source , & time , & pin , & mode );
3704
+ /* Do not fail to resume on error as the wake reason is not critical */
3705
+ if (!ret )
3706
+ dev_info (dev , "ti_sci: wakeup source:0x%x, pin:0x%x, mode:0x%x\n" ,
3707
+ source , pin , mode );
3708
+
3511
3709
return 0 ;
3512
3710
}
3513
3711
0 commit comments