Message ID | 20230803064247.503036-4-d-gole@ti.com |
---|---|
State | Superseded |
Headers | show |
Series | firmware: ti_sci: Introduce system suspend support | expand |
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; > } >
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 --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; }