Lines Matching +full:mbox +full:- +full:rx

1 // SPDX-License-Identifier: GPL-2.0
13 #include <soc/tegra/bpmp-abi.h>
16 #include "bpmp-private.h"
28 } tx, rx; member
33 } mbox; member
41 priv = container_of(client, struct tegra186_bpmp, mbox.client); in mbox_client_to_bpmp()
43 return priv->parent; in mbox_client_to_bpmp()
50 err = tegra_ivc_read_get_next_frame(channel->ivc, &channel->ib); in tegra186_bpmp_is_message_ready()
52 iosys_map_clear(&channel->ib); in tegra186_bpmp_is_message_ready()
63 err = tegra_ivc_write_get_next_frame(channel->ivc, &channel->ob); in tegra186_bpmp_is_channel_free()
65 iosys_map_clear(&channel->ob); in tegra186_bpmp_is_channel_free()
74 return tegra_ivc_read_advance(channel->ivc); in tegra186_bpmp_ack_message()
79 return tegra_ivc_write_advance(channel->ivc); in tegra186_bpmp_post_message()
84 struct tegra186_bpmp *priv = bpmp->priv; in tegra186_bpmp_ring_doorbell()
87 err = mbox_send_message(priv->mbox.channel, NULL); in tegra186_bpmp_ring_doorbell()
91 mbox_client_txdone(priv->mbox.channel, 0); in tegra186_bpmp_ring_doorbell()
99 struct tegra186_bpmp *priv = bpmp->priv; in tegra186_bpmp_ivc_notify()
101 if (WARN_ON(priv->mbox.channel == NULL)) in tegra186_bpmp_ivc_notify()
111 struct tegra186_bpmp *priv = bpmp->priv; in tegra186_bpmp_channel_init()
113 struct iosys_map rx, tx; in tegra186_bpmp_channel_init() local
117 channel->ivc = devm_kzalloc(bpmp->dev, sizeof(*channel->ivc), in tegra186_bpmp_channel_init()
119 if (!channel->ivc) in tegra186_bpmp_channel_init()
120 return -ENOMEM; in tegra186_bpmp_channel_init()
126 if (priv->rx.pool) { in tegra186_bpmp_channel_init()
127 iosys_map_set_vaddr_iomem(&rx, priv->rx.sram + offset); in tegra186_bpmp_channel_init()
128 iosys_map_set_vaddr_iomem(&tx, priv->tx.sram + offset); in tegra186_bpmp_channel_init()
130 iosys_map_set_vaddr(&rx, priv->rx.dram + offset); in tegra186_bpmp_channel_init()
131 iosys_map_set_vaddr(&tx, priv->tx.dram + offset); in tegra186_bpmp_channel_init()
134 err = tegra_ivc_init(channel->ivc, NULL, &rx, priv->rx.phys + offset, &tx, in tegra186_bpmp_channel_init()
135 priv->tx.phys + offset, 1, message_size, tegra186_bpmp_ivc_notify, in tegra186_bpmp_channel_init()
138 dev_err(bpmp->dev, "failed to setup IVC for channel %u: %d\n", in tegra186_bpmp_channel_init()
143 init_completion(&channel->completion); in tegra186_bpmp_channel_init()
144 channel->bpmp = bpmp; in tegra186_bpmp_channel_init()
152 tegra_ivc_reset(channel->ivc); in tegra186_bpmp_channel_reset()
155 while (tegra_ivc_notified(channel->ivc)) in tegra186_bpmp_channel_reset()
161 tegra_ivc_cleanup(channel->ivc); in tegra186_bpmp_channel_cleanup()
173 struct tegra186_bpmp *priv = bpmp->priv; in tegra186_bpmp_teardown_channels()
176 for (i = 0; i < bpmp->threaded.count; i++) { in tegra186_bpmp_teardown_channels()
177 if (!bpmp->threaded_channels[i].bpmp) in tegra186_bpmp_teardown_channels()
180 tegra186_bpmp_channel_cleanup(&bpmp->threaded_channels[i]); in tegra186_bpmp_teardown_channels()
183 tegra186_bpmp_channel_cleanup(bpmp->rx_channel); in tegra186_bpmp_teardown_channels()
184 tegra186_bpmp_channel_cleanup(bpmp->tx_channel); in tegra186_bpmp_teardown_channels()
186 if (priv->tx.pool) { in tegra186_bpmp_teardown_channels()
187 gen_pool_free(priv->tx.pool, (unsigned long)priv->tx.sram, 4096); in tegra186_bpmp_teardown_channels()
188 gen_pool_free(priv->rx.pool, (unsigned long)priv->rx.sram, 4096); in tegra186_bpmp_teardown_channels()
194 struct tegra186_bpmp *priv = bpmp->priv; in tegra186_bpmp_dram_init()
200 np = of_parse_phandle(bpmp->dev->of_node, "memory-region", 0); in tegra186_bpmp_dram_init()
202 return -ENODEV; in tegra186_bpmp_dram_init()
206 dev_warn(bpmp->dev, "failed to parse memory region: %d\n", err); in tegra186_bpmp_dram_init()
213 dev_warn(bpmp->dev, "DRAM region must be larger than 8 KiB\n"); in tegra186_bpmp_dram_init()
214 return -EINVAL; in tegra186_bpmp_dram_init()
217 priv->tx.phys = res.start; in tegra186_bpmp_dram_init()
218 priv->rx.phys = res.start + SZ_4K; in tegra186_bpmp_dram_init()
220 priv->tx.dram = devm_memremap(bpmp->dev, priv->tx.phys, size, in tegra186_bpmp_dram_init()
222 if (IS_ERR(priv->tx.dram)) { in tegra186_bpmp_dram_init()
223 err = PTR_ERR(priv->tx.dram); in tegra186_bpmp_dram_init()
224 dev_warn(bpmp->dev, "failed to map DRAM region: %d\n", err); in tegra186_bpmp_dram_init()
228 priv->rx.dram = priv->tx.dram + SZ_4K; in tegra186_bpmp_dram_init()
235 struct tegra186_bpmp *priv = bpmp->priv; in tegra186_bpmp_sram_init()
238 priv->tx.pool = of_gen_pool_get(bpmp->dev->of_node, "shmem", 0); in tegra186_bpmp_sram_init()
239 if (!priv->tx.pool) { in tegra186_bpmp_sram_init()
240 dev_err(bpmp->dev, "TX shmem pool not found\n"); in tegra186_bpmp_sram_init()
241 return -EPROBE_DEFER; in tegra186_bpmp_sram_init()
244 priv->tx.sram = (void __iomem *)gen_pool_dma_alloc(priv->tx.pool, 4096, in tegra186_bpmp_sram_init()
245 &priv->tx.phys); in tegra186_bpmp_sram_init()
246 if (!priv->tx.sram) { in tegra186_bpmp_sram_init()
247 dev_err(bpmp->dev, "failed to allocate from TX pool\n"); in tegra186_bpmp_sram_init()
248 return -ENOMEM; in tegra186_bpmp_sram_init()
251 priv->rx.pool = of_gen_pool_get(bpmp->dev->of_node, "shmem", 1); in tegra186_bpmp_sram_init()
252 if (!priv->rx.pool) { in tegra186_bpmp_sram_init()
253 dev_err(bpmp->dev, "RX shmem pool not found\n"); in tegra186_bpmp_sram_init()
254 err = -EPROBE_DEFER; in tegra186_bpmp_sram_init()
258 priv->rx.sram = (void __iomem *)gen_pool_dma_alloc(priv->rx.pool, 4096, in tegra186_bpmp_sram_init()
259 &priv->rx.phys); in tegra186_bpmp_sram_init()
260 if (!priv->rx.sram) { in tegra186_bpmp_sram_init()
261 dev_err(bpmp->dev, "failed to allocate from RX pool\n"); in tegra186_bpmp_sram_init()
262 err = -ENOMEM; in tegra186_bpmp_sram_init()
269 gen_pool_free(priv->tx.pool, (unsigned long)priv->tx.sram, 4096); in tegra186_bpmp_sram_init()
280 if (err == -ENODEV) { in tegra186_bpmp_setup_channels()
286 err = tegra186_bpmp_channel_init(bpmp->tx_channel, bpmp, in tegra186_bpmp_setup_channels()
287 bpmp->soc->channels.cpu_tx.offset); in tegra186_bpmp_setup_channels()
291 err = tegra186_bpmp_channel_init(bpmp->rx_channel, bpmp, in tegra186_bpmp_setup_channels()
292 bpmp->soc->channels.cpu_rx.offset); in tegra186_bpmp_setup_channels()
294 tegra186_bpmp_channel_cleanup(bpmp->tx_channel); in tegra186_bpmp_setup_channels()
298 for (i = 0; i < bpmp->threaded.count; i++) { in tegra186_bpmp_setup_channels()
299 unsigned int index = bpmp->soc->channels.thread.offset + i; in tegra186_bpmp_setup_channels()
301 err = tegra186_bpmp_channel_init(&bpmp->threaded_channels[i], in tegra186_bpmp_setup_channels()
318 tegra186_bpmp_channel_reset(bpmp->tx_channel); in tegra186_bpmp_reset_channels()
319 tegra186_bpmp_channel_reset(bpmp->rx_channel); in tegra186_bpmp_reset_channels()
321 for (i = 0; i < bpmp->threaded.count; i++) in tegra186_bpmp_reset_channels()
322 tegra186_bpmp_channel_reset(&bpmp->threaded_channels[i]); in tegra186_bpmp_reset_channels()
330 priv = devm_kzalloc(bpmp->dev, sizeof(*priv), GFP_KERNEL); in tegra186_bpmp_init()
332 return -ENOMEM; in tegra186_bpmp_init()
334 priv->parent = bpmp; in tegra186_bpmp_init()
335 bpmp->priv = priv; in tegra186_bpmp_init()
341 /* mbox registration */ in tegra186_bpmp_init()
342 priv->mbox.client.dev = bpmp->dev; in tegra186_bpmp_init()
343 priv->mbox.client.rx_callback = mbox_handle_rx; in tegra186_bpmp_init()
344 priv->mbox.client.tx_block = false; in tegra186_bpmp_init()
345 priv->mbox.client.knows_txdone = false; in tegra186_bpmp_init()
347 priv->mbox.channel = mbox_request_channel(&priv->mbox.client, 0); in tegra186_bpmp_init()
348 if (IS_ERR(priv->mbox.channel)) { in tegra186_bpmp_init()
349 err = PTR_ERR(priv->mbox.channel); in tegra186_bpmp_init()
350 dev_err(bpmp->dev, "failed to get HSP mailbox: %d\n", err); in tegra186_bpmp_init()
362 struct tegra186_bpmp *priv = bpmp->priv; in tegra186_bpmp_deinit()
364 mbox_free_channel(priv->mbox.channel); in tegra186_bpmp_deinit()