2020-10-12 13:18:48

by Peter Ujfalusi

[permalink] [raw]
Subject: [PATCH v3 00/11] firmware/soc: ti_sci, ringacc/inta: Preparation for AM64 DMA support

Hi,

Changes since v2:
- silence checkpatch CHECK for alignment by going over 80 chars in patch 10

Changes since v1:
- Use AM64X as family name in patch 11
- Added Reviewed-by tag from Grygorii for patch 6-10

The series prepares the ti_sci, ringacc, inta to support the new DMAs introduced
with AM64.

Separate series has been sent for the inta irqchip driver (v2):
https://lore.kernel.org/lkml/[email protected]/

Patches for the DMA support will be based on this series due to build and
feature dependencies.

To support the new DMSS we need to change the ti_sci ring config API in order to
be able to support the new parameters needed in the future.

We also need to add support for the second range in RM as along with the AM64
support, the resource allocation is going to change for existing SoC which used
only the first range for resource allocation.

The tx_tdtype support has been also missing from ti_sci for a long time and
the AM64 specific extended_ch_type depends on the existence of it in the message
struct.

Santosh: if you plan to take this series for 5.11, then can you create an
immutable branch which I can refer to Vinod for the DMA patches I'm going to
send soon.

Regards,
Peter
---
Peter Ujfalusi (11):
firmware: ti_sci: rm: Add support for tx_tdtype parameter for tx
channel
firmware: ti_sci: Use struct ti_sci_resource_desc in get_range ops
firmware: ti_sci: rm: Add support for second resource range
soc: ti: ti_sci_inta_msi: Add support for second range in resource
ranges
firmware: ti_sci: rm: Add support for extended_ch_type for tx channel
firmware: ti_sci: rm: Remove ring_get_config support
firmware: ti_sci: rm: Add new ops for ring configuration
soc: ti: k3-ringacc: Use the ti_sci set_cfg callback for ring
configuration
firmware: ti_sci: rm: Remove unused config() from
ti_sci_rm_ringacc_ops
soc: ti: k3-ringacc: Use correct device for allocation in RING mode
soc: ti: k3-socinfo: Add entry for AM64X SoC family

drivers/firmware/ti_sci.c | 213 ++++++++-----------------
drivers/firmware/ti_sci.h | 72 +++------
drivers/soc/ti/k3-ringacc.c | 97 ++++++-----
drivers/soc/ti/k3-socinfo.c | 1 +
drivers/soc/ti/ti_sci_inta_msi.c | 12 ++
include/linux/soc/ti/k3-ringacc.h | 5 +
include/linux/soc/ti/ti_sci_protocol.h | 85 ++++++----
7 files changed, 214 insertions(+), 271 deletions(-)

--
Peter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


2020-10-12 20:47:45

by Peter Ujfalusi

[permalink] [raw]
Subject: [PATCH v3 02/11] firmware: ti_sci: Use struct ti_sci_resource_desc in get_range ops

Use the ti_sci_resource_desc directly and update it's start and num members
directly instead of requiring individual parameters for them.

This will allow easy extension of the RM parameters without changing API.

Signed-off-by: Peter Ujfalusi <[email protected]>
---
drivers/firmware/ti_sci.c | 32 ++++++++++++--------------
include/linux/soc/ti/ti_sci_protocol.h | 32 +++++++++++++-------------
2 files changed, 31 insertions(+), 33 deletions(-)

diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 65a8c2e82093..7a777e91ce3e 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -1703,14 +1703,14 @@ static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle)
* @subtype: Resource assignment subtype that is being requested
* from the given device.
* @s_host: Host processor ID to which the resources are allocated
- * @range_start: Start index of the resource range
- * @range_num: Number of resources in the range
+ * @desc: Pointer to ti_sci_resource_desc to be updated with the
+ * resource range start index and number of resources
*
* Return: 0 if all went fine, else return appropriate error.
*/
static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
u32 dev_id, u8 subtype, u8 s_host,
- u16 *range_start, u16 *range_num)
+ struct ti_sci_resource_desc *desc)
{
struct ti_sci_msg_resp_get_resource_range *resp;
struct ti_sci_msg_req_get_resource_range *req;
@@ -1721,7 +1721,7 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,

if (IS_ERR(handle))
return PTR_ERR(handle);
- if (!handle)
+ if (!handle || !desc)
return -EINVAL;

info = handle_to_ti_sci_info(handle);
@@ -1754,8 +1754,8 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
} else if (!resp->range_start && !resp->range_num) {
ret = -ENODEV;
} else {
- *range_start = resp->range_start;
- *range_num = resp->range_num;
+ desc->start = resp->range_start;
+ desc->num = resp->range_num;
};

