Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

firmware: ti_sci: Introduce Power Management Ops

Introduce power management ops supported by the TISCI
Low Power Mode API [1].

1) TISCI_MSG_LPM_WAKE_REASON
Get which wake up source woke the SoC from Low Power Mode.
The wake up source IDs will be common for all K3 platforms.

2) TISCI_MSG_LPM_SET_DEVICE_CONSTRAINT
Set LPM constraint on behalf of a device. By setting a constraint, the
device ensures that it will not be powered off or reset in the selected
mode.

3) TISCI_MSG_LPM_SET_LATENCY_CONSTRAINT
Set LPM resume latency constraint. By setting a constraint, the host
ensures that the resume time from selected mode will be less than the
constraint value.

[1] https://software-dl.ti.com/tisci/esd/latest/2_tisci_msgs/pm/lpm.html

Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
[g-vlaev@ti.com: LPM_WAKE_REASON and IO_ISOLATION support]
Signed-off-by: Georgi Vlaev <g-vlaev@ti.com>
[a-kaur@ti.com: SET_DEVICE_CONSTRAINT support]
Signed-off-by: Akashdeep Kaur <a-kaur@ti.com>
[vibhore@ti.com: SET_LATENCY_CONSTRAINT support]
Signed-off-by: Vibhore Vardhan <vibhore@ti.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
Reviewed-by: Akashdeep Kaur <a-kaur@ti.com>
Tested-by: Dhruva Gole <d-gole@ti.com>
Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
Tested-by: Kevin Hilman <khilman@baylibre.com>
Tested-by: Roger Quadros <rogerq@kernel.org>
Acked-by: Dhruva Gole <d-gole@ti.com>
Link: https://lore.kernel.org/r/20241007-tisci-syssuspendresume-v13-4-ed54cd659a49@baylibre.com
Signed-off-by: Nishanth Menon <nm@ti.com>

authored by

Dave Gerlach and committed by
Nishanth Menon
60357991 ec24643b

