diff options
-rw-r--r-- | drivers/gpu/drm/tegra/drm.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/dsi.c | 358 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/output.c | 5 |
3 files changed, 195 insertions, 169 deletions
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 95b6aebfaf00..ae3daa436ee6 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h | |||
@@ -193,7 +193,6 @@ struct tegra_output_ops { | |||
193 | }; | 193 | }; |
194 | 194 | ||
195 | enum tegra_output_type { | 195 | enum tegra_output_type { |
196 | TEGRA_OUTPUT_DSI, | ||
197 | TEGRA_OUTPUT_EDP, | 196 | TEGRA_OUTPUT_EDP, |
198 | }; | 197 | }; |
199 | 198 | ||
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 4c0dfe92402a..0b476e1c005a 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c | |||
@@ -51,7 +51,6 @@ struct tegra_dsi { | |||
51 | struct mipi_dsi_host host; | 51 | struct mipi_dsi_host host; |
52 | 52 | ||
53 | struct regulator *vdd; | 53 | struct regulator *vdd; |
54 | bool enabled; | ||
55 | 54 | ||
56 | unsigned int video_fifo_depth; | 55 | unsigned int video_fifo_depth; |
57 | unsigned int host_fifo_depth; | 56 | unsigned int host_fifo_depth; |
@@ -628,46 +627,6 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, | |||
628 | return 0; | 627 | return 0; |
629 | } | 628 | } |
630 | 629 | ||
631 | static int tegra_output_dsi_enable(struct tegra_output *output) | ||
632 | { | ||
633 | struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc); | ||
634 | const struct drm_display_mode *mode = &dc->base.mode; | ||
635 | struct tegra_dsi *dsi = to_dsi(output); | ||
636 | u32 value; | ||
637 | int err; | ||
638 | |||
639 | if (dsi->enabled) | ||
640 | return 0; | ||
641 | |||
642 | err = tegra_dsi_configure(dsi, dc->pipe, mode); | ||
643 | if (err < 0) | ||
644 | return err; | ||
645 | |||
646 | /* enable display controller */ | ||
647 | value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); | ||
648 | value |= DSI_ENABLE; | ||
649 | tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); | ||
650 | |||
651 | value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND); | ||
652 | value &= ~DISP_CTRL_MODE_MASK; | ||
653 | value |= DISP_CTRL_MODE_C_DISPLAY; | ||
654 | tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND); | ||
655 | |||
656 | value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL); | ||
657 | value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | | ||
658 | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE; | ||
659 | tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL); | ||
660 | |||
661 | tegra_dc_commit(dc); | ||
662 | |||
663 | /* enable DSI controller */ | ||
664 | tegra_dsi_enable(dsi); | ||
665 | |||
666 | dsi->enabled = true; | ||
667 | |||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | static int tegra_dsi_wait_idle(struct tegra_dsi *dsi, unsigned long timeout) | 630 | static int tegra_dsi_wait_idle(struct tegra_dsi *dsi, unsigned long timeout) |
672 | { | 631 | { |
673 | u32 value; | 632 | u32 value; |
@@ -704,6 +663,29 @@ static void tegra_dsi_ganged_disable(struct tegra_dsi *dsi) | |||
704 | tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_CONTROL); | 663 | tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_CONTROL); |
705 | } | 664 | } |
706 | 665 | ||
666 | static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk, | ||
667 | unsigned int vrefresh) | ||
668 | { | ||
669 | unsigned int timeout; | ||
670 | u32 value; | ||
671 | |||
672 | /* one frame high-speed transmission timeout */ | ||
673 | timeout = (bclk / vrefresh) / 512; | ||
674 | value = DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(timeout); | ||
675 | tegra_dsi_writel(dsi, value, DSI_TIMEOUT_0); | ||
676 | |||
677 | /* 2 ms peripheral timeout for panel */ | ||
678 | timeout = 2 * bclk / 512 * 1000; | ||
679 | value = DSI_TIMEOUT_PR(timeout) | DSI_TIMEOUT_TA(0x2000); | ||
680 | tegra_dsi_writel(dsi, value, DSI_TIMEOUT_1); | ||
681 | |||
682 | value = DSI_TALLY_TA(0) | DSI_TALLY_LRX(0) | DSI_TALLY_HTX(0); | ||
683 | tegra_dsi_writel(dsi, value, DSI_TO_TALLY); | ||
684 | |||
685 | if (dsi->slave) | ||
686 | tegra_dsi_set_timeout(dsi->slave, bclk, vrefresh); | ||
687 | } | ||
688 | |||
707 | static void tegra_dsi_disable(struct tegra_dsi *dsi) | 689 | static void tegra_dsi_disable(struct tegra_dsi *dsi) |
708 | { | 690 | { |
709 | u32 value; | 691 | u32 value; |
@@ -747,82 +729,51 @@ static void tegra_dsi_soft_reset(struct tegra_dsi *dsi) | |||
747 | tegra_dsi_soft_reset(dsi->slave); | 729 | tegra_dsi_soft_reset(dsi->slave); |
748 | } | 730 | } |
749 | 731 | ||
750 | static int tegra_output_dsi_disable(struct tegra_output *output) | 732 | static void tegra_dsi_connector_dpms(struct drm_connector *connector, int mode) |
751 | { | 733 | { |
752 | struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc); | ||
753 | struct tegra_dsi *dsi = to_dsi(output); | ||
754 | u32 value; | ||
755 | int err; | ||
756 | |||
757 | if (!dsi->enabled) | ||
758 | return 0; | ||
759 | |||
760 | tegra_dsi_video_disable(dsi); | ||
761 | |||
762 | /* | ||
763 | * The following accesses registers of the display controller, so make | ||
764 | * sure it's only executed when the output is attached to one. | ||
765 | */ | ||
766 | if (dc) { | ||
767 | value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL); | ||
768 | value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | | ||
769 | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE); | ||
770 | tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL); | ||
771 | |||
772 | value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); | ||
773 | value &= ~DSI_ENABLE; | ||
774 | tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); | ||
775 | |||
776 | tegra_dc_commit(dc); | ||
777 | } | ||
778 | |||
779 | err = tegra_dsi_wait_idle(dsi, 100); | ||
780 | if (err < 0) | ||
781 | dev_dbg(dsi->dev, "failed to idle DSI: %d\n", err); | ||
782 | |||
783 | tegra_dsi_soft_reset(dsi); | ||
784 | tegra_dsi_disable(dsi); | ||
785 | |||
786 | dsi->enabled = false; | ||
787 | |||
788 | return 0; | ||
789 | } | 734 | } |
790 | 735 | ||
791 | static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk, | 736 | static const struct drm_connector_funcs tegra_dsi_connector_funcs = { |
792 | unsigned int vrefresh) | 737 | .dpms = tegra_dsi_connector_dpms, |
793 | { | 738 | .detect = tegra_output_connector_detect, |
794 | unsigned int timeout; | 739 | .fill_modes = drm_helper_probe_single_connector_modes, |
795 | u32 value; | 740 | .destroy = tegra_output_connector_destroy, |
741 | }; | ||
796 | 742 | ||
797 | /* one frame high-speed transmission timeout */ | 743 | static enum drm_mode_status |
798 | timeout = (bclk / vrefresh) / 512; | 744 | tegra_dsi_connector_mode_valid(struct drm_connector *connector, |
799 | value = DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(timeout); | 745 | struct drm_display_mode *mode) |
800 | tegra_dsi_writel(dsi, value, DSI_TIMEOUT_0); | 746 | { |
747 | return MODE_OK; | ||
748 | } | ||
801 | 749 | ||
802 | /* 2 ms peripheral timeout for panel */ | 750 | static const struct drm_connector_helper_funcs tegra_dsi_connector_helper_funcs = { |
803 | timeout = 2 * bclk / 512 * 1000; | 751 | .get_modes = tegra_output_connector_get_modes, |
804 | value = DSI_TIMEOUT_PR(timeout) | DSI_TIMEOUT_TA(0x2000); | 752 | .mode_valid = tegra_dsi_connector_mode_valid, |
805 | tegra_dsi_writel(dsi, value, DSI_TIMEOUT_1); | 753 | .best_encoder = tegra_output_connector_best_encoder, |
754 | }; | ||
806 | 755 | ||
807 | value = DSI_TALLY_TA(0) | DSI_TALLY_LRX(0) | DSI_TALLY_HTX(0); | 756 | static const struct drm_encoder_funcs tegra_dsi_encoder_funcs = { |
808 | tegra_dsi_writel(dsi, value, DSI_TO_TALLY); | 757 | .destroy = tegra_output_encoder_destroy, |
758 | }; | ||
809 | 759 | ||
810 | if (dsi->slave) | 760 | static void tegra_dsi_encoder_dpms(struct drm_encoder *encoder, int mode) |
811 | tegra_dsi_set_timeout(dsi->slave, bclk, vrefresh); | 761 | { |
812 | } | 762 | } |
813 | 763 | ||
814 | static int tegra_output_dsi_setup_clock(struct tegra_output *output, | 764 | static bool tegra_dsi_encoder_mode_fixup(struct drm_encoder *encoder, |
815 | struct clk *clk, unsigned long pclk, | 765 | const struct drm_display_mode *mode, |
816 | unsigned int *divp) | 766 | struct drm_display_mode *adjusted) |
817 | { | 767 | { |
818 | struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc); | 768 | struct tegra_output *output = encoder_to_output(encoder); |
819 | struct drm_display_mode *mode = &dc->base.mode; | 769 | struct tegra_dc *dc = to_tegra_dc(encoder->crtc); |
770 | unsigned int mul, div, scdiv, vrefresh, lanes; | ||
820 | struct tegra_dsi *dsi = to_dsi(output); | 771 | struct tegra_dsi *dsi = to_dsi(output); |
821 | unsigned int mul, div, vrefresh, lanes; | 772 | unsigned long pclk, bclk, plld; |
822 | unsigned long bclk, plld; | ||
823 | int err; | 773 | int err; |
824 | 774 | ||
825 | lanes = tegra_dsi_get_lanes(dsi); | 775 | lanes = tegra_dsi_get_lanes(dsi); |
776 | pclk = mode->clock * 1000; | ||
826 | 777 | ||
827 | err = tegra_dsi_get_muldiv(dsi->format, &mul, &div); | 778 | err = tegra_dsi_get_muldiv(dsi->format, &mul, &div); |
828 | if (err < 0) | 779 | if (err < 0) |
@@ -847,19 +798,6 @@ static int tegra_output_dsi_setup_clock(struct tegra_output *output, | |||
847 | */ | 798 | */ |
848 | plld /= 2; | 799 | plld /= 2; |
849 | 800 | ||
850 | err = clk_set_parent(clk, dsi->clk_parent); | ||
851 | if (err < 0) { | ||
852 | dev_err(dsi->dev, "failed to set parent clock: %d\n", err); | ||
853 | return err; | ||
854 | } | ||
855 | |||
856 | err = clk_set_rate(dsi->clk_parent, plld); | ||
857 | if (err < 0) { | ||
858 | dev_err(dsi->dev, "failed to set base clock rate to %lu Hz\n", | ||
859 | plld); | ||
860 | return err; | ||
861 | } | ||
862 | |||
863 | /* | 801 | /* |
864 | * Derive pixel clock from bit clock using the shift clock divider. | 802 | * Derive pixel clock from bit clock using the shift clock divider. |
865 | * Note that this is only half of what we would expect, but we need | 803 | * Note that this is only half of what we would expect, but we need |
@@ -870,39 +808,132 @@ static int tegra_output_dsi_setup_clock(struct tegra_output *output, | |||
870 | * not working properly otherwise. Perhaps the PLLs cannot generate | 808 | * not working properly otherwise. Perhaps the PLLs cannot generate |
871 | * frequencies sufficiently high. | 809 | * frequencies sufficiently high. |
872 | */ | 810 | */ |
873 | *divp = ((8 * mul) / (div * lanes)) - 2; | 811 | scdiv = ((8 * mul) / (div * lanes)) - 2; |
812 | |||
813 | err = tegra_dc_setup_clock(dc, dsi->clk_parent, plld, scdiv); | ||
814 | if (err < 0) { | ||
815 | dev_err(output->dev, "failed to setup DC clock: %d\n", err); | ||
816 | return false; | ||
817 | } | ||
818 | |||
819 | err = clk_set_rate(dsi->clk_parent, plld); | ||
820 | if (err < 0) { | ||
821 | dev_err(dsi->dev, "failed to set clock rate to %lu Hz\n", | ||
822 | plld); | ||
823 | return false; | ||
824 | } | ||
874 | 825 | ||
875 | /* | ||
876 | * XXX: Move the below somewhere else so that we don't need to have | ||
877 | * access to the vrefresh in this function? | ||
878 | */ | ||
879 | tegra_dsi_set_timeout(dsi, bclk, vrefresh); | 826 | tegra_dsi_set_timeout(dsi, bclk, vrefresh); |
880 | 827 | ||
881 | err = tegra_dsi_set_phy_timing(dsi); | 828 | err = tegra_dsi_set_phy_timing(dsi); |
882 | if (err < 0) | 829 | if (err < 0) { |
883 | return err; | 830 | dev_err(dsi->dev, "failed to setup D-PHY timing: %d\n", err); |
831 | return false; | ||
832 | } | ||
884 | 833 | ||
885 | return 0; | 834 | return true; |
835 | } | ||
836 | |||
837 | static void tegra_dsi_encoder_prepare(struct drm_encoder *encoder) | ||
838 | { | ||
839 | } | ||
840 | |||
841 | static void tegra_dsi_encoder_commit(struct drm_encoder *encoder) | ||
842 | { | ||
886 | } | 843 | } |
887 | 844 | ||
888 | static int tegra_output_dsi_check_mode(struct tegra_output *output, | 845 | static void tegra_dsi_encoder_mode_set(struct drm_encoder *encoder, |
889 | struct drm_display_mode *mode, | 846 | struct drm_display_mode *mode, |
890 | enum drm_mode_status *status) | 847 | struct drm_display_mode *adjusted) |
848 | { | ||
849 | struct tegra_output *output = encoder_to_output(encoder); | ||
850 | struct tegra_dc *dc = to_tegra_dc(encoder->crtc); | ||
851 | struct tegra_dsi *dsi = to_dsi(output); | ||
852 | u32 value; | ||
853 | int err; | ||
854 | |||
855 | |||
856 | err = tegra_dsi_configure(dsi, dc->pipe, mode); | ||
857 | if (err < 0) { | ||
858 | dev_err(dsi->dev, "failed to configure DSI: %d\n", err); | ||
859 | return; | ||
860 | } | ||
861 | |||
862 | if (output->panel) | ||
863 | drm_panel_prepare(output->panel); | ||
864 | |||
865 | /* enable display controller */ | ||
866 | value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); | ||
867 | value |= DSI_ENABLE; | ||
868 | tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); | ||
869 | |||
870 | value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND); | ||
871 | value &= ~DISP_CTRL_MODE_MASK; | ||
872 | value |= DISP_CTRL_MODE_C_DISPLAY; | ||
873 | tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND); | ||
874 | |||
875 | value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL); | ||
876 | value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | | ||
877 | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE; | ||
878 | tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL); | ||
879 | |||
880 | tegra_dc_commit(dc); | ||
881 | |||
882 | /* enable DSI controller */ | ||
883 | tegra_dsi_enable(dsi); | ||
884 | |||
885 | if (output->panel) | ||
886 | drm_panel_enable(output->panel); | ||
887 | |||
888 | return; | ||
889 | } | ||
890 | |||
891 | static void tegra_dsi_encoder_disable(struct drm_encoder *encoder) | ||
891 | { | 892 | { |
893 | struct tegra_output *output = encoder_to_output(encoder); | ||
894 | struct tegra_dc *dc = to_tegra_dc(encoder->crtc); | ||
895 | struct tegra_dsi *dsi = to_dsi(output); | ||
896 | u32 value; | ||
897 | int err; | ||
898 | |||
899 | if (output->panel) | ||
900 | drm_panel_disable(output->panel); | ||
901 | |||
902 | tegra_dsi_video_disable(dsi); | ||
903 | |||
892 | /* | 904 | /* |
893 | * FIXME: For now, always assume that the mode is okay. | 905 | * The following accesses registers of the display controller, so make |
906 | * sure it's only executed when the output is attached to one. | ||
894 | */ | 907 | */ |
908 | if (dc) { | ||
909 | value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); | ||
910 | value &= ~DSI_ENABLE; | ||
911 | tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); | ||
895 | 912 | ||
896 | *status = MODE_OK; | 913 | tegra_dc_commit(dc); |
914 | } | ||
897 | 915 | ||
898 | return 0; | 916 | err = tegra_dsi_wait_idle(dsi, 100); |
917 | if (err < 0) | ||
918 | dev_dbg(dsi->dev, "failed to idle DSI: %d\n", err); | ||
919 | |||
920 | tegra_dsi_soft_reset(dsi); | ||
921 | |||
922 | if (output->panel) | ||
923 | drm_panel_unprepare(output->panel); | ||
924 | |||
925 | tegra_dsi_disable(dsi); | ||
926 | |||
927 | return; | ||
899 | } | 928 | } |
900 | 929 | ||
901 | static const struct tegra_output_ops dsi_ops = { | 930 | static const struct drm_encoder_helper_funcs tegra_dsi_encoder_helper_funcs = { |
902 | .enable = tegra_output_dsi_enable, | 931 | .dpms = tegra_dsi_encoder_dpms, |
903 | .disable = tegra_output_dsi_disable, | 932 | .mode_fixup = tegra_dsi_encoder_mode_fixup, |
904 | .setup_clock = tegra_output_dsi_setup_clock, | 933 | .prepare = tegra_dsi_encoder_prepare, |
905 | .check_mode = tegra_output_dsi_check_mode, | 934 | .commit = tegra_dsi_encoder_commit, |
935 | .mode_set = tegra_dsi_encoder_mode_set, | ||
936 | .disable = tegra_dsi_encoder_disable, | ||
906 | }; | 937 | }; |
907 | 938 | ||
908 | static int tegra_dsi_pad_enable(struct tegra_dsi *dsi) | 939 | static int tegra_dsi_pad_enable(struct tegra_dsi *dsi) |
@@ -952,15 +983,30 @@ static int tegra_dsi_init(struct host1x_client *client) | |||
952 | 983 | ||
953 | /* Gangsters must not register their own outputs. */ | 984 | /* Gangsters must not register their own outputs. */ |
954 | if (!dsi->master) { | 985 | if (!dsi->master) { |
955 | dsi->output.type = TEGRA_OUTPUT_DSI; | ||
956 | dsi->output.dev = client->dev; | 986 | dsi->output.dev = client->dev; |
957 | dsi->output.ops = &dsi_ops; | ||
958 | 987 | ||
959 | err = tegra_output_init(drm, &dsi->output); | 988 | drm_connector_init(drm, &dsi->output.connector, |
960 | if (err < 0) { | 989 | &tegra_dsi_connector_funcs, |
961 | dev_err(client->dev, "output setup failed: %d\n", err); | 990 | DRM_MODE_CONNECTOR_DSI); |
962 | return err; | 991 | drm_connector_helper_add(&dsi->output.connector, |
963 | } | 992 | &tegra_dsi_connector_helper_funcs); |
993 | dsi->output.connector.dpms = DRM_MODE_DPMS_OFF; | ||
994 | |||
995 | if (dsi->output.panel) | ||
996 | drm_panel_attach(dsi->output.panel, | ||
997 | &dsi->output.connector); | ||
998 | |||
999 | drm_encoder_init(drm, &dsi->output.encoder, | ||
1000 | &tegra_dsi_encoder_funcs, | ||
1001 | DRM_MODE_ENCODER_DSI); | ||
1002 | drm_encoder_helper_add(&dsi->output.encoder, | ||
1003 | &tegra_dsi_encoder_helper_funcs); | ||
1004 | |||
1005 | drm_mode_connector_attach_encoder(&dsi->output.connector, | ||
1006 | &dsi->output.encoder); | ||
1007 | drm_connector_register(&dsi->output.connector); | ||
1008 | |||
1009 | dsi->output.encoder.possible_crtcs = 0x3; | ||
964 | } | 1010 | } |
965 | 1011 | ||
966 | if (IS_ENABLED(CONFIG_DEBUG_FS)) { | 1012 | if (IS_ENABLED(CONFIG_DEBUG_FS)) { |
@@ -981,28 +1027,14 @@ static int tegra_dsi_exit(struct host1x_client *client) | |||
981 | struct tegra_dsi *dsi = host1x_client_to_dsi(client); | 1027 | struct tegra_dsi *dsi = host1x_client_to_dsi(client); |
982 | int err; | 1028 | int err; |
983 | 1029 | ||
1030 | tegra_output_exit(&dsi->output); | ||
1031 | |||
984 | if (IS_ENABLED(CONFIG_DEBUG_FS)) { | 1032 | if (IS_ENABLED(CONFIG_DEBUG_FS)) { |
985 | err = tegra_dsi_debugfs_exit(dsi); | 1033 | err = tegra_dsi_debugfs_exit(dsi); |
986 | if (err < 0) | 1034 | if (err < 0) |
987 | dev_err(dsi->dev, "debugfs cleanup failed: %d\n", err); | 1035 | dev_err(dsi->dev, "debugfs cleanup failed: %d\n", err); |
988 | } | 1036 | } |
989 | 1037 | ||
990 | if (!dsi->master) { | ||
991 | err = tegra_output_disable(&dsi->output); | ||
992 | if (err < 0) { | ||
993 | dev_err(client->dev, "output failed to disable: %d\n", | ||
994 | err); | ||
995 | return err; | ||
996 | } | ||
997 | |||
998 | err = tegra_output_exit(&dsi->output); | ||
999 | if (err < 0) { | ||
1000 | dev_err(client->dev, "output cleanup failed: %d\n", | ||
1001 | err); | ||
1002 | return err; | ||
1003 | } | ||
1004 | } | ||
1005 | |||
1006 | reset_control_assert(dsi->rst); | 1038 | reset_control_assert(dsi->rst); |
1007 | 1039 | ||
1008 | return 0; | 1040 | return 0; |
@@ -1547,6 +1579,12 @@ static int tegra_dsi_remove(struct platform_device *pdev) | |||
1547 | return err; | 1579 | return err; |
1548 | } | 1580 | } |
1549 | 1581 | ||
1582 | err = tegra_output_remove(&dsi->output); | ||
1583 | if (err < 0) { | ||
1584 | dev_err(&pdev->dev, "failed to remove output: %d\n", err); | ||
1585 | return err; | ||
1586 | } | ||
1587 | |||
1550 | mipi_dsi_host_unregister(&dsi->host); | 1588 | mipi_dsi_host_unregister(&dsi->host); |
1551 | tegra_mipi_free(dsi->mipi); | 1589 | tegra_mipi_free(dsi->mipi); |
1552 | 1590 | ||
@@ -1555,12 +1593,6 @@ static int tegra_dsi_remove(struct platform_device *pdev) | |||
1555 | clk_disable_unprepare(dsi->clk); | 1593 | clk_disable_unprepare(dsi->clk); |
1556 | reset_control_assert(dsi->rst); | 1594 | reset_control_assert(dsi->rst); |
1557 | 1595 | ||
1558 | err = tegra_output_remove(&dsi->output); | ||
1559 | if (err < 0) { | ||
1560 | dev_err(&pdev->dev, "failed to remove output: %d\n", err); | ||
1561 | return err; | ||
1562 | } | ||
1563 | |||
1564 | return 0; | 1596 | return 0; |
1565 | } | 1597 | } |
1566 | 1598 | ||
diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index c7ebe8ea3868..81de885226ff 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c | |||
@@ -274,11 +274,6 @@ int tegra_output_init(struct drm_device *drm, struct tegra_output *output) | |||
274 | int connector, encoder; | 274 | int connector, encoder; |
275 | 275 | ||
276 | switch (output->type) { | 276 | switch (output->type) { |
277 | case TEGRA_OUTPUT_DSI: | ||
278 | connector = DRM_MODE_CONNECTOR_DSI; | ||
279 | encoder = DRM_MODE_ENCODER_DSI; | ||
280 | break; | ||
281 | |||
282 | case TEGRA_OUTPUT_EDP: | 277 | case TEGRA_OUTPUT_EDP: |
283 | connector = DRM_MODE_CONNECTOR_eDP; | 278 | connector = DRM_MODE_CONNECTOR_eDP; |
284 | encoder = DRM_MODE_ENCODER_TMDS; | 279 | encoder = DRM_MODE_ENCODER_TMDS; |