diff mbox series

[V6,3/4] firmware: ti_sci: Allocate memory for Low Power Modes

Message ID 20230803064247.503036-4-d-gole@ti.com (mailing list archive)
State Handled Elsewhere, archived
Headers show
Series firmware: ti_sci: Introduce system suspend support | expand

Commit Message

Dhruva Gole Aug. 3, 2023, 6:42 a.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_QUERY_FW_CAPS message to the firmware during
probe to determine if any low power modes are 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>
Tested-by: Roger Quadros <rogerq@kernel.org>
[d-gole@ti.com: Use dma_alloc_attrs instead of dma_alloc_coherent]
Signed-off-by: Dhruva Gole <d-gole@ti.com>
---
 drivers/firmware/ti_sci.c | 42 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

Comments

Andrew Davis Aug. 3, 2023, 3:23 p.m. UTC | #1
On 8/3/23 1:42 AM, Dhruva Gole wrote:
> 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_QUERY_FW_CAPS message to the firmware during
> probe to determine if any low power modes are 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>
> Tested-by: Roger Quadros <rogerq@kernel.org>
> [d-gole@ti.com: Use dma_alloc_attrs instead of dma_alloc_coherent]
> Signed-off-by: Dhruva Gole <d-gole@ti.com>
> ---
>   drivers/firmware/ti_sci.c | 42 +++++++++++++++++++++++++++++++++++++++
>   1 file changed, 42 insertions(+)
> 
> diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
> index 3b40f9336b3f..0334ade19868 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,9 @@ 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
> + * @fw_caps:	FW/SoC low power capabilities
>    * @users:	Number of users of this instance
>    */
>   struct ti_sci_info {
> @@ -113,6 +120,9 @@ 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;
> +	u64 fw_caps;
>   	/* protected by ti_sci_list_mutex */
>   	int users;
>   };
> @@ -3511,6 +3521,25 @@ static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode,
>   	return NOTIFY_BAD;
>   }
>   
> +static int ti_sci_init_suspend(struct platform_device *pdev,
> +			       struct ti_sci_info *info)
> +{
> +	struct device *dev = &pdev->dev;
> +
> +	dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
> +	info->ctx_mem_buf = dma_alloc_attrs(info->dev, LPM_CTX_MEM_SIZE,
> +					    &info->ctx_mem_addr,
> +					    GFP_KERNEL,
> +					    DMA_ATTR_NO_KERNEL_MAPPING |
> +					    DMA_ATTR_FORCE_CONTIGUOUS);
> +	if (!info->ctx_mem_buf) {
> +		dev_err(info->dev, "Failed to allocate LPM context memory\n");
> +		return -ENOMEM;
> +	}
> +
> +	return 0;
> +}
> +
>   /* Description for K2G */
>   static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
>   	.default_host_id = 2,
> @@ -3661,6 +3690,15 @@ static int ti_sci_probe(struct platform_device *pdev)
>   		}
>   	}
>   
> +	/*
> +	 * Check if the firmware supports any optional low power modes
> +	 * and initialize them if present. Old revisions of TIFS (< 08.04)
> +	 * will NACK the request.
> +	 */
> +	ret = ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps);
> +	if (!ret && (info->fw_caps & MSG_MASK_CAPS_LPM))
> +		ti_sci_init_suspend(pdev, info);
> +
>   	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,
> @@ -3708,6 +3746,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,

You allocated with dma_alloc_attrs() you should free with dma_free_attrs().

Andrew

> +				  info->ctx_mem_buf,
> +				  info->ctx_mem_addr);
>   	return ret;
>   }
>
Dhruva Gole Aug. 3, 2023, 3:57 p.m. UTC | #2
On Aug 03, 2023 at 10:23:47 -0500, Andrew Davis wrote:
> On 8/3/23 1:42 AM, Dhruva Gole wrote:
> > 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_QUERY_FW_CAPS message to the firmware during
> > probe to determine if any low power modes are 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>
> > Tested-by: Roger Quadros <rogerq@kernel.org>
> > [d-gole@ti.com: Use dma_alloc_attrs instead of dma_alloc_coherent]
> > Signed-off-by: Dhruva Gole <d-gole@ti.com>
> > ---
> >   drivers/firmware/ti_sci.c | 42 +++++++++++++++++++++++++++++++++++++++
> >   1 file changed, 42 insertions(+)
> > 
[..snip..]
> >   static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
> >   	.default_host_id = 2,
> > @@ -3661,6 +3690,15 @@ static int ti_sci_probe(struct platform_device *pdev)
> >   		}
> >   	}
> > +	/*
> > +	 * Check if the firmware supports any optional low power modes
> > +	 * and initialize them if present. Old revisions of TIFS (< 08.04)
> > +	 * will NACK the request.
> > +	 */
> > +	ret = ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps);
> > +	if (!ret && (info->fw_caps & MSG_MASK_CAPS_LPM))
> > +		ti_sci_init_suspend(pdev, info);
> > +
> >   	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,
> > @@ -3708,6 +3746,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,
> 
> You allocated with dma_alloc_attrs() you should free with dma_free_attrs().

Good catch, will fix this in next revision

> 
> Andrew
> 
> > +				  info->ctx_mem_buf,
> > +				  info->ctx_mem_addr);
> >   	return ret;
> >   }
diff mbox series

Patch

diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 3b40f9336b3f..0334ade19868 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,9 @@  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
+ * @fw_caps:	FW/SoC low power capabilities
  * @users:	Number of users of this instance
  */
 struct ti_sci_info {
@@ -113,6 +120,9 @@  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;
+	u64 fw_caps;
 	/* protected by ti_sci_list_mutex */
 	int users;
 };
@@ -3511,6 +3521,25 @@  static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode,
 	return NOTIFY_BAD;
 }
 
+static int ti_sci_init_suspend(struct platform_device *pdev,
+			       struct ti_sci_info *info)
+{
+	struct device *dev = &pdev->dev;
+
+	dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+	info->ctx_mem_buf = dma_alloc_attrs(info->dev, LPM_CTX_MEM_SIZE,
+					    &info->ctx_mem_addr,
+					    GFP_KERNEL,
+					    DMA_ATTR_NO_KERNEL_MAPPING |
+					    DMA_ATTR_FORCE_CONTIGUOUS);
+	if (!info->ctx_mem_buf) {
+		dev_err(info->dev, "Failed to allocate LPM context memory\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
 /* Description for K2G */
 static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
 	.default_host_id = 2,
@@ -3661,6 +3690,15 @@  static int ti_sci_probe(struct platform_device *pdev)
 		}
 	}
 
+	/*
+	 * Check if the firmware supports any optional low power modes
+	 * and initialize them if present. Old revisions of TIFS (< 08.04)
+	 * will NACK the request.
+	 */
+	ret = ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps);
+	if (!ret && (info->fw_caps & MSG_MASK_CAPS_LPM))
+		ti_sci_init_suspend(pdev, info);
+
 	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,
@@ -3708,6 +3746,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;
 }