+300
+198
drivers/firmware/ti_sci.c
··· 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; ··· 3155 2975 struct ti_sci_core_ops *core_ops = &ops->core_ops; 3156 2976 struct ti_sci_dev_ops *dops = &ops->dev_ops; 3157 2977 struct ti_sci_clk_ops *cops = &ops->clk_ops; 2978 + struct ti_sci_pm_ops *pmops = &ops->pm_ops; 3158 2979 struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops; 3159 2980 struct ti_sci_rm_irq_ops *iops = &ops->rm_irq_ops; 3160 2981 struct ti_sci_rm_ringacc_ops *rops = &ops->rm_ring_ops; ··· 3194 3013 cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq; 3195 3014 cops->set_freq = ti_sci_cmd_clk_set_freq; 3196 3015 cops->get_freq = ti_sci_cmd_clk_get_freq; 3016 + 3017 + if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) { 3018 + pr_debug("detected DM managed LPM in fw_caps\n"); 3019 + pmops->lpm_wake_reason = ti_sci_msg_cmd_lpm_wake_reason; 3020 + pmops->set_device_constraint = ti_sci_cmd_set_device_constraint; 3021 + pmops->set_latency_constraint = ti_sci_cmd_set_latency_constraint; 3022 + } 3197 3023 3198 3024 rm_core_ops->get_range = ti_sci_cmd_get_resource_range; 3199 3025 rm_core_ops->get_range_from_shost = ··· 3691 3503 { 3692 3504 struct ti_sci_info *info = dev_get_drvdata(dev); 3693 3505 int ret = 0; 3506 + u32 source; 3507 + u64 time; 3508 + u8 pin; 3509 + u8 mode; 3694 3510 3695 3511 ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_DISABLE); 3696 3512 if (ret) 3697 3513 return ret; 3514 + 3515 + ret = ti_sci_msg_cmd_lpm_wake_reason(&info->handle, &source, &time, &pin, &mode); 3516 + /* Do not fail to resume on error as the wake reason is not critical */ 3517 + if (!ret) 3518 + dev_info(dev, "ti_sci: wakeup source:0x%x, pin:0x%x, mode:0x%x\n", 3519 + source, pin, mode); 3698 3520 3699 3521 return 0; 3700 3522 }
+76
drivers/firmware/ti_sci.h
··· 38 38 39 39 /* Low Power Mode Requests */ 40 40 #define TI_SCI_MSG_PREPARE_SLEEP 0x0300 41 + #define TI_SCI_MSG_LPM_WAKE_REASON 0x0306 41 42 #define TI_SCI_MSG_SET_IO_ISOLATION 0x0307 43 + #define TI_SCI_MSG_LPM_SET_DEVICE_CONSTRAINT 0x0309 44 + #define TI_SCI_MSG_LPM_SET_LATENCY_CONSTRAINT 0x030A 42 45 43 46 /* Resource Management Requests */ 44 47 #define TI_SCI_MSG_GET_RESOURCE_RANGE 0x1500 ··· 611 608 struct ti_sci_msg_req_set_io_isolation { 612 609 struct ti_sci_msg_hdr hdr; 613 610 u8 state; 611 + } __packed; 612 + 613 + /** 614 + * struct ti_sci_msg_resp_lpm_wake_reason - Response for TI_SCI_MSG_LPM_WAKE_REASON. 615 + * 616 + * @hdr: Generic header. 617 + * @wake_source: The wake up source that woke soc from LPM. 618 + * @wake_timestamp: Timestamp at which soc woke. 619 + * @wake_pin: The pin that has triggered wake up. 620 + * @mode: The last entered low power mode. 621 + * @rsvd: Reserved for future use. 622 + * 623 + * Response to a generic message with message type TI_SCI_MSG_LPM_WAKE_REASON, 624 + * used to query the wake up source, pin and entered low power mode. 625 + */ 626 + struct ti_sci_msg_resp_lpm_wake_reason { 627 + struct ti_sci_msg_hdr hdr; 628 + u32 wake_source; 629 + u64 wake_timestamp; 630 + u8 wake_pin; 631 + u8 mode; 632 + u32 rsvd[2]; 633 + } __packed; 634 + 635 + /** 636 + * struct ti_sci_msg_req_lpm_set_device_constraint - Request for 637 + * TISCI_MSG_LPM_SET_DEVICE_CONSTRAINT. 638 + * 639 + * @hdr: TISCI header to provide ACK/NAK flags to the host. 640 + * @id: Device ID of device whose constraint has to be modified. 641 + * @state: The desired state of device constraint: set or clear. 642 + * @rsvd: Reserved for future use. 643 + * 644 + * This message is used by host to set constraint on the device. This can be 645 + * sent anytime after boot before prepare sleep message. Any device can set a 646 + * constraint on the low power mode that the SoC can enter. It allows 647 + * configurable information to be easily shared from the application, as this 648 + * is a non-secure message and therefore can be sent by anyone. By setting a 649 + * constraint, the device ensures that it will not be powered off or reset in 650 + * the selected mode. Note: Access Restriction: Exclusivity flag of Device will 651 + * be honored. If some other host already has constraint on this device ID, 652 + * NACK will be returned. 653 + */ 654 + struct ti_sci_msg_req_lpm_set_device_constraint { 655 + struct ti_sci_msg_hdr hdr; 656 + u32 id; 657 + u8 state; 658 + u32 rsvd[2]; 659 + } __packed; 660 + 661 + /** 662 + * struct ti_sci_msg_req_lpm_set_latency_constraint - Request for 663 + * TISCI_MSG_LPM_SET_LATENCY_CONSTRAINT. 664 + * 665 + * @hdr: TISCI header to provide ACK/NAK flags to the host. 666 + * @wkup_latency: The maximum acceptable latency to wake up from low power mode 667 + * in milliseconds. The deeper the state, the higher the latency. 668 + * @state: The desired state of wakeup latency constraint: set or clear. 669 + * @rsvd: Reserved for future use. 670 + * 671 + * This message is used by host to set wakeup latency from low power mode. This can 672 + * be sent anytime after boot before prepare sleep message, and can be sent after 673 + * current low power mode is exited. Any device can set a constraint on the low power 674 + * mode that the SoC can enter. It allows configurable information to be easily shared 675 + * from the application, as this is a non-secure message and therefore can be sent by 676 + * anyone. By setting a wakeup latency constraint, the host ensures that the resume time 677 + * from selected low power mode will be less than the constraint value. 678 + */ 679 + struct ti_sci_msg_req_lpm_set_latency_constraint { 680 + struct ti_sci_msg_hdr hdr; 681 + u16 latency; 682 + u8 state; 683 + u32 rsvd; 614 684 } __packed; 615 685 616 686 #define TI_SCI_IRQ_SECONDARY_HOST_INVALID 0xff
+26
include/linux/soc/ti/ti_sci_protocol.h
··· 199 199 #define TISCI_MSG_VALUE_IO_ENABLE 1 200 200 #define TISCI_MSG_VALUE_IO_DISABLE 0 201 201 202 + /* TISCI LPM constraint state values */ 203 + #define TISCI_MSG_CONSTRAINT_SET 1 204 + #define TISCI_MSG_CONSTRAINT_CLR 0 205 + 206 + /** 207 + * struct ti_sci_pm_ops - Low Power Mode (LPM) control operations 208 + * @lpm_wake_reason: Get the wake up source that woke the SoC from LPM 209 + * - source: The wake up source that woke soc from LPM. 210 + * - timestamp: Timestamp at which soc woke. 211 + * @set_device_constraint: Set LPM constraint on behalf of a device 212 + * - id: Device Identifier 213 + * - state: The desired state of device constraint: set or clear. 214 + * @set_latency_constraint: Set LPM resume latency constraint 215 + * - latency: maximum acceptable latency to wake up from low power mode 216 + * - state: The desired state of latency constraint: set or clear. 217 + */ 218 + struct ti_sci_pm_ops { 219 + int (*lpm_wake_reason)(const struct ti_sci_handle *handle, 220 + u32 *source, u64 *timestamp, u8 *pin, u8 *mode); 221 + int (*set_device_constraint)(const struct ti_sci_handle *handle, 222 + u32 id, u8 state); 223 + int (*set_latency_constraint)(const struct ti_sci_handle *handle, 224 + u16 latency, u8 state); 225 + }; 226 + 202 227 /** 203 228 * struct ti_sci_resource_desc - Description of TI SCI resource instance range. 204 229 * @start: Start index of the first resource range. ··· 568 543 struct ti_sci_core_ops core_ops; 569 544 struct ti_sci_dev_ops dev_ops; 570 545 struct ti_sci_clk_ops clk_ops; 546 + struct ti_sci_pm_ops pm_ops; 571 547 struct ti_sci_rm_core_ops rm_core_ops; 572 548 struct ti_sci_rm_irq_ops rm_irq_ops; 573 549 struct ti_sci_rm_ringacc_ops rm_ring_ops;