[v2,3/5] firmware: ti_sci: Allocate memory for the LPM modes

Message ID 20221108224527.137179-4-g-vlaev@ti.com
State New
Headers
Series firmware: ti_sci: Introduce system suspend support |

Commit Message

Georgi Vlaev Nov. 8, 2022, 10:45 p.m. UTC
  From: Dave Gerlach <d-gerlach@ti.com>

A region of memory in DDR must be used during Deep Sleep for saving
of some system context when using the ti_sci firmware. From DM's point
of view, this can be any contiguous region in the DDR, so can allocate
512KB of DMA reserved memory in probe(), instead of another carveout.

Also send a TISCI_MSG_PREPARE_SUSPEND message to the firmware during
probe to determine if system suspend is supported and if
ti_sci_init_suspend should be called based on the response received.

Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Vibhore Vardhan <vibhore@ti.com>
Signed-off-by: Georgi Vlaev <g-vlaev@ti.com>
---
 drivers/firmware/ti_sci.c | 55 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)
  

Comments

kernel test robot Nov. 11, 2022, 1 p.m. UTC | #1
Hi Georgi,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on f0c4d9fc9cc9462659728d168387191387e903cc]

url:    https://github.com/intel-lab-lkp/linux/commits/Georgi-Vlaev/firmware-ti_sci-Introduce-system-suspend-support/20221109-064746
base:   f0c4d9fc9cc9462659728d168387191387e903cc
patch link:    https://lore.kernel.org/r/20221108224527.137179-4-g-vlaev%40ti.com
patch subject: [PATCH v2 3/5] firmware: ti_sci: Allocate memory for the LPM modes
config: arm-randconfig-r011-20221111
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 463da45892e2d2a262277b91b96f5f8c05dc25d0)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://github.com/intel-lab-lkp/linux/commit/4ac0e207de172d504b6bcbf299c892e915327bf9
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Georgi-Vlaev/firmware-ti_sci-Introduce-system-suspend-support/20221109-064746
        git checkout 4ac0e207de172d504b6bcbf299c892e915327bf9
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash drivers/firmware/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/firmware/ti_sci.c:3519:37: warning: shift count >= width of type [-Wshift-count-overflow]
                                          (u32)(info->ctx_mem_addr >> 32), 0);
                                                                   ^  ~~
   1 warning generated.


vim +3519 drivers/firmware/ti_sci.c

  3496	
  3497	static int ti_sci_init_suspend(struct platform_device *pdev,
  3498				       struct ti_sci_info *info)
  3499	{
  3500		struct device *dev = &pdev->dev;
  3501		int ret;
  3502	
  3503		dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
  3504		info->ctx_mem_buf = dma_alloc_coherent(info->dev, LPM_CTX_MEM_SIZE,
  3505						       &info->ctx_mem_addr,
  3506						       GFP_KERNEL);
  3507		if (!info->ctx_mem_buf) {
  3508			dev_err(info->dev, "Failed to allocate LPM context memory\n");
  3509			return -ENOMEM;
  3510		}
  3511	
  3512		/*
  3513		 * Attempt to call prepare_sleep, this will be NAK'd if suspend is not
  3514		 * supported by firmware in use, in which case we will not attempt to
  3515		 * init suspend.
  3516		 */
  3517		ret = ti_sci_cmd_prepare_sleep(&info->handle, 0,
  3518					       (u32)(info->ctx_mem_addr & 0xffffffff) ,
> 3519					       (u32)(info->ctx_mem_addr >> 32), 0);
  3520	
  3521		if (ret)
  3522			goto err;
  3523	
  3524		return 0;
  3525	err:
  3526		dma_free_coherent(info->dev, LPM_CTX_MEM_SIZE,
  3527				  info->ctx_mem_buf,
  3528				  info->ctx_mem_addr);
  3529		return ret;
  3530	}
  3531
  

Patch

diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index f13cf19587e3..6a07c7276c24 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -10,6 +10,7 @@ 
 
 #include <linux/bitmap.h>
 #include <linux/debugfs.h>
+#include <linux/dma-mapping.h>
 #include <linux/export.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
@@ -25,6 +26,9 @@ 
 
 #include "ti_sci.h"
 
+/* Low power mode memory context size */
+#define LPM_CTX_MEM_SIZE 0x80000
+
 /* List of all TI SCI devices active in system */
 static LIST_HEAD(ti_sci_list);
 /* Protection for the entire list */
@@ -96,6 +100,8 @@  struct ti_sci_desc {
  * @minfo:	Message info
  * @node:	list head
  * @host_id:	Host ID
+ * @ctx_mem_addr: Low power context memory phys address
+ * @ctx_mem_buf: Low power context memory buffer
  * @users:	Number of users of this instance
  * @is_suspending: Flag set to indicate in suspend path.
  */
@@ -114,6 +120,8 @@  struct ti_sci_info {
 	struct ti_sci_xfers_info minfo;
 	struct list_head node;
 	u8 host_id;
+	dma_addr_t ctx_mem_addr;
+	void* ctx_mem_buf;
 	/* protected by ti_sci_list_mutex */
 	int users;
 	bool is_suspending;
@@ -3486,6 +3494,41 @@  static int ti_sci_resume(struct device *dev)
 
 static DEFINE_SIMPLE_DEV_PM_OPS(ti_sci_pm_ops, ti_sci_suspend, ti_sci_resume);
 
+static int ti_sci_init_suspend(struct platform_device *pdev,
+			       struct ti_sci_info *info)
+{
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+	info->ctx_mem_buf = dma_alloc_coherent(info->dev, LPM_CTX_MEM_SIZE,
+					       &info->ctx_mem_addr,
+					       GFP_KERNEL);
+	if (!info->ctx_mem_buf) {
+		dev_err(info->dev, "Failed to allocate LPM context memory\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * Attempt to call prepare_sleep, this will be NAK'd if suspend is not
+	 * supported by firmware in use, in which case we will not attempt to
+	 * init suspend.
+	 */
+	ret = ti_sci_cmd_prepare_sleep(&info->handle, 0,
+				       (u32)(info->ctx_mem_addr & 0xffffffff) ,
+				       (u32)(info->ctx_mem_addr >> 32), 0);
+
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	dma_free_coherent(info->dev, LPM_CTX_MEM_SIZE,
+			  info->ctx_mem_buf,
+			  info->ctx_mem_addr);
+	return ret;
+}
+
 /* Description for K2G */
 static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
 	.default_host_id = 2,
@@ -3638,6 +3681,14 @@  static int ti_sci_probe(struct platform_device *pdev)
 		}
 	}
 
+	ret = ti_sci_init_suspend(pdev, info);
+	if (ret)
+		dev_warn(dev,
+			 "ti_sci_init_suspend failed, mem suspend will be non-functional.\n");
+
+	/* Suspend is an optional feature, reset return value and continue. */
+	ret = 0;
+
 	dev_info(dev, "ABI: %d.%d (firmware rev 0x%04x '%s')\n",
 		 info->handle.version.abi_major, info->handle.version.abi_minor,
 		 info->handle.version.firmware_revision,
@@ -3685,6 +3736,10 @@  static int ti_sci_remove(struct platform_device *pdev)
 		mbox_free_channel(info->chan_rx);
 	}
 
+	if (info->ctx_mem_buf)
+		dma_free_coherent(info->dev, LPM_CTX_MEM_SIZE,
+				  info->ctx_mem_buf,
+				  info->ctx_mem_addr);
 	return ret;
 }