Lines Matching full:bpmp
17 #include <soc/tegra/bpmp.h>
18 #include <soc/tegra/bpmp-abi.h>
21 #include "bpmp-private.h"
30 struct tegra_bpmp *bpmp = channel->bpmp; in channel_to_ops() local
32 return bpmp->soc->ops; in channel_to_ops()
38 struct tegra_bpmp *bpmp; in tegra_bpmp_get() local
41 np = of_parse_phandle(dev->of_node, "nvidia,bpmp", 0); in tegra_bpmp_get()
47 bpmp = ERR_PTR(-ENODEV); in tegra_bpmp_get()
51 bpmp = platform_get_drvdata(pdev); in tegra_bpmp_get()
52 if (!bpmp) { in tegra_bpmp_get()
53 bpmp = ERR_PTR(-EPROBE_DEFER); in tegra_bpmp_get()
60 return bpmp; in tegra_bpmp_get()
64 void tegra_bpmp_put(struct tegra_bpmp *bpmp) in tegra_bpmp_put() argument
66 if (bpmp) in tegra_bpmp_put()
67 put_device(bpmp->dev); in tegra_bpmp_put()
74 struct tegra_bpmp *bpmp = channel->bpmp; in tegra_bpmp_channel_get_thread_index() local
78 count = bpmp->soc->channels.thread.count; in tegra_bpmp_channel_get_thread_index()
80 index = channel - channel->bpmp->threaded_channels; in tegra_bpmp_channel_get_thread_index()
111 unsigned long timeout = channel->bpmp->soc->channels.cpu_tx.timeout; in tegra_bpmp_wait_response()
157 unsigned long timeout = channel->bpmp->soc->channels.cpu_tx.timeout; in tegra_bpmp_wait_request_channel_free()
186 static int tegra_bpmp_ring_doorbell(struct tegra_bpmp *bpmp) in tegra_bpmp_ring_doorbell() argument
188 return bpmp->soc->ops->ring_doorbell(bpmp); in tegra_bpmp_ring_doorbell()
211 struct tegra_bpmp *bpmp = channel->bpmp; in tegra_bpmp_channel_read() local
222 spin_lock_irqsave(&bpmp->lock, flags); in tegra_bpmp_channel_read()
224 clear_bit(index, bpmp->threaded.allocated); in tegra_bpmp_channel_read()
225 spin_unlock_irqrestore(&bpmp->lock, flags); in tegra_bpmp_channel_read()
228 up(&bpmp->threaded.lock); in tegra_bpmp_channel_read()
247 tegra_bpmp_write_threaded(struct tegra_bpmp *bpmp, unsigned int mrq, in tegra_bpmp_write_threaded() argument
250 unsigned long timeout = bpmp->soc->channels.thread.timeout; in tegra_bpmp_write_threaded()
251 unsigned int count = bpmp->soc->channels.thread.count; in tegra_bpmp_write_threaded()
257 err = down_timeout(&bpmp->threaded.lock, usecs_to_jiffies(timeout)); in tegra_bpmp_write_threaded()
261 spin_lock_irqsave(&bpmp->lock, flags); in tegra_bpmp_write_threaded()
263 index = find_first_zero_bit(bpmp->threaded.allocated, count); in tegra_bpmp_write_threaded()
269 channel = &bpmp->threaded_channels[index]; in tegra_bpmp_write_threaded()
276 set_bit(index, bpmp->threaded.allocated); in tegra_bpmp_write_threaded()
283 set_bit(index, bpmp->threaded.busy); in tegra_bpmp_write_threaded()
285 spin_unlock_irqrestore(&bpmp->lock, flags); in tegra_bpmp_write_threaded()
289 clear_bit(index, bpmp->threaded.allocated); in tegra_bpmp_write_threaded()
291 spin_unlock_irqrestore(&bpmp->lock, flags); in tegra_bpmp_write_threaded()
292 up(&bpmp->threaded.lock); in tegra_bpmp_write_threaded()
312 int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp, in tegra_bpmp_transfer_atomic() argument
324 if (bpmp->suspended) { in tegra_bpmp_transfer_atomic()
325 /* Reset BPMP IPC channels during resume based on flags passed */ in tegra_bpmp_transfer_atomic()
327 tegra_bpmp_resume(bpmp->dev); in tegra_bpmp_transfer_atomic()
332 channel = bpmp->tx_channel; in tegra_bpmp_transfer_atomic()
334 spin_lock(&bpmp->atomic_tx_lock); in tegra_bpmp_transfer_atomic()
339 spin_unlock(&bpmp->atomic_tx_lock); in tegra_bpmp_transfer_atomic()
343 spin_unlock(&bpmp->atomic_tx_lock); in tegra_bpmp_transfer_atomic()
345 err = tegra_bpmp_ring_doorbell(bpmp); in tegra_bpmp_transfer_atomic()
358 int tegra_bpmp_transfer(struct tegra_bpmp *bpmp, in tegra_bpmp_transfer() argument
371 if (bpmp->suspended) { in tegra_bpmp_transfer()
372 /* Reset BPMP IPC channels during resume based on flags passed */ in tegra_bpmp_transfer()
374 tegra_bpmp_resume(bpmp->dev); in tegra_bpmp_transfer()
379 channel = tegra_bpmp_write_threaded(bpmp, msg->mrq, msg->tx.data, in tegra_bpmp_transfer()
384 err = tegra_bpmp_ring_doorbell(bpmp); in tegra_bpmp_transfer()
388 timeout = usecs_to_jiffies(bpmp->soc->channels.thread.timeout); in tegra_bpmp_transfer()
399 static struct tegra_bpmp_mrq *tegra_bpmp_find_mrq(struct tegra_bpmp *bpmp, in tegra_bpmp_find_mrq() argument
404 list_for_each_entry(entry, &bpmp->mrqs, list) in tegra_bpmp_find_mrq()
415 struct tegra_bpmp *bpmp = channel->bpmp; in tegra_bpmp_mrq_return() local
441 err = tegra_bpmp_ring_doorbell(bpmp); in tegra_bpmp_mrq_return()
448 static void tegra_bpmp_handle_mrq(struct tegra_bpmp *bpmp, in tegra_bpmp_handle_mrq() argument
455 spin_lock(&bpmp->lock); in tegra_bpmp_handle_mrq()
457 entry = tegra_bpmp_find_mrq(bpmp, mrq); in tegra_bpmp_handle_mrq()
459 spin_unlock(&bpmp->lock); in tegra_bpmp_handle_mrq()
466 spin_unlock(&bpmp->lock); in tegra_bpmp_handle_mrq()
469 int tegra_bpmp_request_mrq(struct tegra_bpmp *bpmp, unsigned int mrq, in tegra_bpmp_request_mrq() argument
478 entry = devm_kzalloc(bpmp->dev, sizeof(*entry), GFP_KERNEL); in tegra_bpmp_request_mrq()
482 spin_lock_irqsave(&bpmp->lock, flags); in tegra_bpmp_request_mrq()
487 list_add(&entry->list, &bpmp->mrqs); in tegra_bpmp_request_mrq()
489 spin_unlock_irqrestore(&bpmp->lock, flags); in tegra_bpmp_request_mrq()
495 void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, unsigned int mrq, void *data) in tegra_bpmp_free_mrq() argument
500 spin_lock_irqsave(&bpmp->lock, flags); in tegra_bpmp_free_mrq()
502 entry = tegra_bpmp_find_mrq(bpmp, mrq); in tegra_bpmp_free_mrq()
507 devm_kfree(bpmp->dev, entry); in tegra_bpmp_free_mrq()
510 spin_unlock_irqrestore(&bpmp->lock, flags); in tegra_bpmp_free_mrq()
514 bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq) in tegra_bpmp_mrq_is_supported() argument
531 err = tegra_bpmp_transfer(bpmp, &msg); in tegra_bpmp_mrq_is_supported()
554 static int tegra_bpmp_ping(struct tegra_bpmp *bpmp) in tegra_bpmp_ping() argument
577 err = tegra_bpmp_transfer_atomic(bpmp, &msg); in tegra_bpmp_ping()
582 dev_dbg(bpmp->dev, in tegra_bpmp_ping()
591 static int tegra_bpmp_get_firmware_tag_old(struct tegra_bpmp *bpmp, char *tag, in tegra_bpmp_get_firmware_tag_old() argument
604 virt = dma_alloc_coherent(bpmp->dev, TAG_SZ, &phys, in tegra_bpmp_get_firmware_tag_old()
618 err = tegra_bpmp_transfer_atomic(bpmp, &msg); in tegra_bpmp_get_firmware_tag_old()
624 dma_free_coherent(bpmp->dev, TAG_SZ, virt, phys); in tegra_bpmp_get_firmware_tag_old()
629 static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag, in tegra_bpmp_get_firmware_tag() argument
632 if (tegra_bpmp_mrq_is_supported(bpmp, MRQ_QUERY_FW_TAG)) { in tegra_bpmp_get_firmware_tag()
646 err = tegra_bpmp_transfer(bpmp, &msg); in tegra_bpmp_get_firmware_tag()
657 return tegra_bpmp_get_firmware_tag_old(bpmp, tag, size); in tegra_bpmp_get_firmware_tag()
670 void tegra_bpmp_handle_rx(struct tegra_bpmp *bpmp) in tegra_bpmp_handle_rx() argument
676 channel = bpmp->rx_channel; in tegra_bpmp_handle_rx()
677 count = bpmp->soc->channels.thread.count; in tegra_bpmp_handle_rx()
678 busy = bpmp->threaded.busy; in tegra_bpmp_handle_rx()
683 tegra_bpmp_handle_mrq(bpmp, mrq, channel); in tegra_bpmp_handle_rx()
686 spin_lock(&bpmp->lock); in tegra_bpmp_handle_rx()
691 channel = &bpmp->threaded_channels[i]; in tegra_bpmp_handle_rx()
699 spin_unlock(&bpmp->lock); in tegra_bpmp_handle_rx()
704 struct tegra_bpmp *bpmp; in tegra_bpmp_probe() local
709 bpmp = devm_kzalloc(&pdev->dev, sizeof(*bpmp), GFP_KERNEL); in tegra_bpmp_probe()
710 if (!bpmp) in tegra_bpmp_probe()
713 bpmp->soc = of_device_get_match_data(&pdev->dev); in tegra_bpmp_probe()
714 bpmp->dev = &pdev->dev; in tegra_bpmp_probe()
716 INIT_LIST_HEAD(&bpmp->mrqs); in tegra_bpmp_probe()
717 spin_lock_init(&bpmp->lock); in tegra_bpmp_probe()
719 bpmp->threaded.count = bpmp->soc->channels.thread.count; in tegra_bpmp_probe()
720 sema_init(&bpmp->threaded.lock, bpmp->threaded.count); in tegra_bpmp_probe()
722 size = BITS_TO_LONGS(bpmp->threaded.count) * sizeof(long); in tegra_bpmp_probe()
724 bpmp->threaded.allocated = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); in tegra_bpmp_probe()
725 if (!bpmp->threaded.allocated) in tegra_bpmp_probe()
728 bpmp->threaded.busy = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); in tegra_bpmp_probe()
729 if (!bpmp->threaded.busy) in tegra_bpmp_probe()
732 spin_lock_init(&bpmp->atomic_tx_lock); in tegra_bpmp_probe()
733 bpmp->tx_channel = devm_kzalloc(&pdev->dev, sizeof(*bpmp->tx_channel), in tegra_bpmp_probe()
735 if (!bpmp->tx_channel) in tegra_bpmp_probe()
738 bpmp->rx_channel = devm_kzalloc(&pdev->dev, sizeof(*bpmp->rx_channel), in tegra_bpmp_probe()
740 if (!bpmp->rx_channel) in tegra_bpmp_probe()
743 bpmp->threaded_channels = devm_kcalloc(&pdev->dev, bpmp->threaded.count, in tegra_bpmp_probe()
744 sizeof(*bpmp->threaded_channels), in tegra_bpmp_probe()
746 if (!bpmp->threaded_channels) in tegra_bpmp_probe()
749 platform_set_drvdata(pdev, bpmp); in tegra_bpmp_probe()
751 err = bpmp->soc->ops->init(bpmp); in tegra_bpmp_probe()
755 err = tegra_bpmp_request_mrq(bpmp, MRQ_PING, in tegra_bpmp_probe()
756 tegra_bpmp_mrq_handle_ping, bpmp); in tegra_bpmp_probe()
760 err = tegra_bpmp_ping(bpmp); in tegra_bpmp_probe()
762 dev_err(&pdev->dev, "failed to ping BPMP: %d\n", err); in tegra_bpmp_probe()
766 err = tegra_bpmp_get_firmware_tag(bpmp, tag, sizeof(tag)); in tegra_bpmp_probe()
779 err = tegra_bpmp_init_clocks(bpmp); in tegra_bpmp_probe()
785 err = tegra_bpmp_init_resets(bpmp); in tegra_bpmp_probe()
791 err = tegra_bpmp_init_powergates(bpmp); in tegra_bpmp_probe()
796 err = tegra_bpmp_init_debugfs(bpmp); in tegra_bpmp_probe()
803 tegra_bpmp_free_mrq(bpmp, MRQ_PING, bpmp); in tegra_bpmp_probe()
805 if (bpmp->soc->ops->deinit) in tegra_bpmp_probe()
806 bpmp->soc->ops->deinit(bpmp); in tegra_bpmp_probe()
813 struct tegra_bpmp *bpmp = dev_get_drvdata(dev); in tegra_bpmp_suspend() local
815 bpmp->suspended = true; in tegra_bpmp_suspend()
822 struct tegra_bpmp *bpmp = dev_get_drvdata(dev); in tegra_bpmp_resume() local
824 bpmp->suspended = false; in tegra_bpmp_resume()
826 if (bpmp->soc->ops->resume) in tegra_bpmp_resume()
827 return bpmp->soc->ops->resume(bpmp); in tegra_bpmp_resume()
888 { .compatible = "nvidia,tegra186-bpmp", .data = &tegra186_soc },
891 { .compatible = "nvidia,tegra210-bpmp", .data = &tegra210_soc },
898 .name = "tegra-bpmp",