fail:
@@ -1771,18 +1771,18 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
* @dev_id: TISCI device ID.
* @subtype: Resource assignment subtype that is being requested
* from the given device.
- * @range_start: Start index of the resource range
- * @range_num: Number of resources in the range
+ * @desc: Pointer to ti_sci_resource_desc to be updated with the
+ * resource range start index and number of resources
*
* Return: 0 if all went fine, else return appropriate error.
*/
static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle,
u32 dev_id, u8 subtype,
- u16 *range_start, u16 *range_num)
+ struct ti_sci_resource_desc *desc)
{
return ti_sci_get_resource_range(handle, dev_id, subtype,
TI_SCI_IRQ_SECONDARY_HOST_INVALID,
- range_start, range_num);
+ desc);
}

/**
@@ -1793,18 +1793,17 @@ static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle,
* @subtype: Resource assignment subtype that is being requested
* from the given device.
* @s_host: Host processor ID to which the resources are allocated
- * @range_start: Start index of the resource range
- * @range_num: Number of resources in the range
+ * @desc: Pointer to ti_sci_resource_desc to be updated with the
+ * resource range start index and number of resources
*
* Return: 0 if all went fine, else return appropriate error.
*/
static
int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle,
u32 dev_id, u8 subtype, u8 s_host,
- u16 *range_start, u16 *range_num)
+ struct ti_sci_resource_desc *desc)
{
- return ti_sci_get_resource_range(handle, dev_id, subtype, s_host,
- range_start, range_num);
+ return ti_sci_get_resource_range(handle, dev_id, subtype, s_host, desc);
}

/**
@@ -3243,8 +3242,7 @@ devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle,
for (i = 0; i < res->sets; i++) {
ret = handle->ops.rm_core_ops.get_range(handle, dev_id,
sub_types[i],
- &res->desc[i].start,
- &res->desc[i].num);
+ &res->desc[i]);
if (ret) {
dev_dbg(dev, "dev = %d subtype %d not allocated for this host\n",
dev_id, sub_types[i]);
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
index d254d99fd45b..6cd537db4d33 100644
--- a/include/linux/soc/ti/ti_sci_protocol.h
+++ b/include/linux/soc/ti/ti_sci_protocol.h
@@ -195,6 +195,18 @@ struct ti_sci_clk_ops {
u64 *current_freq);
};

+/**
+ * struct ti_sci_resource_desc - Description of TI SCI resource instance range.
+ * @start: Start index of the resource.
+ * @num: Number of resources.
+ * @res_map: Bitmap to manage the allocation of these resources.
+ */
+struct ti_sci_resource_desc {
+ u16 start;
+ u16 num;
+ unsigned long *res_map;
+};
+
/**
* struct ti_sci_rm_core_ops - Resource management core operations
* @get_range: Get a range of resources belonging to ti sci host.
@@ -209,15 +221,15 @@ struct ti_sci_clk_ops {
* - dev_id: TISCI device ID.
* - subtype: Resource assignment subtype that is being requested
* from the given device.
- * - range_start: Start index of the resource range
- * - range_end: Number of resources in the range
+ * - desc: Pointer to ti_sci_resource_desc to be updated with the resource
+ * range start index and number of resources
*/
struct ti_sci_rm_core_ops {
int (*get_range)(const struct ti_sci_handle *handle, u32 dev_id,
- u8 subtype, u16 *range_start, u16 *range_num);
+ u8 subtype, struct ti_sci_resource_desc *desc);
int (*get_range_from_shost)(const struct ti_sci_handle *handle,
u32 dev_id, u8 subtype, u8 s_host,
- u16 *range_start, u16 *range_num);
+ struct ti_sci_resource_desc *desc);
};

