• Home
  • Raw
  • Download

Lines Matching +full:data +full:- +full:channel

1 // SPDX-License-Identifier: GPL-2.0-only
19 #include <soc/tegra/bpmp-abi.h>
22 #include "bpmp-private.h"
35 channel_to_ops(struct tegra_bpmp_channel *channel) in channel_to_ops() argument
37 struct tegra_bpmp *bpmp = channel->bpmp; in channel_to_ops()
39 return bpmp->soc->ops; in channel_to_ops()
48 np = of_parse_phandle(dev->of_node, "nvidia,bpmp", 0); in tegra_bpmp_get()
50 return ERR_PTR(-ENOENT); in tegra_bpmp_get()
54 bpmp = ERR_PTR(-ENODEV); in tegra_bpmp_get()
60 bpmp = ERR_PTR(-EPROBE_DEFER); in tegra_bpmp_get()
61 put_device(&pdev->dev); in tegra_bpmp_get()
74 put_device(bpmp->dev); in tegra_bpmp_put()
79 tegra_bpmp_channel_get_thread_index(struct tegra_bpmp_channel *channel) in tegra_bpmp_channel_get_thread_index() argument
81 struct tegra_bpmp *bpmp = channel->bpmp; in tegra_bpmp_channel_get_thread_index()
85 count = bpmp->soc->channels.thread.count; in tegra_bpmp_channel_get_thread_index()
87 index = channel - channel->bpmp->threaded_channels; in tegra_bpmp_channel_get_thread_index()
89 return -EINVAL; in tegra_bpmp_channel_get_thread_index()
96 return (msg->tx.size <= MSG_DATA_MIN_SZ) && in tegra_bpmp_message_valid()
97 (msg->rx.size <= MSG_DATA_MIN_SZ) && in tegra_bpmp_message_valid()
98 (msg->tx.size == 0 || msg->tx.data) && in tegra_bpmp_message_valid()
99 (msg->rx.size == 0 || msg->rx.data); in tegra_bpmp_message_valid()
102 static bool tegra_bpmp_is_response_ready(struct tegra_bpmp_channel *channel) in tegra_bpmp_is_response_ready() argument
104 const struct tegra_bpmp_ops *ops = channel_to_ops(channel); in tegra_bpmp_is_response_ready()
106 return ops->is_response_ready(channel); in tegra_bpmp_is_response_ready()
109 static bool tegra_bpmp_is_request_ready(struct tegra_bpmp_channel *channel) in tegra_bpmp_is_request_ready() argument
111 const struct tegra_bpmp_ops *ops = channel_to_ops(channel); in tegra_bpmp_is_request_ready()
113 return ops->is_request_ready(channel); in tegra_bpmp_is_request_ready()
116 static int tegra_bpmp_wait_response(struct tegra_bpmp_channel *channel) in tegra_bpmp_wait_response() argument
118 unsigned long timeout = channel->bpmp->soc->channels.cpu_tx.timeout; in tegra_bpmp_wait_response()
124 if (tegra_bpmp_is_response_ready(channel)) in tegra_bpmp_wait_response()
128 return -ETIMEDOUT; in tegra_bpmp_wait_response()
131 static int tegra_bpmp_ack_response(struct tegra_bpmp_channel *channel) in tegra_bpmp_ack_response() argument
133 const struct tegra_bpmp_ops *ops = channel_to_ops(channel); in tegra_bpmp_ack_response()
135 return ops->ack_response(channel); in tegra_bpmp_ack_response()
138 static int tegra_bpmp_ack_request(struct tegra_bpmp_channel *channel) in tegra_bpmp_ack_request() argument
140 const struct tegra_bpmp_ops *ops = channel_to_ops(channel); in tegra_bpmp_ack_request()
142 return ops->ack_request(channel); in tegra_bpmp_ack_request()
146 tegra_bpmp_is_request_channel_free(struct tegra_bpmp_channel *channel) in tegra_bpmp_is_request_channel_free() argument
148 const struct tegra_bpmp_ops *ops = channel_to_ops(channel); in tegra_bpmp_is_request_channel_free()
150 return ops->is_request_channel_free(channel); in tegra_bpmp_is_request_channel_free()
154 tegra_bpmp_is_response_channel_free(struct tegra_bpmp_channel *channel) in tegra_bpmp_is_response_channel_free() argument
156 const struct tegra_bpmp_ops *ops = channel_to_ops(channel); in tegra_bpmp_is_response_channel_free()
158 return ops->is_response_channel_free(channel); in tegra_bpmp_is_response_channel_free()
162 tegra_bpmp_wait_request_channel_free(struct tegra_bpmp_channel *channel) in tegra_bpmp_wait_request_channel_free() argument
164 unsigned long timeout = channel->bpmp->soc->channels.cpu_tx.timeout; in tegra_bpmp_wait_request_channel_free()
170 if (tegra_bpmp_is_request_channel_free(channel)) in tegra_bpmp_wait_request_channel_free()
176 return -ETIMEDOUT; in tegra_bpmp_wait_request_channel_free()
179 static int tegra_bpmp_post_request(struct tegra_bpmp_channel *channel) in tegra_bpmp_post_request() argument
181 const struct tegra_bpmp_ops *ops = channel_to_ops(channel); in tegra_bpmp_post_request()
183 return ops->post_request(channel); in tegra_bpmp_post_request()
186 static int tegra_bpmp_post_response(struct tegra_bpmp_channel *channel) in tegra_bpmp_post_response() argument
188 const struct tegra_bpmp_ops *ops = channel_to_ops(channel); in tegra_bpmp_post_response()
190 return ops->post_response(channel); in tegra_bpmp_post_response()
195 return bpmp->soc->ops->ring_doorbell(bpmp); in tegra_bpmp_ring_doorbell()
198 static ssize_t __tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel, in __tegra_bpmp_channel_read() argument
199 void *data, size_t size, int *ret) in __tegra_bpmp_channel_read() argument
203 if (data && size > 0) in __tegra_bpmp_channel_read()
204 memcpy(data, channel->ib->data, size); in __tegra_bpmp_channel_read()
206 err = tegra_bpmp_ack_response(channel); in __tegra_bpmp_channel_read()
210 *ret = channel->ib->code; in __tegra_bpmp_channel_read()
215 static ssize_t tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel, in tegra_bpmp_channel_read() argument
216 void *data, size_t size, int *ret) in tegra_bpmp_channel_read() argument
218 struct tegra_bpmp *bpmp = channel->bpmp; in tegra_bpmp_channel_read()
223 index = tegra_bpmp_channel_get_thread_index(channel); in tegra_bpmp_channel_read()
229 spin_lock_irqsave(&bpmp->lock, flags); in tegra_bpmp_channel_read()
230 err = __tegra_bpmp_channel_read(channel, data, size, ret); in tegra_bpmp_channel_read()
231 clear_bit(index, bpmp->threaded.allocated); in tegra_bpmp_channel_read()
232 spin_unlock_irqrestore(&bpmp->lock, flags); in tegra_bpmp_channel_read()
235 up(&bpmp->threaded.lock); in tegra_bpmp_channel_read()
240 static ssize_t __tegra_bpmp_channel_write(struct tegra_bpmp_channel *channel, in __tegra_bpmp_channel_write() argument
242 const void *data, size_t size) in __tegra_bpmp_channel_write() argument
244 channel->ob->code = mrq; in __tegra_bpmp_channel_write()
245 channel->ob->flags = flags; in __tegra_bpmp_channel_write()
247 if (data && size > 0) in __tegra_bpmp_channel_write()
248 memcpy(channel->ob->data, data, size); in __tegra_bpmp_channel_write()
250 return tegra_bpmp_post_request(channel); in __tegra_bpmp_channel_write()
255 const void *data, size_t size) in tegra_bpmp_write_threaded() argument
257 unsigned long timeout = bpmp->soc->channels.thread.timeout; in tegra_bpmp_write_threaded()
258 unsigned int count = bpmp->soc->channels.thread.count; in tegra_bpmp_write_threaded()
259 struct tegra_bpmp_channel *channel; in tegra_bpmp_write_threaded() local
264 err = down_timeout(&bpmp->threaded.lock, usecs_to_jiffies(timeout)); in tegra_bpmp_write_threaded()
268 spin_lock_irqsave(&bpmp->lock, flags); in tegra_bpmp_write_threaded()
270 index = find_first_zero_bit(bpmp->threaded.allocated, count); in tegra_bpmp_write_threaded()
272 err = -EBUSY; in tegra_bpmp_write_threaded()
276 channel = &bpmp->threaded_channels[index]; in tegra_bpmp_write_threaded()
278 if (!tegra_bpmp_is_request_channel_free(channel)) { in tegra_bpmp_write_threaded()
279 err = -EBUSY; in tegra_bpmp_write_threaded()
283 set_bit(index, bpmp->threaded.allocated); in tegra_bpmp_write_threaded()
285 err = __tegra_bpmp_channel_write(channel, mrq, MSG_ACK | MSG_RING, in tegra_bpmp_write_threaded()
286 data, size); in tegra_bpmp_write_threaded()
290 set_bit(index, bpmp->threaded.busy); in tegra_bpmp_write_threaded()
292 spin_unlock_irqrestore(&bpmp->lock, flags); in tegra_bpmp_write_threaded()
293 return channel; in tegra_bpmp_write_threaded()
296 clear_bit(index, bpmp->threaded.allocated); in tegra_bpmp_write_threaded()
298 spin_unlock_irqrestore(&bpmp->lock, flags); in tegra_bpmp_write_threaded()
299 up(&bpmp->threaded.lock); in tegra_bpmp_write_threaded()
304 static ssize_t tegra_bpmp_channel_write(struct tegra_bpmp_channel *channel, in tegra_bpmp_channel_write() argument
306 const void *data, size_t size) in tegra_bpmp_channel_write() argument
310 err = tegra_bpmp_wait_request_channel_free(channel); in tegra_bpmp_channel_write()
314 return __tegra_bpmp_channel_write(channel, mrq, flags, data, size); in tegra_bpmp_channel_write()
320 struct tegra_bpmp_channel *channel; in tegra_bpmp_transfer_atomic() local
324 return -EPERM; in tegra_bpmp_transfer_atomic()
327 return -EINVAL; in tegra_bpmp_transfer_atomic()
329 channel = bpmp->tx_channel; in tegra_bpmp_transfer_atomic()
331 spin_lock(&bpmp->atomic_tx_lock); in tegra_bpmp_transfer_atomic()
333 err = tegra_bpmp_channel_write(channel, msg->mrq, MSG_ACK, in tegra_bpmp_transfer_atomic()
334 msg->tx.data, msg->tx.size); in tegra_bpmp_transfer_atomic()
336 spin_unlock(&bpmp->atomic_tx_lock); in tegra_bpmp_transfer_atomic()
340 spin_unlock(&bpmp->atomic_tx_lock); in tegra_bpmp_transfer_atomic()
346 err = tegra_bpmp_wait_response(channel); in tegra_bpmp_transfer_atomic()
350 return __tegra_bpmp_channel_read(channel, msg->rx.data, msg->rx.size, in tegra_bpmp_transfer_atomic()
351 &msg->rx.ret); in tegra_bpmp_transfer_atomic()
358 struct tegra_bpmp_channel *channel; in tegra_bpmp_transfer() local
363 return -EPERM; in tegra_bpmp_transfer()
366 return -EINVAL; in tegra_bpmp_transfer()
368 channel = tegra_bpmp_write_threaded(bpmp, msg->mrq, msg->tx.data, in tegra_bpmp_transfer()
369 msg->tx.size); in tegra_bpmp_transfer()
370 if (IS_ERR(channel)) in tegra_bpmp_transfer()
371 return PTR_ERR(channel); in tegra_bpmp_transfer()
377 timeout = usecs_to_jiffies(bpmp->soc->channels.thread.timeout); in tegra_bpmp_transfer()
379 err = wait_for_completion_timeout(&channel->completion, timeout); in tegra_bpmp_transfer()
381 return -ETIMEDOUT; in tegra_bpmp_transfer()
383 return tegra_bpmp_channel_read(channel, msg->rx.data, msg->rx.size, in tegra_bpmp_transfer()
384 &msg->rx.ret); in tegra_bpmp_transfer()
393 list_for_each_entry(entry, &bpmp->mrqs, list) in tegra_bpmp_find_mrq()
394 if (entry->mrq == mrq) in tegra_bpmp_find_mrq()
400 void tegra_bpmp_mrq_return(struct tegra_bpmp_channel *channel, int code, in tegra_bpmp_mrq_return() argument
401 const void *data, size_t size) in tegra_bpmp_mrq_return() argument
403 unsigned long flags = channel->ib->flags; in tegra_bpmp_mrq_return()
404 struct tegra_bpmp *bpmp = channel->bpmp; in tegra_bpmp_mrq_return()
410 err = tegra_bpmp_ack_request(channel); in tegra_bpmp_mrq_return()
417 if (WARN_ON(!tegra_bpmp_is_response_channel_free(channel))) in tegra_bpmp_mrq_return()
420 channel->ob->code = code; in tegra_bpmp_mrq_return()
422 if (data && size > 0) in tegra_bpmp_mrq_return()
423 memcpy(channel->ob->data, data, size); in tegra_bpmp_mrq_return()
425 err = tegra_bpmp_post_response(channel); in tegra_bpmp_mrq_return()
439 struct tegra_bpmp_channel *channel) in tegra_bpmp_handle_mrq() argument
444 spin_lock(&bpmp->lock); in tegra_bpmp_handle_mrq()
448 spin_unlock(&bpmp->lock); in tegra_bpmp_handle_mrq()
449 tegra_bpmp_mrq_return(channel, -EINVAL, &zero, sizeof(zero)); in tegra_bpmp_handle_mrq()
453 entry->handler(mrq, channel, entry->data); in tegra_bpmp_handle_mrq()
455 spin_unlock(&bpmp->lock); in tegra_bpmp_handle_mrq()
459 tegra_bpmp_mrq_handler_t handler, void *data) in tegra_bpmp_request_mrq() argument
465 return -EINVAL; in tegra_bpmp_request_mrq()
467 entry = devm_kzalloc(bpmp->dev, sizeof(*entry), GFP_KERNEL); in tegra_bpmp_request_mrq()
469 return -ENOMEM; in tegra_bpmp_request_mrq()
471 spin_lock_irqsave(&bpmp->lock, flags); in tegra_bpmp_request_mrq()
473 entry->mrq = mrq; in tegra_bpmp_request_mrq()
474 entry->handler = handler; in tegra_bpmp_request_mrq()
475 entry->data = data; in tegra_bpmp_request_mrq()
476 list_add(&entry->list, &bpmp->mrqs); in tegra_bpmp_request_mrq()
478 spin_unlock_irqrestore(&bpmp->lock, flags); in tegra_bpmp_request_mrq()
484 void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, unsigned int mrq, void *data) in tegra_bpmp_free_mrq() argument
489 spin_lock_irqsave(&bpmp->lock, flags); in tegra_bpmp_free_mrq()
495 list_del(&entry->list); in tegra_bpmp_free_mrq()
496 devm_kfree(bpmp->dev, entry); in tegra_bpmp_free_mrq()
499 spin_unlock_irqrestore(&bpmp->lock, flags); in tegra_bpmp_free_mrq()
510 .data = &req, in tegra_bpmp_mrq_is_supported()
514 .data = &resp, in tegra_bpmp_mrq_is_supported()
529 struct tegra_bpmp_channel *channel, in tegra_bpmp_mrq_handle_ping() argument
530 void *data) in tegra_bpmp_mrq_handle_ping() argument
535 request = (struct mrq_ping_request *)channel->ib->data; in tegra_bpmp_mrq_handle_ping()
538 response.reply = request->challenge << 1; in tegra_bpmp_mrq_handle_ping()
540 tegra_bpmp_mrq_return(channel, 0, &response, sizeof(response)); in tegra_bpmp_mrq_handle_ping()
559 msg.tx.data = &request; in tegra_bpmp_ping()
561 msg.rx.data = &response; in tegra_bpmp_ping()
571 dev_dbg(bpmp->dev, in tegra_bpmp_ping()
591 return -EINVAL; in tegra_bpmp_get_firmware_tag_old()
593 virt = dma_alloc_coherent(bpmp->dev, TAG_SZ, &phys, in tegra_bpmp_get_firmware_tag_old()
596 return -ENOMEM; in tegra_bpmp_get_firmware_tag_old()
603 msg.tx.data = &request; in tegra_bpmp_get_firmware_tag_old()
613 dma_free_coherent(bpmp->dev, TAG_SZ, virt, phys); in tegra_bpmp_get_firmware_tag_old()
626 .data = &resp, in tegra_bpmp_get_firmware_tag()
633 return -EINVAL; in tegra_bpmp_get_firmware_tag()
640 return -EINVAL; in tegra_bpmp_get_firmware_tag()
649 static void tegra_bpmp_channel_signal(struct tegra_bpmp_channel *channel) in tegra_bpmp_channel_signal() argument
651 unsigned long flags = channel->ob->flags; in tegra_bpmp_channel_signal()
656 complete(&channel->completion); in tegra_bpmp_channel_signal()
661 struct tegra_bpmp_channel *channel; in tegra_bpmp_handle_rx() local
665 channel = bpmp->rx_channel; in tegra_bpmp_handle_rx()
666 count = bpmp->soc->channels.thread.count; in tegra_bpmp_handle_rx()
667 busy = bpmp->threaded.busy; in tegra_bpmp_handle_rx()
669 if (tegra_bpmp_is_request_ready(channel)) in tegra_bpmp_handle_rx()
670 tegra_bpmp_handle_mrq(bpmp, channel->ib->code, channel); in tegra_bpmp_handle_rx()
672 spin_lock(&bpmp->lock); in tegra_bpmp_handle_rx()
675 struct tegra_bpmp_channel *channel; in tegra_bpmp_handle_rx() local
677 channel = &bpmp->threaded_channels[i]; in tegra_bpmp_handle_rx()
679 if (tegra_bpmp_is_response_ready(channel)) { in tegra_bpmp_handle_rx()
680 tegra_bpmp_channel_signal(channel); in tegra_bpmp_handle_rx()
685 spin_unlock(&bpmp->lock); in tegra_bpmp_handle_rx()
695 bpmp = devm_kzalloc(&pdev->dev, sizeof(*bpmp), GFP_KERNEL); in tegra_bpmp_probe()
697 return -ENOMEM; in tegra_bpmp_probe()
699 bpmp->soc = of_device_get_match_data(&pdev->dev); in tegra_bpmp_probe()
700 bpmp->dev = &pdev->dev; in tegra_bpmp_probe()
702 INIT_LIST_HEAD(&bpmp->mrqs); in tegra_bpmp_probe()
703 spin_lock_init(&bpmp->lock); in tegra_bpmp_probe()
705 bpmp->threaded.count = bpmp->soc->channels.thread.count; in tegra_bpmp_probe()
706 sema_init(&bpmp->threaded.lock, bpmp->threaded.count); in tegra_bpmp_probe()
708 size = BITS_TO_LONGS(bpmp->threaded.count) * sizeof(long); in tegra_bpmp_probe()
710 bpmp->threaded.allocated = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); in tegra_bpmp_probe()
711 if (!bpmp->threaded.allocated) in tegra_bpmp_probe()
712 return -ENOMEM; in tegra_bpmp_probe()
714 bpmp->threaded.busy = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); in tegra_bpmp_probe()
715 if (!bpmp->threaded.busy) in tegra_bpmp_probe()
716 return -ENOMEM; in tegra_bpmp_probe()
718 spin_lock_init(&bpmp->atomic_tx_lock); in tegra_bpmp_probe()
719 bpmp->tx_channel = devm_kzalloc(&pdev->dev, sizeof(*bpmp->tx_channel), in tegra_bpmp_probe()
721 if (!bpmp->tx_channel) in tegra_bpmp_probe()
722 return -ENOMEM; in tegra_bpmp_probe()
724 bpmp->rx_channel = devm_kzalloc(&pdev->dev, sizeof(*bpmp->rx_channel), in tegra_bpmp_probe()
726 if (!bpmp->rx_channel) in tegra_bpmp_probe()
727 return -ENOMEM; in tegra_bpmp_probe()
729 bpmp->threaded_channels = devm_kcalloc(&pdev->dev, bpmp->threaded.count, in tegra_bpmp_probe()
730 sizeof(*bpmp->threaded_channels), in tegra_bpmp_probe()
732 if (!bpmp->threaded_channels) in tegra_bpmp_probe()
733 return -ENOMEM; in tegra_bpmp_probe()
735 err = bpmp->soc->ops->init(bpmp); in tegra_bpmp_probe()
746 dev_err(&pdev->dev, "failed to ping BPMP: %d\n", err); in tegra_bpmp_probe()
752 dev_err(&pdev->dev, "failed to get firmware tag: %d\n", err); in tegra_bpmp_probe()
756 dev_info(&pdev->dev, "firmware: %.*s\n", (int)sizeof(tag), tag); in tegra_bpmp_probe()
760 err = of_platform_default_populate(pdev->dev.of_node, NULL, &pdev->dev); in tegra_bpmp_probe()
764 if (of_find_property(pdev->dev.of_node, "#clock-cells", NULL)) { in tegra_bpmp_probe()
770 if (of_find_property(pdev->dev.of_node, "#reset-cells", NULL)) { in tegra_bpmp_probe()
776 if (of_find_property(pdev->dev.of_node, "#power-domain-cells", NULL)) { in tegra_bpmp_probe()
784 dev_err(&pdev->dev, "debugfs initialization failed: %d\n", err); in tegra_bpmp_probe()
791 if (bpmp->soc->ops->deinit) in tegra_bpmp_probe()
792 bpmp->soc->ops->deinit(bpmp); in tegra_bpmp_probe()
801 if (bpmp->soc->ops->resume) in tegra_bpmp_resume()
802 return bpmp->soc->ops->resume(bpmp); in tegra_bpmp_resume()
862 { .compatible = "nvidia,tegra186-bpmp", .data = &tegra186_soc },
865 { .compatible = "nvidia,tegra210-bpmp", .data = &tegra210_soc },
872 .name = "tegra-bpmp",