.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved. |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License version 2 as |
---|
6 | | - * published by the Free Software Foundation. |
---|
7 | 4 | */ |
---|
8 | 5 | |
---|
9 | 6 | #include <linux/clk.h> |
---|
| 7 | +#include <linux/delay.h> |
---|
10 | 8 | #include <linux/host1x.h> |
---|
11 | 9 | #include <linux/module.h> |
---|
12 | 10 | #include <linux/of.h> |
---|
.. | .. |
---|
16 | 14 | #include <linux/pm_runtime.h> |
---|
17 | 15 | #include <linux/reset.h> |
---|
18 | 16 | |
---|
19 | | -#include <drm/drmP.h> |
---|
20 | 17 | #include <drm/drm_atomic.h> |
---|
21 | 18 | #include <drm/drm_atomic_helper.h> |
---|
22 | | -#include <drm/drm_crtc_helper.h> |
---|
| 19 | +#include <drm/drm_fourcc.h> |
---|
| 20 | +#include <drm/drm_probe_helper.h> |
---|
23 | 21 | |
---|
24 | 22 | #include "drm.h" |
---|
25 | 23 | #include "dc.h" |
---|
.. | .. |
---|
97 | 95 | |
---|
98 | 96 | static int tegra_windowgroup_enable(struct tegra_windowgroup *wgrp) |
---|
99 | 97 | { |
---|
| 98 | + int err = 0; |
---|
| 99 | + |
---|
100 | 100 | mutex_lock(&wgrp->lock); |
---|
101 | 101 | |
---|
102 | 102 | if (wgrp->usecount == 0) { |
---|
103 | | - pm_runtime_get_sync(wgrp->parent); |
---|
| 103 | + err = host1x_client_resume(wgrp->parent); |
---|
| 104 | + if (err < 0) { |
---|
| 105 | + dev_err(wgrp->parent->dev, "failed to resume: %d\n", err); |
---|
| 106 | + goto unlock; |
---|
| 107 | + } |
---|
| 108 | + |
---|
104 | 109 | reset_control_deassert(wgrp->rst); |
---|
105 | 110 | } |
---|
106 | 111 | |
---|
107 | 112 | wgrp->usecount++; |
---|
108 | | - mutex_unlock(&wgrp->lock); |
---|
109 | 113 | |
---|
110 | | - return 0; |
---|
| 114 | +unlock: |
---|
| 115 | + mutex_unlock(&wgrp->lock); |
---|
| 116 | + return err; |
---|
111 | 117 | } |
---|
112 | 118 | |
---|
113 | 119 | static void tegra_windowgroup_disable(struct tegra_windowgroup *wgrp) |
---|
.. | .. |
---|
123 | 129 | wgrp->index); |
---|
124 | 130 | } |
---|
125 | 131 | |
---|
126 | | - pm_runtime_put(wgrp->parent); |
---|
| 132 | + host1x_client_suspend(wgrp->parent); |
---|
127 | 133 | } |
---|
128 | 134 | |
---|
129 | 135 | wgrp->usecount--; |
---|
.. | .. |
---|
385 | 391 | struct tegra_plane *p = to_tegra_plane(plane); |
---|
386 | 392 | struct tegra_dc *dc; |
---|
387 | 393 | u32 value; |
---|
| 394 | + int err; |
---|
388 | 395 | |
---|
389 | 396 | /* rien ne va plus */ |
---|
390 | 397 | if (!old_state || !old_state->crtc) |
---|
391 | 398 | return; |
---|
392 | 399 | |
---|
393 | 400 | dc = to_tegra_dc(old_state->crtc); |
---|
| 401 | + |
---|
| 402 | + err = host1x_client_resume(&dc->client); |
---|
| 403 | + if (err < 0) { |
---|
| 404 | + dev_err(dc->dev, "failed to resume: %d\n", err); |
---|
| 405 | + return; |
---|
| 406 | + } |
---|
394 | 407 | |
---|
395 | 408 | /* |
---|
396 | 409 | * XXX Legacy helpers seem to sometimes call ->atomic_disable() even |
---|
.. | .. |
---|
400 | 413 | if (WARN_ON(p->dc == NULL)) |
---|
401 | 414 | p->dc = dc; |
---|
402 | 415 | |
---|
403 | | - pm_runtime_get_sync(dc->dev); |
---|
404 | | - |
---|
405 | 416 | value = tegra_plane_readl(p, DC_WIN_WIN_OPTIONS); |
---|
406 | 417 | value &= ~WIN_ENABLE; |
---|
407 | 418 | tegra_plane_writel(p, value, DC_WIN_WIN_OPTIONS); |
---|
408 | 419 | |
---|
409 | 420 | tegra_dc_remove_shared_plane(dc, p); |
---|
410 | 421 | |
---|
411 | | - pm_runtime_put(dc->dev); |
---|
| 422 | + host1x_client_suspend(&dc->client); |
---|
412 | 423 | } |
---|
413 | 424 | |
---|
414 | 425 | static void tegra_shared_plane_atomic_update(struct drm_plane *plane, |
---|
.. | .. |
---|
419 | 430 | unsigned int zpos = plane->state->normalized_zpos; |
---|
420 | 431 | struct drm_framebuffer *fb = plane->state->fb; |
---|
421 | 432 | struct tegra_plane *p = to_tegra_plane(plane); |
---|
422 | | - struct tegra_bo *bo; |
---|
423 | 433 | dma_addr_t base; |
---|
424 | 434 | u32 value; |
---|
| 435 | + int err; |
---|
425 | 436 | |
---|
426 | 437 | /* rien ne va plus */ |
---|
427 | 438 | if (!plane->state->crtc || !plane->state->fb) |
---|
.. | .. |
---|
432 | 443 | return; |
---|
433 | 444 | } |
---|
434 | 445 | |
---|
435 | | - pm_runtime_get_sync(dc->dev); |
---|
| 446 | + err = host1x_client_resume(&dc->client); |
---|
| 447 | + if (err < 0) { |
---|
| 448 | + dev_err(dc->dev, "failed to resume: %d\n", err); |
---|
| 449 | + return; |
---|
| 450 | + } |
---|
436 | 451 | |
---|
437 | 452 | tegra_dc_assign_shared_plane(dc, p); |
---|
438 | 453 | |
---|
.. | .. |
---|
462 | 477 | /* disable compression */ |
---|
463 | 478 | tegra_plane_writel(p, 0, DC_WINBUF_CDE_CONTROL); |
---|
464 | 479 | |
---|
465 | | - bo = tegra_fb_get_plane(fb, 0); |
---|
466 | | - base = bo->paddr; |
---|
| 480 | + base = state->iova[0] + fb->offsets[0]; |
---|
467 | 481 | |
---|
468 | 482 | tegra_plane_writel(p, state->format, DC_WIN_COLOR_DEPTH); |
---|
469 | 483 | tegra_plane_writel(p, 0, DC_WIN_PRECOMP_WGRP_PARAMS); |
---|
.. | .. |
---|
523 | 537 | value &= ~CONTROL_CSC_ENABLE; |
---|
524 | 538 | tegra_plane_writel(p, value, DC_WIN_WINDOW_SET_CONTROL); |
---|
525 | 539 | |
---|
526 | | - pm_runtime_put(dc->dev); |
---|
| 540 | + host1x_client_suspend(&dc->client); |
---|
527 | 541 | } |
---|
528 | 542 | |
---|
529 | 543 | static const struct drm_plane_helper_funcs tegra_shared_plane_helper_funcs = { |
---|
| 544 | + .prepare_fb = tegra_plane_prepare_fb, |
---|
| 545 | + .cleanup_fb = tegra_plane_cleanup_fb, |
---|
530 | 546 | .atomic_check = tegra_shared_plane_atomic_check, |
---|
531 | 547 | .atomic_update = tegra_shared_plane_atomic_update, |
---|
532 | 548 | .atomic_disable = tegra_shared_plane_atomic_disable, |
---|
.. | .. |
---|
557 | 573 | plane->base.index = index; |
---|
558 | 574 | |
---|
559 | 575 | plane->wgrp = &hub->wgrps[wgrp]; |
---|
560 | | - plane->wgrp->parent = dc->dev; |
---|
| 576 | + plane->wgrp->parent = &dc->client; |
---|
561 | 577 | |
---|
562 | 578 | p = &plane->base.base; |
---|
563 | 579 | |
---|
.. | .. |
---|
611 | 627 | tegra_display_hub_get_state(struct tegra_display_hub *hub, |
---|
612 | 628 | struct drm_atomic_state *state) |
---|
613 | 629 | { |
---|
614 | | - struct drm_device *drm = dev_get_drvdata(hub->client.parent); |
---|
615 | 630 | struct drm_private_state *priv; |
---|
616 | | - |
---|
617 | | - WARN_ON(!drm_modeset_is_locked(&drm->mode_config.connection_mutex)); |
---|
618 | 631 | |
---|
619 | 632 | priv = drm_atomic_get_private_obj_state(state, &hub->base); |
---|
620 | 633 | if (IS_ERR(priv)) |
---|
.. | .. |
---|
665 | 678 | static void tegra_display_hub_update(struct tegra_dc *dc) |
---|
666 | 679 | { |
---|
667 | 680 | u32 value; |
---|
| 681 | + int err; |
---|
668 | 682 | |
---|
669 | | - pm_runtime_get_sync(dc->dev); |
---|
| 683 | + err = host1x_client_resume(&dc->client); |
---|
| 684 | + if (err < 0) { |
---|
| 685 | + dev_err(dc->dev, "failed to resume: %d\n", err); |
---|
| 686 | + return; |
---|
| 687 | + } |
---|
670 | 688 | |
---|
671 | 689 | value = tegra_dc_readl(dc, DC_CMD_IHUB_COMMON_MISC_CTL); |
---|
672 | 690 | value &= ~LATENCY_EVENT; |
---|
.. | .. |
---|
681 | 699 | tegra_dc_writel(dc, COMMON_ACTREQ, DC_CMD_STATE_CONTROL); |
---|
682 | 700 | tegra_dc_readl(dc, DC_CMD_STATE_CONTROL); |
---|
683 | 701 | |
---|
684 | | - pm_runtime_put(dc->dev); |
---|
| 702 | + host1x_client_suspend(&dc->client); |
---|
685 | 703 | } |
---|
686 | 704 | |
---|
687 | 705 | void tegra_display_hub_atomic_commit(struct drm_device *drm, |
---|
.. | .. |
---|
714 | 732 | static int tegra_display_hub_init(struct host1x_client *client) |
---|
715 | 733 | { |
---|
716 | 734 | struct tegra_display_hub *hub = to_tegra_display_hub(client); |
---|
717 | | - struct drm_device *drm = dev_get_drvdata(client->parent); |
---|
| 735 | + struct drm_device *drm = dev_get_drvdata(client->host); |
---|
718 | 736 | struct tegra_drm *tegra = drm->dev_private; |
---|
719 | 737 | struct tegra_display_hub_state *state; |
---|
720 | 738 | |
---|
.. | .. |
---|
722 | 740 | if (!state) |
---|
723 | 741 | return -ENOMEM; |
---|
724 | 742 | |
---|
725 | | - drm_atomic_private_obj_init(&hub->base, &state->base, |
---|
| 743 | + drm_atomic_private_obj_init(drm, &hub->base, &state->base, |
---|
726 | 744 | &tegra_display_hub_state_funcs); |
---|
727 | 745 | |
---|
728 | 746 | tegra->hub = hub; |
---|
.. | .. |
---|
732 | 750 | |
---|
733 | 751 | static int tegra_display_hub_exit(struct host1x_client *client) |
---|
734 | 752 | { |
---|
735 | | - struct drm_device *drm = dev_get_drvdata(client->parent); |
---|
| 753 | + struct drm_device *drm = dev_get_drvdata(client->host); |
---|
736 | 754 | struct tegra_drm *tegra = drm->dev_private; |
---|
737 | 755 | |
---|
738 | 756 | drm_atomic_private_obj_fini(&tegra->hub->base); |
---|
.. | .. |
---|
741 | 759 | return 0; |
---|
742 | 760 | } |
---|
743 | 761 | |
---|
| 762 | +static int tegra_display_hub_runtime_suspend(struct host1x_client *client) |
---|
| 763 | +{ |
---|
| 764 | + struct tegra_display_hub *hub = to_tegra_display_hub(client); |
---|
| 765 | + struct device *dev = client->dev; |
---|
| 766 | + unsigned int i = hub->num_heads; |
---|
| 767 | + int err; |
---|
| 768 | + |
---|
| 769 | + err = reset_control_assert(hub->rst); |
---|
| 770 | + if (err < 0) |
---|
| 771 | + return err; |
---|
| 772 | + |
---|
| 773 | + while (i--) |
---|
| 774 | + clk_disable_unprepare(hub->clk_heads[i]); |
---|
| 775 | + |
---|
| 776 | + clk_disable_unprepare(hub->clk_hub); |
---|
| 777 | + clk_disable_unprepare(hub->clk_dsc); |
---|
| 778 | + clk_disable_unprepare(hub->clk_disp); |
---|
| 779 | + |
---|
| 780 | + pm_runtime_put_sync(dev); |
---|
| 781 | + |
---|
| 782 | + return 0; |
---|
| 783 | +} |
---|
| 784 | + |
---|
| 785 | +static int tegra_display_hub_runtime_resume(struct host1x_client *client) |
---|
| 786 | +{ |
---|
| 787 | + struct tegra_display_hub *hub = to_tegra_display_hub(client); |
---|
| 788 | + struct device *dev = client->dev; |
---|
| 789 | + unsigned int i; |
---|
| 790 | + int err; |
---|
| 791 | + |
---|
| 792 | + err = pm_runtime_resume_and_get(dev); |
---|
| 793 | + if (err < 0) { |
---|
| 794 | + dev_err(dev, "failed to get runtime PM: %d\n", err); |
---|
| 795 | + return err; |
---|
| 796 | + } |
---|
| 797 | + |
---|
| 798 | + err = clk_prepare_enable(hub->clk_disp); |
---|
| 799 | + if (err < 0) |
---|
| 800 | + goto put_rpm; |
---|
| 801 | + |
---|
| 802 | + err = clk_prepare_enable(hub->clk_dsc); |
---|
| 803 | + if (err < 0) |
---|
| 804 | + goto disable_disp; |
---|
| 805 | + |
---|
| 806 | + err = clk_prepare_enable(hub->clk_hub); |
---|
| 807 | + if (err < 0) |
---|
| 808 | + goto disable_dsc; |
---|
| 809 | + |
---|
| 810 | + for (i = 0; i < hub->num_heads; i++) { |
---|
| 811 | + err = clk_prepare_enable(hub->clk_heads[i]); |
---|
| 812 | + if (err < 0) |
---|
| 813 | + goto disable_heads; |
---|
| 814 | + } |
---|
| 815 | + |
---|
| 816 | + err = reset_control_deassert(hub->rst); |
---|
| 817 | + if (err < 0) |
---|
| 818 | + goto disable_heads; |
---|
| 819 | + |
---|
| 820 | + return 0; |
---|
| 821 | + |
---|
| 822 | +disable_heads: |
---|
| 823 | + while (i--) |
---|
| 824 | + clk_disable_unprepare(hub->clk_heads[i]); |
---|
| 825 | + |
---|
| 826 | + clk_disable_unprepare(hub->clk_hub); |
---|
| 827 | +disable_dsc: |
---|
| 828 | + clk_disable_unprepare(hub->clk_dsc); |
---|
| 829 | +disable_disp: |
---|
| 830 | + clk_disable_unprepare(hub->clk_disp); |
---|
| 831 | +put_rpm: |
---|
| 832 | + pm_runtime_put_sync(dev); |
---|
| 833 | + return err; |
---|
| 834 | +} |
---|
| 835 | + |
---|
744 | 836 | static const struct host1x_client_ops tegra_display_hub_ops = { |
---|
745 | 837 | .init = tegra_display_hub_init, |
---|
746 | 838 | .exit = tegra_display_hub_exit, |
---|
| 839 | + .suspend = tegra_display_hub_runtime_suspend, |
---|
| 840 | + .resume = tegra_display_hub_runtime_resume, |
---|
747 | 841 | }; |
---|
748 | 842 | |
---|
749 | 843 | static int tegra_display_hub_probe(struct platform_device *pdev) |
---|
750 | 844 | { |
---|
| 845 | + struct device_node *child = NULL; |
---|
751 | 846 | struct tegra_display_hub *hub; |
---|
| 847 | + struct clk *clk; |
---|
752 | 848 | unsigned int i; |
---|
753 | 849 | int err; |
---|
754 | 850 | |
---|
.. | .. |
---|
764 | 860 | return err; |
---|
765 | 861 | } |
---|
766 | 862 | |
---|
767 | | - hub->clk_dsc = devm_clk_get(&pdev->dev, "dsc"); |
---|
768 | | - if (IS_ERR(hub->clk_dsc)) { |
---|
769 | | - err = PTR_ERR(hub->clk_dsc); |
---|
770 | | - return err; |
---|
| 863 | + if (hub->soc->supports_dsc) { |
---|
| 864 | + hub->clk_dsc = devm_clk_get(&pdev->dev, "dsc"); |
---|
| 865 | + if (IS_ERR(hub->clk_dsc)) { |
---|
| 866 | + err = PTR_ERR(hub->clk_dsc); |
---|
| 867 | + return err; |
---|
| 868 | + } |
---|
771 | 869 | } |
---|
772 | 870 | |
---|
773 | 871 | hub->clk_hub = devm_clk_get(&pdev->dev, "hub"); |
---|
.. | .. |
---|
805 | 903 | return err; |
---|
806 | 904 | } |
---|
807 | 905 | |
---|
| 906 | + hub->num_heads = of_get_child_count(pdev->dev.of_node); |
---|
| 907 | + |
---|
| 908 | + hub->clk_heads = devm_kcalloc(&pdev->dev, hub->num_heads, sizeof(clk), |
---|
| 909 | + GFP_KERNEL); |
---|
| 910 | + if (!hub->clk_heads) |
---|
| 911 | + return -ENOMEM; |
---|
| 912 | + |
---|
| 913 | + for (i = 0; i < hub->num_heads; i++) { |
---|
| 914 | + child = of_get_next_child(pdev->dev.of_node, child); |
---|
| 915 | + if (!child) { |
---|
| 916 | + dev_err(&pdev->dev, "failed to find node for head %u\n", |
---|
| 917 | + i); |
---|
| 918 | + return -ENODEV; |
---|
| 919 | + } |
---|
| 920 | + |
---|
| 921 | + clk = devm_get_clk_from_child(&pdev->dev, child, "dc"); |
---|
| 922 | + if (IS_ERR(clk)) { |
---|
| 923 | + dev_err(&pdev->dev, "failed to get clock for head %u\n", |
---|
| 924 | + i); |
---|
| 925 | + of_node_put(child); |
---|
| 926 | + return PTR_ERR(clk); |
---|
| 927 | + } |
---|
| 928 | + |
---|
| 929 | + hub->clk_heads[i] = clk; |
---|
| 930 | + } |
---|
| 931 | + |
---|
| 932 | + of_node_put(child); |
---|
| 933 | + |
---|
808 | 934 | /* XXX: enable clock across reset? */ |
---|
809 | 935 | err = reset_control_assert(hub->rst); |
---|
810 | 936 | if (err < 0) |
---|
.. | .. |
---|
822 | 948 | dev_err(&pdev->dev, "failed to register host1x client: %d\n", |
---|
823 | 949 | err); |
---|
824 | 950 | |
---|
| 951 | + err = devm_of_platform_populate(&pdev->dev); |
---|
| 952 | + if (err < 0) |
---|
| 953 | + goto unregister; |
---|
| 954 | + |
---|
| 955 | + return err; |
---|
| 956 | + |
---|
| 957 | +unregister: |
---|
| 958 | + host1x_client_unregister(&hub->client); |
---|
| 959 | + pm_runtime_disable(&pdev->dev); |
---|
825 | 960 | return err; |
---|
826 | 961 | } |
---|
827 | 962 | |
---|
828 | 963 | static int tegra_display_hub_remove(struct platform_device *pdev) |
---|
829 | 964 | { |
---|
830 | 965 | struct tegra_display_hub *hub = platform_get_drvdata(pdev); |
---|
| 966 | + unsigned int i; |
---|
831 | 967 | int err; |
---|
832 | 968 | |
---|
833 | 969 | err = host1x_client_unregister(&hub->client); |
---|
.. | .. |
---|
836 | 972 | err); |
---|
837 | 973 | } |
---|
838 | 974 | |
---|
| 975 | + for (i = 0; i < hub->soc->num_wgrps; i++) { |
---|
| 976 | + struct tegra_windowgroup *wgrp = &hub->wgrps[i]; |
---|
| 977 | + |
---|
| 978 | + mutex_destroy(&wgrp->lock); |
---|
| 979 | + } |
---|
| 980 | + |
---|
839 | 981 | pm_runtime_disable(&pdev->dev); |
---|
840 | 982 | |
---|
841 | 983 | return err; |
---|
842 | 984 | } |
---|
843 | 985 | |
---|
844 | | -static int __maybe_unused tegra_display_hub_suspend(struct device *dev) |
---|
845 | | -{ |
---|
846 | | - struct tegra_display_hub *hub = dev_get_drvdata(dev); |
---|
847 | | - int err; |
---|
848 | | - |
---|
849 | | - err = reset_control_assert(hub->rst); |
---|
850 | | - if (err < 0) |
---|
851 | | - return err; |
---|
852 | | - |
---|
853 | | - clk_disable_unprepare(hub->clk_hub); |
---|
854 | | - clk_disable_unprepare(hub->clk_dsc); |
---|
855 | | - clk_disable_unprepare(hub->clk_disp); |
---|
856 | | - |
---|
857 | | - return 0; |
---|
858 | | -} |
---|
859 | | - |
---|
860 | | -static int __maybe_unused tegra_display_hub_resume(struct device *dev) |
---|
861 | | -{ |
---|
862 | | - struct tegra_display_hub *hub = dev_get_drvdata(dev); |
---|
863 | | - int err; |
---|
864 | | - |
---|
865 | | - err = clk_prepare_enable(hub->clk_disp); |
---|
866 | | - if (err < 0) |
---|
867 | | - return err; |
---|
868 | | - |
---|
869 | | - err = clk_prepare_enable(hub->clk_dsc); |
---|
870 | | - if (err < 0) |
---|
871 | | - goto disable_disp; |
---|
872 | | - |
---|
873 | | - err = clk_prepare_enable(hub->clk_hub); |
---|
874 | | - if (err < 0) |
---|
875 | | - goto disable_dsc; |
---|
876 | | - |
---|
877 | | - err = reset_control_deassert(hub->rst); |
---|
878 | | - if (err < 0) |
---|
879 | | - goto disable_hub; |
---|
880 | | - |
---|
881 | | - return 0; |
---|
882 | | - |
---|
883 | | -disable_hub: |
---|
884 | | - clk_disable_unprepare(hub->clk_hub); |
---|
885 | | -disable_dsc: |
---|
886 | | - clk_disable_unprepare(hub->clk_dsc); |
---|
887 | | -disable_disp: |
---|
888 | | - clk_disable_unprepare(hub->clk_disp); |
---|
889 | | - return err; |
---|
890 | | -} |
---|
891 | | - |
---|
892 | | -static const struct dev_pm_ops tegra_display_hub_pm_ops = { |
---|
893 | | - SET_RUNTIME_PM_OPS(tegra_display_hub_suspend, |
---|
894 | | - tegra_display_hub_resume, NULL) |
---|
895 | | -}; |
---|
896 | | - |
---|
897 | 986 | static const struct tegra_display_hub_soc tegra186_display_hub = { |
---|
898 | 987 | .num_wgrps = 6, |
---|
| 988 | + .supports_dsc = true, |
---|
| 989 | +}; |
---|
| 990 | + |
---|
| 991 | +static const struct tegra_display_hub_soc tegra194_display_hub = { |
---|
| 992 | + .num_wgrps = 6, |
---|
| 993 | + .supports_dsc = false, |
---|
899 | 994 | }; |
---|
900 | 995 | |
---|
901 | 996 | static const struct of_device_id tegra_display_hub_of_match[] = { |
---|
902 | 997 | { |
---|
| 998 | + .compatible = "nvidia,tegra194-display", |
---|
| 999 | + .data = &tegra194_display_hub |
---|
| 1000 | + }, { |
---|
903 | 1001 | .compatible = "nvidia,tegra186-display", |
---|
904 | 1002 | .data = &tegra186_display_hub |
---|
905 | 1003 | }, { |
---|
.. | .. |
---|
912 | 1010 | .driver = { |
---|
913 | 1011 | .name = "tegra-display-hub", |
---|
914 | 1012 | .of_match_table = tegra_display_hub_of_match, |
---|
915 | | - .pm = &tegra_display_hub_pm_ops, |
---|
916 | 1013 | }, |
---|
917 | 1014 | .probe = tegra_display_hub_probe, |
---|
918 | 1015 | .remove = tegra_display_hub_remove, |
---|