#define TI_SCI_RESASG_SUBTYPE_IR_OUTPUT 0
@@ -522,18 +534,6 @@ struct ti_sci_handle {

#define TI_SCI_RESOURCE_NULL 0xffff

-/**
- * struct ti_sci_resource_desc - Description of TI SCI resource instance range.
- * @start: Start index of the resource.
- * @num: Number of resources.
- * @res_map: Bitmap to manage the allocation of these resources.
- */
-struct ti_sci_resource_desc {
- u16 start;
- u16 num;
- unsigned long *res_map;
-};
-
/**
* struct ti_sci_resource - Structure representing a resource assigned
* to a device.
--
Peter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

2020-10-12 20:47:50

by Peter Ujfalusi

[permalink] [raw]
Subject: [PATCH v3 10/11] soc: ti: k3-ringacc: Use correct device for allocation in RING mode

In RING mode the ringacc does not access the ring memory. In this access
mode the ringacc coherency does not have meaning.

If the ring is configured in RING mode, then the ringacc itself will not
access to the ring memory. Only the requester (user) of the ring is going
to read/write to the memory.
Extend the ring configuration parameters with a device pointer to be used
for DMA API when the ring is configured in RING mode.

Extending the ring configuration struct will allow per ring selection of
device to be used for allocation, thus allowing per ring coherency.

To avoid regression, fall back to use the ringacc dev in case the alloc_dev
is not provided.

Signed-off-by: Peter Ujfalusi <[email protected]>
Reviewed-by: Grygorii Strashko <[email protected]>
---
drivers/soc/ti/k3-ringacc.c | 18 +++++++++++++-----
include/linux/soc/ti/k3-ringacc.h | 5 +++++
2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c
index 9ddd77113c5a..7fdb688452f7 100644
--- a/drivers/soc/ti/k3-ringacc.c
+++ b/drivers/soc/ti/k3-ringacc.c
@@ -141,6 +141,7 @@ struct k3_ring_state {
* @parent: Pointer on struct @k3_ringacc
* @use_count: Use count for shared rings
* @proxy_id: RA Ring Proxy Id (only if @K3_RINGACC_RING_USE_PROXY)
+ * @dma_dev: device to be used for DMA API (allocation, mapping)
*/
struct k3_ring {
struct k3_ring_rt_regs __iomem *rt;
@@ -160,6 +161,7 @@ struct k3_ring {
struct k3_ringacc *parent;
u32 use_count;
int proxy_id;
+ struct device *dma_dev;
};

struct k3_ringacc_ops {
@@ -508,11 +510,12 @@ int k3_ringacc_ring_free(struct k3_ring *ring)

k3_ringacc_ring_free_sci(ring);

- dma_free_coherent(ringacc->dev,
+ dma_free_coherent(ring->dma_dev,
ring->size * (4 << ring->elm_size),
ring->ring_mem_virt, ring->ring_mem_dma);
ring->flags = 0;
ring->ops = NULL;
+ ring->dma_dev = NULL;
if (ring->proxy_id != K3_RINGACC_PROXY_NOT_USED) {
clear_bit(ring->proxy_id, ringacc->proxy_inuse);
ring->proxy = NULL;
@@ -633,8 +636,12 @@ int k3_ringacc_ring_cfg(struct k3_ring *ring, struct k3_ring_cfg *cfg)
switch (ring->mode) {
case K3_RINGACC_RING_MODE_RING:
ring->ops = &k3_ring_mode_ring_ops;
+ ring->dma_dev = cfg->dma_dev;
+ if (!ring->dma_dev)
+ ring->dma_dev = ringacc->dev;
break;
case K3_RINGACC_RING_MODE_MESSAGE:
+ ring->dma_dev = ringacc->dev;
if (ring->proxy)
ring->ops = &k3_ring_mode_proxy_ops;
else
@@ -646,9 +653,9 @@ int k3_ringacc_ring_cfg(struct k3_ring *ring, struct k3_ring_cfg *cfg)
goto err_free_proxy;
}

- ring->ring_mem_virt = dma_alloc_coherent(ringacc->dev,
- ring->size * (4 << ring->elm_size),
- &ring->ring_mem_dma, GFP_KERNEL);
+ ring->ring_mem_virt = dma_alloc_coherent(ring->dma_dev,
+ ring->size * (4 << ring->elm_size),
+ &ring->ring_mem_dma, GFP_KERNEL);
if (!ring->ring_mem_virt) {
dev_err(ringacc->dev, "Failed to alloc ring mem\n");
ret = -ENOMEM;
@@ -669,12 +676,13 @@ int k3_ringacc_ring_cfg(struct k3_ring *ring, struct k3_ring_cfg *cfg)
return 0;

err_free_mem:
- dma_free_coherent(ringacc->dev,
+ dma_free_coherent(ring->dma_dev,
ring->size * (4 << ring->elm_size),
ring->ring_mem_virt,
ring->ring_mem_dma);
err_free_ops:
ring->ops = NULL;
+ ring->dma_dev = NULL;
err_free_proxy:
ring->proxy = NULL;
return ret;
diff --git a/include/linux/soc/ti/k3-ringacc.h b/include/linux/soc/ti/k3-ringacc.h
index 5a472eca5ee4..658dc71d2901 100644
--- a/include/linux/soc/ti/k3-ringacc.h
+++ b/include/linux/soc/ti/k3-ringacc.h
@@ -67,6 +67,9 @@ struct k3_ring;
* few times. It's usable when the same ring is used as Free Host PD ring
* for different flows, for example.
* Note: Locking should be done by consumer if required
+ * @dma_dev: Master device which is using and accessing to the ring
+ * memory when the mode is K3_RINGACC_RING_MODE_RING. Memory allocations
+ * should be done using this device.
*/
struct k3_ring_cfg {
u32 size;
@@ -74,6 +77,8 @@ struct k3_ring_cfg {
enum k3_ring_mode mode;
#define K3_RINGACC_RING_SHARED BIT(1)
u32 flags;
+
+ struct device *dma_dev;
};

#define K3_RINGACC_RING_ID_ANY (-1)
--
Peter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki