Re: [PATCH v4 07/15] dmaengine: ti: k3 PSI-L remote endpoint configuration

From: Peter Ujfalusi
Date: Tue Nov 05 2019 - 03:12:59 EST




On 05/11/2019 9.49, Tero Kristo wrote:
> On 01/11/2019 10:41, Peter Ujfalusi wrote:
>> In K3 architecture the DMA operates within threads. One end of the thread
>> is UDMAP, the other is on the peripheral side.
>>
>> The UDMAP channel configuration depends on the needs of the remote
>> endpoint and it can be differ from peripheral to peripheral.
>>
>> This patch adds database for am654 and j721e and small API to fetch the
>> PSI-L endpoint configuration from the database which should only used by
>> the DMA driver(s).
>>
>> Another API is added for native peripherals to give possibility to
>> pass new
>> configuration for the threads they are using, which is needed to be
>> able to
>> handle changes caused by different firmware loaded for the peripheral for
>> example.
>>
>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@xxxxxx>
>> ---
>> Â drivers/dma/ti/KconfigÂÂÂÂÂÂÂÂ |ÂÂ 3 +
>> Â drivers/dma/ti/MakefileÂÂÂÂÂÂÂ |ÂÂ 1 +
>> Â drivers/dma/ti/k3-psil-am654.c | 172 ++++++++++++++++++++++++++
>> Â drivers/dma/ti/k3-psil-j721e.c | 219 +++++++++++++++++++++++++++++++++
>>  drivers/dma/ti/k3-psil-priv.h | 39 ++++++
>> Â drivers/dma/ti/k3-psil.cÂÂÂÂÂÂ |Â 97 +++++++++++++++
>> Â include/linux/dma/k3-psil.hÂÂÂ |Â 47 +++++++
>> Â 7 files changed, 578 insertions(+)
>> Â create mode 100644 drivers/dma/ti/k3-psil-am654.c
>> Â create mode 100644 drivers/dma/ti/k3-psil-j721e.c
>> Â create mode 100644 drivers/dma/ti/k3-psil-priv.h
>> Â create mode 100644 drivers/dma/ti/k3-psil.c
>> Â create mode 100644 include/linux/dma/k3-psil.h

...

>> diff --git a/drivers/dma/ti/k3-psil.c b/drivers/dma/ti/k3-psil.c
>> new file mode 100644
>> index 000000000000..e610022f09f4
>> --- /dev/null
>> +++ b/drivers/dma/ti/k3-psil.c
>> @@ -0,0 +1,97 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + *Â Copyright (C) 2019 Texas Instruments Incorporated -
>> http://www.ti.com
>> + *Â Author: Peter Ujfalusi <peter.ujfalusi@xxxxxx>
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/device.h>
>> +#include <linux/module.h>
>> +#include <linux/mutex.h>
>> +#include <linux/of.h>
>> +
>> +#include "k3-psil-priv.h"
>> +
>> +extern struct psil_ep_map am654_ep_map;
>> +extern struct psil_ep_map j721e_ep_map;
>> +
>> +static DEFINE_MUTEX(ep_map_mutex);
>> +static struct psil_ep_map *soc_ep_map;
>
> So, you are only protecting the high level soc_ep_map pointer only. You
> don't need to protect the database itself via some usecounting or
> something, or are you doing it within the DMA driver?

That's correct, I protect only the soc_ep_map.
The DMA drivers can look up threads concurrently I just need to make
sure that the soc_ep_map is configured when the first
psil_get_ep_config() comes.
After this the DMA drivers are free to look up things.

The ep_config update will be coming from the DMA client driver(s) and
not from the DMA driver. The clinet driver knows how thier PSI-L
endpoint if configured so they could update the default configuration
_before_ they would request a DMA channel.

>
> -Tero
>
>> +
>> +struct psil_endpoint_config *psil_get_ep_config(u32 thread_id)
>> +{
>> +ÂÂÂ int i;
>> +
>> +ÂÂÂ mutex_lock(&ep_map_mutex);
>> +ÂÂÂ if (!soc_ep_map) {
>> +ÂÂÂÂÂÂÂ if (of_machine_is_compatible("ti,am654")) {
>> +ÂÂÂÂÂÂÂÂÂÂÂ soc_ep_map = &am654_ep_map;
>> +ÂÂÂÂÂÂÂ } else if (of_machine_is_compatible("ti,j721e")) {
>> +ÂÂÂÂÂÂÂÂÂÂÂ soc_ep_map = &j721e_ep_map;
>> +ÂÂÂÂÂÂÂ } else {
>> +ÂÂÂÂÂÂÂÂÂÂÂ pr_err("PSIL: No compatible machine found for map\n");
>> +ÂÂÂÂÂÂÂÂÂÂÂ return ERR_PTR(-ENOTSUPP);
>> +ÂÂÂÂÂÂÂ }
>> +ÂÂÂÂÂÂÂ pr_debug("%s: Using map for %s\n", __func__, soc_ep_map->name);
>> +ÂÂÂ }
>> +ÂÂÂ mutex_unlock(&ep_map_mutex);
>> +
>> +ÂÂÂ if (thread_id & K3_PSIL_DST_THREAD_ID_OFFSET && soc_ep_map->dst) {
>> +ÂÂÂÂÂÂÂ /* check in destination thread map */
>> +ÂÂÂÂÂÂÂ for (i = 0; i < soc_ep_map->dst_count; i++) {
>> +ÂÂÂÂÂÂÂÂÂÂÂ if (soc_ep_map->dst[i].thread_id == thread_id)
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ return &soc_ep_map->dst[i].ep_config;
>> +ÂÂÂÂÂÂÂ }
>> +ÂÂÂ }
>> +
>> +ÂÂÂ thread_id &= ~K3_PSIL_DST_THREAD_ID_OFFSET;
>> +ÂÂÂ if (soc_ep_map->src) {
>> +ÂÂÂÂÂÂÂ for (i = 0; i < soc_ep_map->src_count; i++) {
>> +ÂÂÂÂÂÂÂÂÂÂÂ if (soc_ep_map->src[i].thread_id == thread_id)
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ return &soc_ep_map->src[i].ep_config;
>> +ÂÂÂÂÂÂÂ }
>> +ÂÂÂ }
>> +
>> +ÂÂÂ return ERR_PTR(-ENOENT);
>> +}
>> +EXPORT_SYMBOL(psil_get_ep_config);
>> +
>> +int psil_set_new_ep_config(struct device *dev, const char *name,
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ struct psil_endpoint_config *ep_config)
>> +{
>> +ÂÂÂ struct psil_endpoint_config *dst_ep_config;
>> +ÂÂÂ struct of_phandle_args dma_spec;
>> +ÂÂÂ u32 thread_id;
>> +ÂÂÂ int index;
>> +
>> +ÂÂÂ if (!dev || !dev->of_node)
>> +ÂÂÂÂÂÂÂ return -EINVAL;
>> +
>> +ÂÂÂ index = of_property_match_string(dev->of_node, "dma-names", name);
>> +ÂÂÂ if (index < 0)
>> +ÂÂÂÂÂÂÂ return index;
>> +
>> +ÂÂÂ if (of_parse_phandle_with_args(dev->of_node, "dmas", "#dma-cells",
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ index, &dma_spec))
>> +ÂÂÂÂÂÂÂ return -ENOENT;
>> +
>> +ÂÂÂ thread_id = dma_spec.args[0];
>> +
>> +ÂÂÂ dst_ep_config = psil_get_ep_config(thread_id);
>> +ÂÂÂ if (IS_ERR(dst_ep_config)) {
>> +ÂÂÂÂÂÂÂ pr_err("PSIL: thread ID 0x%04x not defined in map\n",
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ thread_id);
>> +ÂÂÂÂÂÂÂ of_node_put(dma_spec.np);
>> +ÂÂÂÂÂÂÂ return PTR_ERR(dst_ep_config);
>> +ÂÂÂ }
>> +
>> +ÂÂÂ memcpy(dst_ep_config, ep_config, sizeof(*dst_ep_config));
>> +
>> +ÂÂÂ of_node_put(dma_spec.np);
>> +ÂÂÂ return 0;
>> +}
>> +EXPORT_SYMBOL(psil_set_new_ep_config);
>> +
>> +MODULE_DESCRIPTION("TI K3 PSI-L endpoint database");
>> +MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@xxxxxx>");
>> +MODULE_LICENSE("GPL v2");
>> diff --git a/include/linux/dma/k3-psil.h b/include/linux/dma/k3-psil.h
>> new file mode 100644
>> index 000000000000..16e9c8c6f839
>> --- /dev/null
>> +++ b/include/linux/dma/k3-psil.h
>> @@ -0,0 +1,47 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + *Â Copyright (C) 2019 Texas Instruments Incorporated -
>> http://www.ti.com
>> + */
>> +
>> +#ifndef K3_PSIL_H_
>> +#define K3_PSIL_H_
>> +
>> +#include <linux/types.h>
>> +
>> +#define K3_PSIL_DST_THREAD_ID_OFFSET 0x8000
>> +
>> +struct device;
>> +
>> +/* Channel Throughput Levels */
>> +enum udma_tp_level {
>> +ÂÂÂ UDMA_TP_NORMAL = 0,
>> +ÂÂÂ UDMA_TP_HIGH = 1,
>> +ÂÂÂ UDMA_TP_ULTRAHIGH = 2,
>> +ÂÂÂ UDMA_TP_LAST,
>> +};
>> +
>> +enum psil_endpoint_type {
>> +ÂÂÂ PSIL_EP_NATIVE = 0,
>> +ÂÂÂ PSIL_EP_PDMA_XY,
>> +ÂÂÂ PSIL_EP_PDMA_MCAN,
>> +ÂÂÂ PSIL_EP_PDMA_AASRC,
>> +};
>> +
>> +struct psil_endpoint_config {
>> +ÂÂÂ enum psil_endpoint_type ep_type;
>> +
>> +ÂÂÂ unsigned pkt_mode:1;
>> +ÂÂÂ unsigned notdpkt:1;
>> +ÂÂÂ unsigned needs_epib:1;
>> +ÂÂÂ u32 psd_size;
>> +ÂÂÂ enum udma_tp_level channel_tpl;
>> +
>> +ÂÂÂ /* PDMA properties, valid for PSIL_EP_PDMA_* */
>> +ÂÂÂ unsigned pdma_acc32:1;
>> +ÂÂÂ unsigned pdma_burst:1;
>> +};
>> +
>> +int psil_set_new_ep_config(struct device *dev, const char *name,
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ struct psil_endpoint_config *ep_config);
>> +
>> +#endif /* K3_PSIL_H_ */
>>
>
> --
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

- PÃter

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