1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com
4 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/device.h>
10 #include <linux/init.h>
11 #include <linux/mutex.h>
13 #include <linux/sys_soc.h>
15 #include "k3-psil-priv.h"
17 static DEFINE_MUTEX(ep_map_mutex
);
18 static const struct psil_ep_map
*soc_ep_map
;
20 static const struct soc_device_attribute k3_soc_devices
[] = {
21 { .family
= "AM65X", .data
= &am654_ep_map
},
22 { .family
= "J721E", .data
= &j721e_ep_map
},
23 { .family
= "J7200", .data
= &j7200_ep_map
},
24 { .family
= "AM64X", .data
= &am64_ep_map
},
25 { .family
= "J721S2", .data
= &j721s2_ep_map
},
26 { .family
= "AM62X", .data
= &am62_ep_map
},
27 { .family
= "AM62AX", .data
= &am62a_ep_map
},
28 { .family
= "J784S4", .data
= &j784s4_ep_map
},
29 { .family
= "AM62PX", .data
= &am62p_ep_map
},
30 { .family
= "J722S", .data
= &am62p_ep_map
},
34 struct psil_endpoint_config
*psil_get_ep_config(u32 thread_id
)
38 mutex_lock(&ep_map_mutex
);
40 const struct soc_device_attribute
*soc
;
42 soc
= soc_device_match(k3_soc_devices
);
44 soc_ep_map
= soc
->data
;
46 pr_err("PSIL: No compatible machine found for map\n");
47 mutex_unlock(&ep_map_mutex
);
48 return ERR_PTR(-ENOTSUPP
);
50 pr_debug("%s: Using map for %s\n", __func__
, soc_ep_map
->name
);
52 mutex_unlock(&ep_map_mutex
);
54 if (thread_id
& K3_PSIL_DST_THREAD_ID_OFFSET
&& soc_ep_map
->dst
) {
55 /* check in destination thread map */
56 for (i
= 0; i
< soc_ep_map
->dst_count
; i
++) {
57 if (soc_ep_map
->dst
[i
].thread_id
== thread_id
)
58 return &soc_ep_map
->dst
[i
].ep_config
;
62 thread_id
&= ~K3_PSIL_DST_THREAD_ID_OFFSET
;
63 if (soc_ep_map
->src
) {
64 for (i
= 0; i
< soc_ep_map
->src_count
; i
++) {
65 if (soc_ep_map
->src
[i
].thread_id
== thread_id
)
66 return &soc_ep_map
->src
[i
].ep_config
;
70 return ERR_PTR(-ENOENT
);
72 EXPORT_SYMBOL_GPL(psil_get_ep_config
);
74 int psil_set_new_ep_config(struct device
*dev
, const char *name
,
75 struct psil_endpoint_config
*ep_config
)
77 struct psil_endpoint_config
*dst_ep_config
;
78 struct of_phandle_args dma_spec
;
82 if (!dev
|| !dev
->of_node
)
85 index
= of_property_match_string(dev
->of_node
, "dma-names", name
);
89 if (of_parse_phandle_with_args(dev
->of_node
, "dmas", "#dma-cells",
93 thread_id
= dma_spec
.args
[0];
95 dst_ep_config
= psil_get_ep_config(thread_id
);
96 if (IS_ERR(dst_ep_config
)) {
97 pr_err("PSIL: thread ID 0x%04x not defined in map\n",
99 of_node_put(dma_spec
.np
);
100 return PTR_ERR(dst_ep_config
);
103 memcpy(dst_ep_config
, ep_config
, sizeof(*dst_ep_config
));
105 of_node_put(dma_spec
.np
);
108 EXPORT_SYMBOL_GPL(psil_set_new_ep_config
);
109 MODULE_DESCRIPTION("K3 PSI-L endpoint configuration");
110 MODULE_LICENSE("GPL v2");