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

Andrew Davis afd at ti.com
Thu Aug 3 08:23:47 PDT 2023


On 8/3/23 1:42 AM, Dhruva Gole wrote:
> From: Dave Gerlach <d-gerlach at 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 at ti.com>
> Signed-off-by: Vibhore Vardhan <vibhore at ti.com>
> Signed-off-by: Georgi Vlaev <g-vlaev at ti.com>
> Tested-by: Roger Quadros <rogerq at kernel.org>
> [d-gole at ti.com: Use dma_alloc_attrs instead of dma_alloc_coherent]
> Signed-off-by: Dhruva Gole <d-gole at 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;
>   }
>   



More information about the linux-arm-kernel mailing list