diff options
author | Pavan Kunapuli <pkunapuli@nvidia.com> | 2015-09-11 04:30:38 -0400 |
---|---|---|
committer | Anshuman Nath Kar <anshumank@nvidia.com> | 2015-10-26 18:28:44 -0400 |
commit | 79e4eddf1a62ac0c2a3dbee4e85ec7bfc8e50fe7 (patch) | |
tree | 7236168077ba83d0ab7d3daa9ee457deb0ad7f3d /drivers/video/tegra/dc/dsi.c | |
parent | 8db8d15ada9a3c4ac1e7616f35acd94214ed979e (diff) |
video: tegra: dc: Fix dc,dsi and mipical clocks for T18x
Change-Id: If12a79067fd1a052a72b52e645198b9f558aaab6
Signed-off-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Reviewed-on: http://git-master/r/797599
Reviewed-by: Gaurav Sarode <gsarode@nvidia.com>
Tested-by: Gaurav Sarode <gsarode@nvidia.com>
(cherry picked from commit 716fa4d64a8788299762246cfb336c954cf149d4)
Signed-off-by: Anshuman Nath Kar <anshumank@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/dc/dsi.c')
-rw-r--r-- | drivers/video/tegra/dc/dsi.c | 276 |
1 files changed, 236 insertions, 40 deletions
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c index 26330828e..9e5723c84 100644 --- a/drivers/video/tegra/dc/dsi.c +++ b/drivers/video/tegra/dc/dsi.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/tegra-soc.h> | 37 | #include <linux/tegra-soc.h> |
38 | #include <linux/nvhost.h> | 38 | #include <linux/nvhost.h> |
39 | #include <linux/of_address.h> | 39 | #include <linux/of_address.h> |
40 | #include <linux/io.h> | ||
40 | 41 | ||
41 | #include <mach/dc.h> | 42 | #include <mach/dc.h> |
42 | #include <mach/fb.h> | 43 | #include <mach/fb.h> |
@@ -60,6 +61,7 @@ | |||
60 | !defined(CONFIG_ARCH_TEGRA_3x_SOC) && \ | 61 | !defined(CONFIG_ARCH_TEGRA_3x_SOC) && \ |
61 | !defined(CONFIG_ARCH_TEGRA_11x_SOC) && \ | 62 | !defined(CONFIG_ARCH_TEGRA_11x_SOC) && \ |
62 | !defined(CONFIG_ARCH_TEGRA_14x_SOC) | 63 | !defined(CONFIG_ARCH_TEGRA_14x_SOC) |
64 | |||
63 | #define DSI_USE_SYNC_POINTS 1 | 65 | #define DSI_USE_SYNC_POINTS 1 |
64 | #else | 66 | #else |
65 | #define DSI_USE_SYNC_POINTS 0 | 67 | #define DSI_USE_SYNC_POINTS 0 |
@@ -440,14 +442,22 @@ inline void tegra_dsi_reset_deassert(struct tegra_dc_dsi_data *dsi) | |||
440 | { | 442 | { |
441 | int i = 0; | 443 | int i = 0; |
442 | for (i = 0; i < dsi->max_instances; i++) | 444 | for (i = 0; i < dsi->max_instances; i++) |
445 | #ifndef CONFIG_TEGRA_NVDISPLAY | ||
443 | tegra_periph_reset_deassert(dsi->dsi_clk[i]); | 446 | tegra_periph_reset_deassert(dsi->dsi_clk[i]); |
447 | #else | ||
448 | reset_control_deassert(dsi->dsi_reset[i]); | ||
449 | #endif | ||
444 | } | 450 | } |
445 | 451 | ||
446 | inline void tegra_dsi_reset_assert(struct tegra_dc_dsi_data *dsi) | 452 | inline void tegra_dsi_reset_assert(struct tegra_dc_dsi_data *dsi) |
447 | { | 453 | { |
448 | int i = 0; | 454 | int i = 0; |
449 | for (i = 0; i < dsi->max_instances; i++) | 455 | for (i = 0; i < dsi->max_instances; i++) |
456 | #ifndef CONFIG_TEGRA_NVDISPLAY | ||
450 | tegra_periph_reset_assert(dsi->dsi_clk[i]); | 457 | tegra_periph_reset_assert(dsi->dsi_clk[i]); |
458 | #else | ||
459 | reset_control_assert(dsi->dsi_reset[i]); | ||
460 | #endif | ||
451 | } | 461 | } |
452 | 462 | ||
453 | static inline void tegra_dsi_lp_clk_enable(struct tegra_dc_dsi_data *dsi); | 463 | static inline void tegra_dsi_lp_clk_enable(struct tegra_dc_dsi_data *dsi); |
@@ -456,8 +466,14 @@ static inline void tegra_dsi_lp_clk_disable(struct tegra_dc_dsi_data *dsi); | |||
456 | void tegra_dsi_clk_enable(struct tegra_dc_dsi_data *dsi) | 466 | void tegra_dsi_clk_enable(struct tegra_dc_dsi_data *dsi) |
457 | { | 467 | { |
458 | int i = 0; | 468 | int i = 0; |
469 | int err; | ||
470 | |||
459 | for (i = 0; i < dsi->max_instances; i++) { | 471 | for (i = 0; i < dsi->max_instances; i++) { |
460 | tegra_disp_clk_prepare_enable(dsi->dsi_clk[i]); | 472 | err = tegra_disp_clk_prepare_enable(dsi->dsi_clk[i]); |
473 | if (err) { | ||
474 | dev_err(&dsi->dc->ndev->dev, | ||
475 | "dsi%d clk enable failed. err %d\n", i, err); | ||
476 | } | ||
461 | udelay(800); | 477 | udelay(800); |
462 | } | 478 | } |
463 | } | 479 | } |
@@ -607,6 +623,17 @@ static struct tegra_dc_shift_clk_div tegra_dsi_get_shift_clk_div( | |||
607 | */ | 623 | */ |
608 | shift_clk_div = dsi->default_shift_clk_div; | 624 | shift_clk_div = dsi->default_shift_clk_div; |
609 | 625 | ||
626 | /* | ||
627 | * There is no shift clock divider in T18x. In order to maintain | ||
628 | * backward compatibility in the driver, just set the shift clock | ||
629 | * divisor and multiplier to 1. | ||
630 | */ | ||
631 | #if defined(CONFIG_ARCH_TEGRA_18x_SOC) | ||
632 | shift_clk_div.mul = 1; | ||
633 | shift_clk_div.div = 1; | ||
634 | return shift_clk_div; | ||
635 | #endif | ||
636 | |||
610 | /* Calculate shift_clk_div which can match the video_burst_mode. */ | 637 | /* Calculate shift_clk_div which can match the video_burst_mode. */ |
611 | if (dsi->info.video_burst_mode >= | 638 | if (dsi->info.video_burst_mode >= |
612 | TEGRA_DSI_VIDEO_BURST_MODE_LOWEST_SPEED) { | 639 | TEGRA_DSI_VIDEO_BURST_MODE_LOWEST_SPEED) { |
@@ -967,6 +994,15 @@ static void tegra_dsi_get_phy_timing(struct tegra_dc_dsi_data *dsi, | |||
967 | } | 994 | } |
968 | } | 995 | } |
969 | 996 | ||
997 | static inline int tegra_dsi_ignore_phy_timing_range_violation(void) | ||
998 | { | ||
999 | #if defined(CONFIG_ARCH_TEGRA_18x_SOC) | ||
1000 | return 1; | ||
1001 | #else | ||
1002 | return 0; | ||
1003 | #endif | ||
1004 | } | ||
1005 | |||
970 | static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | 1006 | static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, |
971 | struct dsi_phy_timing_inclk *phy_timing, | 1007 | struct dsi_phy_timing_inclk *phy_timing, |
972 | u32 clk_ps, u8 lphs) | 1008 | u32 clk_ps, u8 lphs) |
@@ -986,10 +1022,12 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
986 | DSI_CONVERT_T_PHY_TO_T_PHY_PS( | 1022 | DSI_CONVERT_T_PHY_TO_T_PHY_PS( |
987 | phy_timing->t_tlpx, clk_ps, T_TLPX_HW_INC), | 1023 | phy_timing->t_tlpx, clk_ps, T_TLPX_HW_INC), |
988 | MIPI_T_TLPX_PS_MIN, MIPI_T_TLPX_PS_MAX); | 1024 | MIPI_T_TLPX_PS_MIN, MIPI_T_TLPX_PS_MAX); |
1025 | |||
989 | if (err < 0) { | 1026 | if (err < 0) { |
990 | dev_warn(&dsi->dc->ndev->dev, | 1027 | dev_warn(&dsi->dc->ndev->dev, |
991 | "dsi: Tlpx mipi range violated\n"); | 1028 | "dsi: Tlpx mipi range violated\n"); |
992 | goto fail; | 1029 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1030 | goto fail; | ||
993 | } | 1031 | } |
994 | 1032 | ||
995 | if (lphs == DSI_LPHS_IN_HS_MODE) { | 1033 | if (lphs == DSI_LPHS_IN_HS_MODE) { |
@@ -997,10 +1035,12 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
997 | DSI_CONVERT_T_PHY_TO_T_PHY_PS( | 1035 | DSI_CONVERT_T_PHY_TO_T_PHY_PS( |
998 | phy_timing->t_hsdexit, clk_ps, T_HSEXIT_HW_INC), | 1036 | phy_timing->t_hsdexit, clk_ps, T_HSEXIT_HW_INC), |
999 | MIPI_T_HSEXIT_PS_MIN, MIPI_T_HSEXIT_PS_MAX); | 1037 | MIPI_T_HSEXIT_PS_MIN, MIPI_T_HSEXIT_PS_MAX); |
1038 | |||
1000 | if (err < 0) { | 1039 | if (err < 0) { |
1001 | dev_warn(&dsi->dc->ndev->dev, | 1040 | dev_warn(&dsi->dc->ndev->dev, |
1002 | "dsi: HsExit mipi range violated\n"); | 1041 | "dsi: HsExit mipi range violated\n"); |
1003 | goto fail; | 1042 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1043 | goto fail; | ||
1004 | } | 1044 | } |
1005 | 1045 | ||
1006 | err = CHECK_RANGE( | 1046 | err = CHECK_RANGE( |
@@ -1010,7 +1050,8 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
1010 | if (err < 0) { | 1050 | if (err < 0) { |
1011 | dev_warn(&dsi->dc->ndev->dev, | 1051 | dev_warn(&dsi->dc->ndev->dev, |
1012 | "dsi: HsTrail mipi range violated\n"); | 1052 | "dsi: HsTrail mipi range violated\n"); |
1013 | goto fail; | 1053 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1054 | goto fail; | ||
1014 | } | 1055 | } |
1015 | 1056 | ||
1016 | err = CHECK_RANGE( | 1057 | err = CHECK_RANGE( |
@@ -1020,7 +1061,8 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
1020 | if (err < 0) { | 1061 | if (err < 0) { |
1021 | dev_warn(&dsi->dc->ndev->dev, | 1062 | dev_warn(&dsi->dc->ndev->dev, |
1022 | "dsi: HsZero mipi range violated\n"); | 1063 | "dsi: HsZero mipi range violated\n"); |
1023 | goto fail; | 1064 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1065 | goto fail; | ||
1024 | } | 1066 | } |
1025 | 1067 | ||
1026 | err = CHECK_RANGE( | 1068 | err = CHECK_RANGE( |
@@ -1031,7 +1073,8 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
1031 | if (err < 0) { | 1073 | if (err < 0) { |
1032 | dev_warn(&dsi->dc->ndev->dev, | 1074 | dev_warn(&dsi->dc->ndev->dev, |
1033 | "dsi: HsPrepare mipi range violated\n"); | 1075 | "dsi: HsPrepare mipi range violated\n"); |
1034 | goto fail; | 1076 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1077 | goto fail; | ||
1035 | } | 1078 | } |
1036 | 1079 | ||
1037 | err = CHECK_RANGE( | 1080 | err = CHECK_RANGE( |
@@ -1044,7 +1087,8 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
1044 | if (err < 0) { | 1087 | if (err < 0) { |
1045 | dev_warn(&dsi->dc->ndev->dev, | 1088 | dev_warn(&dsi->dc->ndev->dev, |
1046 | "dsi: HsPrepare + HsZero mipi range violated\n"); | 1089 | "dsi: HsPrepare + HsZero mipi range violated\n"); |
1047 | goto fail; | 1090 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1091 | goto fail; | ||
1048 | } | 1092 | } |
1049 | } else { | 1093 | } else { |
1050 | /* default is LP mode */ | 1094 | /* default is LP mode */ |
@@ -1055,7 +1099,8 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
1055 | if (err < 0) { | 1099 | if (err < 0) { |
1056 | dev_warn(&dsi->dc->ndev->dev, | 1100 | dev_warn(&dsi->dc->ndev->dev, |
1057 | "dsi: WakeUp mipi range violated\n"); | 1101 | "dsi: WakeUp mipi range violated\n"); |
1058 | goto fail; | 1102 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1103 | goto fail; | ||
1059 | } | 1104 | } |
1060 | 1105 | ||
1061 | err = CHECK_RANGE( | 1106 | err = CHECK_RANGE( |
@@ -1068,7 +1113,8 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
1068 | if (err < 0) { | 1113 | if (err < 0) { |
1069 | dev_warn(&dsi->dc->ndev->dev, | 1114 | dev_warn(&dsi->dc->ndev->dev, |
1070 | "dsi: TaSure mipi range violated\n"); | 1115 | "dsi: TaSure mipi range violated\n"); |
1071 | goto fail; | 1116 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1117 | goto fail; | ||
1072 | } | 1118 | } |
1073 | } | 1119 | } |
1074 | 1120 | ||
@@ -1081,7 +1127,8 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
1081 | if (err < 0) { | 1127 | if (err < 0) { |
1082 | dev_warn(&dsi->dc->ndev->dev, | 1128 | dev_warn(&dsi->dc->ndev->dev, |
1083 | "dsi: ClkTrail mipi range violated\n"); | 1129 | "dsi: ClkTrail mipi range violated\n"); |
1084 | goto fail; | 1130 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1131 | goto fail; | ||
1085 | } | 1132 | } |
1086 | 1133 | ||
1087 | err = CHECK_RANGE( | 1134 | err = CHECK_RANGE( |
@@ -1091,7 +1138,8 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
1091 | if (err < 0) { | 1138 | if (err < 0) { |
1092 | dev_warn(&dsi->dc->ndev->dev, | 1139 | dev_warn(&dsi->dc->ndev->dev, |
1093 | "dsi: ClkPost mipi range violated\n"); | 1140 | "dsi: ClkPost mipi range violated\n"); |
1094 | goto fail; | 1141 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1142 | goto fail; | ||
1095 | } | 1143 | } |
1096 | 1144 | ||
1097 | err = CHECK_RANGE( | 1145 | err = CHECK_RANGE( |
@@ -1101,7 +1149,8 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
1101 | if (err < 0) { | 1149 | if (err < 0) { |
1102 | dev_warn(&dsi->dc->ndev->dev, | 1150 | dev_warn(&dsi->dc->ndev->dev, |
1103 | "dsi: ClkZero mipi range violated\n"); | 1151 | "dsi: ClkZero mipi range violated\n"); |
1104 | goto fail; | 1152 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1153 | goto fail; | ||
1105 | } | 1154 | } |
1106 | 1155 | ||
1107 | err = CHECK_RANGE( | 1156 | err = CHECK_RANGE( |
@@ -1111,7 +1160,8 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
1111 | if (err < 0) { | 1160 | if (err < 0) { |
1112 | dev_warn(&dsi->dc->ndev->dev, | 1161 | dev_warn(&dsi->dc->ndev->dev, |
1113 | "dsi: ClkPrepare mipi range violated\n"); | 1162 | "dsi: ClkPrepare mipi range violated\n"); |
1114 | goto fail; | 1163 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1164 | goto fail; | ||
1115 | } | 1165 | } |
1116 | 1166 | ||
1117 | err = CHECK_RANGE( | 1167 | err = CHECK_RANGE( |
@@ -1121,7 +1171,8 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
1121 | if (err < 0) { | 1171 | if (err < 0) { |
1122 | dev_warn(&dsi->dc->ndev->dev, | 1172 | dev_warn(&dsi->dc->ndev->dev, |
1123 | "dsi: ClkPre mipi range violated\n"); | 1173 | "dsi: ClkPre mipi range violated\n"); |
1124 | goto fail; | 1174 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1175 | goto fail; | ||
1125 | } | 1176 | } |
1126 | 1177 | ||
1127 | err = CHECK_RANGE( | 1178 | err = CHECK_RANGE( |
@@ -1134,7 +1185,8 @@ static int tegra_dsi_mipi_phy_timing_range(struct tegra_dc_dsi_data *dsi, | |||
1134 | if (err < 0) { | 1185 | if (err < 0) { |
1135 | dev_warn(&dsi->dc->ndev->dev, | 1186 | dev_warn(&dsi->dc->ndev->dev, |
1136 | "dsi: ClkPrepare + ClkZero mipi range violated\n"); | 1187 | "dsi: ClkPrepare + ClkZero mipi range violated\n"); |
1137 | goto fail; | 1188 | if (!tegra_dsi_ignore_phy_timing_range_violation()) |
1189 | goto fail; | ||
1138 | } | 1190 | } |
1139 | } | 1191 | } |
1140 | fail: | 1192 | fail: |
@@ -1278,6 +1330,7 @@ static void tegra_dsi_set_phy_timing(struct tegra_dc_dsi_data *dsi, u8 lphs) | |||
1278 | phy_timing.t_tasure += T_TASURE_HW_INC; | 1330 | phy_timing.t_tasure += T_TASURE_HW_INC; |
1279 | phy_timing.t_tago += T_TAGO_HW_INC; | 1331 | phy_timing.t_tago += T_TAGO_HW_INC; |
1280 | } | 1332 | } |
1333 | |||
1281 | val = DSI_PHY_TIMING_0_THSDEXIT(phy_timing.t_hsdexit) | | 1334 | val = DSI_PHY_TIMING_0_THSDEXIT(phy_timing.t_hsdexit) | |
1282 | DSI_PHY_TIMING_0_THSTRAIL(phy_timing.t_hstrail) | | 1335 | DSI_PHY_TIMING_0_THSTRAIL(phy_timing.t_hstrail) | |
1283 | DSI_PHY_TIMING_0_TDATZERO(phy_timing.t_datzero) | | 1336 | DSI_PHY_TIMING_0_TDATZERO(phy_timing.t_datzero) | |
@@ -1775,7 +1828,6 @@ static void tegra_dsi_soft_reset(struct tegra_dc_dsi_data *dsi) | |||
1775 | break; | 1828 | break; |
1776 | } | 1829 | } |
1777 | } | 1830 | } |
1778 | |||
1779 | tegra_dsi_writel(dsi, | 1831 | tegra_dsi_writel(dsi, |
1780 | DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE), | 1832 | DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE), |
1781 | DSI_POWER_CONTROL); | 1833 | DSI_POWER_CONTROL); |
@@ -1932,6 +1984,13 @@ static void tegra_dsi_set_dc_clk(struct tegra_dc *dc, | |||
1932 | u32 shift_clk_div_register; | 1984 | u32 shift_clk_div_register; |
1933 | u32 val; | 1985 | u32 val; |
1934 | 1986 | ||
1987 | /* | ||
1988 | * Shift clock divider is removed in T18x. There is no display | ||
1989 | * clock control register and not shift clk div programming. | ||
1990 | */ | ||
1991 | #if defined CONFIG_ARCH_TEGRA_18x_SOC | ||
1992 | return; | ||
1993 | #endif | ||
1935 | /* formula: (dsi->shift_clk_div - 1) * 2 */ | 1994 | /* formula: (dsi->shift_clk_div - 1) * 2 */ |
1936 | shift_clk_div_register = DIV_ROUND_CLOSEST( | 1995 | shift_clk_div_register = DIV_ROUND_CLOSEST( |
1937 | ((dsi->shift_clk_div.mul - | 1996 | ((dsi->shift_clk_div.mul - |
@@ -2000,8 +2059,13 @@ static void tegra_dsi_set_dsi_clk(struct tegra_dc *dc, | |||
2000 | 2059 | ||
2001 | dsi->current_dsi_clk_khz = | 2060 | dsi->current_dsi_clk_khz = |
2002 | clk_get_rate(dsi->dsi_clk[0]) / 1000; | 2061 | clk_get_rate(dsi->dsi_clk[0]) / 1000; |
2062 | #if defined(CONFIG_ARCH_TEGRA_18x_SOC) | ||
2063 | dsi->current_bit_clk_ps = DIV_ROUND_CLOSEST((1000 * 1000 * 1000), | ||
2064 | dsi->current_dsi_clk_khz); | ||
2065 | #else | ||
2003 | dsi->current_bit_clk_ps = DIV_ROUND_CLOSEST((1000 * 1000 * 1000), | 2066 | dsi->current_bit_clk_ps = DIV_ROUND_CLOSEST((1000 * 1000 * 1000), |
2004 | (dsi->current_dsi_clk_khz * 2)); | 2067 | (dsi->current_dsi_clk_khz * 2)); |
2068 | #endif | ||
2005 | } | 2069 | } |
2006 | 2070 | ||
2007 | static void tegra_dsi_hs_clk_out_enable(struct tegra_dc_dsi_data *dsi) | 2071 | static void tegra_dsi_hs_clk_out_enable(struct tegra_dc_dsi_data *dsi) |
@@ -2135,6 +2199,9 @@ static void tegra_dsi_pad_disable(struct tegra_dc_dsi_data *dsi) | |||
2135 | { | 2199 | { |
2136 | u32 val; | 2200 | u32 val; |
2137 | 2201 | ||
2202 | #if defined(CONFIG_ARCH_TEGRA_18x_SOC) | ||
2203 | return; | ||
2204 | #endif | ||
2138 | if (dsi->info.controller_vs == DSI_VS_1) { | 2205 | if (dsi->info.controller_vs == DSI_VS_1) { |
2139 | val = tegra_dsi_readl(dsi, DSI_PAD_CONTROL_0_VS1); | 2206 | val = tegra_dsi_readl(dsi, DSI_PAD_CONTROL_0_VS1); |
2140 | val &= ~(DSI_PAD_CONTROL_0_VS1_PAD_PDIO(0xf) | | 2207 | val &= ~(DSI_PAD_CONTROL_0_VS1_PAD_PDIO(0xf) | |
@@ -2164,6 +2231,9 @@ static void tegra_dsi_pad_enable(struct tegra_dc_dsi_data *dsi) | |||
2164 | { | 2231 | { |
2165 | u32 val; | 2232 | u32 val; |
2166 | 2233 | ||
2234 | #if defined(CONFIG_ARCH_TEGRA_18x_SOC) | ||
2235 | return; | ||
2236 | #endif | ||
2167 | if (dsi->info.controller_vs == DSI_VS_1) { | 2237 | if (dsi->info.controller_vs == DSI_VS_1) { |
2168 | val = tegra_dsi_readl(dsi, DSI_PAD_CONTROL_0_VS1); | 2238 | val = tegra_dsi_readl(dsi, DSI_PAD_CONTROL_0_VS1); |
2169 | val &= ~(DSI_PAD_CONTROL_0_VS1_PAD_PDIO(0xf) | | 2239 | val &= ~(DSI_PAD_CONTROL_0_VS1_PAD_PDIO(0xf) | |
@@ -2354,6 +2424,7 @@ void tegra_dsi_mipi_calibration_13x(struct tegra_dc_dsi_data *dsi) | |||
2354 | static void tegra_dsi_mipi_calibration_21x(struct tegra_dc_dsi_data *dsi) | 2424 | static void tegra_dsi_mipi_calibration_21x(struct tegra_dc_dsi_data *dsi) |
2355 | { | 2425 | { |
2356 | u32 val = 0; | 2426 | u32 val = 0; |
2427 | #if !defined(CONFIG_ARCH_TEGRA_18x_SOC) | ||
2357 | struct clk *clk72mhz = NULL; | 2428 | struct clk *clk72mhz = NULL; |
2358 | clk72mhz = clk_get_sys("clk72mhz", NULL); | 2429 | clk72mhz = clk_get_sys("clk72mhz", NULL); |
2359 | if (IS_ERR_OR_NULL(clk72mhz)) { | 2430 | if (IS_ERR_OR_NULL(clk72mhz)) { |
@@ -2361,7 +2432,7 @@ static void tegra_dsi_mipi_calibration_21x(struct tegra_dc_dsi_data *dsi) | |||
2361 | return; | 2432 | return; |
2362 | } | 2433 | } |
2363 | tegra_disp_clk_prepare_enable(clk72mhz); | 2434 | tegra_disp_clk_prepare_enable(clk72mhz); |
2364 | 2435 | #endif | |
2365 | /* Calibration settings begin */ | 2436 | /* Calibration settings begin */ |
2366 | val = tegra_mipi_cal_read(dsi->mipi_cal, | 2437 | val = tegra_mipi_cal_read(dsi->mipi_cal, |
2367 | MIPI_CAL_MIPI_BIAS_PAD_CFG2_0); | 2438 | MIPI_CAL_MIPI_BIAS_PAD_CFG2_0); |
@@ -2447,8 +2518,9 @@ static void tegra_dsi_mipi_calibration_21x(struct tegra_dc_dsi_data *dsi) | |||
2447 | 2518 | ||
2448 | tegra_dsi_mipi_calibration_status(dsi); | 2519 | tegra_dsi_mipi_calibration_status(dsi); |
2449 | } | 2520 | } |
2450 | 2521 | #if !defined(CONFIG_ARCH_TEGRA_18x_SOC) | |
2451 | tegra_disp_clk_disable_unprepare(clk72mhz); | 2522 | tegra_disp_clk_disable_unprepare(clk72mhz); |
2523 | #endif | ||
2452 | } | 2524 | } |
2453 | #endif | 2525 | #endif |
2454 | 2526 | ||
@@ -2773,7 +2845,8 @@ static void tegra_dsi_pad_calibration(struct tegra_dc_dsi_data *dsi) | |||
2773 | 2845 | ||
2774 | #if defined(CONFIG_ARCH_TEGRA_11x_SOC) || \ | 2846 | #if defined(CONFIG_ARCH_TEGRA_11x_SOC) || \ |
2775 | defined(CONFIG_ARCH_TEGRA_14x_SOC) || \ | 2847 | defined(CONFIG_ARCH_TEGRA_14x_SOC) || \ |
2776 | defined(CONFIG_ARCH_TEGRA_12x_SOC) | 2848 | defined(CONFIG_ARCH_TEGRA_12x_SOC) || \ |
2849 | defined(CONFIG_ARCH_TEGRA_18x_SOC) | ||
2777 | tegra_mipi_cal_write(dsi->mipi_cal, | 2850 | tegra_mipi_cal_write(dsi->mipi_cal, |
2778 | MIPI_BIAS_PAD_E_VCLAMP_REF(0x1), | 2851 | MIPI_BIAS_PAD_E_VCLAMP_REF(0x1), |
2779 | MIPI_CAL_MIPI_BIAS_PAD_CFG0_0); | 2852 | MIPI_CAL_MIPI_BIAS_PAD_CFG0_0); |
@@ -2800,7 +2873,11 @@ static void tegra_dsi_pad_calibration(struct tegra_dc_dsi_data *dsi) | |||
2800 | /* disable mipi bias pad */ | 2873 | /* disable mipi bias pad */ |
2801 | val = tegra_mipi_cal_read(dsi->mipi_cal, | 2874 | val = tegra_mipi_cal_read(dsi->mipi_cal, |
2802 | MIPI_CAL_MIPI_BIAS_PAD_CFG0_0); | 2875 | MIPI_CAL_MIPI_BIAS_PAD_CFG0_0); |
2803 | val |= MIPI_BIAS_PAD_PDVCLAMP(0x1); | 2876 | #ifdef CONFIG_TEGRA_NVDISPLAY |
2877 | val &= ~MIPI_BIAS_PAD_PDVCLAMP(0x1); | ||
2878 | #else | ||
2879 | val |= ~MIPI_BIAS_PAD_PDVCLAMP(0x1); | ||
2880 | #endif | ||
2804 | tegra_mipi_cal_write(dsi->mipi_cal, val, | 2881 | tegra_mipi_cal_write(dsi->mipi_cal, val, |
2805 | MIPI_CAL_MIPI_BIAS_PAD_CFG0_0); | 2882 | MIPI_CAL_MIPI_BIAS_PAD_CFG0_0); |
2806 | 2883 | ||
@@ -2841,7 +2918,7 @@ static void tegra_dsi_pad_calibration(struct tegra_dc_dsi_data *dsi) | |||
2841 | #endif | 2918 | #endif |
2842 | } | 2919 | } |
2843 | } | 2920 | } |
2844 | 2921 | #if !defined(CONFIG_ARCH_TEGRA_18x_SOC) | |
2845 | static void tegra_dsi_panelB_enable(void) | 2922 | static void tegra_dsi_panelB_enable(void) |
2846 | { | 2923 | { |
2847 | unsigned int val; | 2924 | unsigned int val; |
@@ -2850,7 +2927,7 @@ static void tegra_dsi_panelB_enable(void) | |||
2850 | val |= DSIB_MODE_ENABLE; | 2927 | val |= DSIB_MODE_ENABLE; |
2851 | writel(val, (IO_ADDRESS(APB_MISC_GP_MIPI_PAD_CTRL_0))); | 2928 | writel(val, (IO_ADDRESS(APB_MISC_GP_MIPI_PAD_CTRL_0))); |
2852 | } | 2929 | } |
2853 | 2930 | #endif | |
2854 | static int tegra_dsi_init_hw(struct tegra_dc *dc, | 2931 | static int tegra_dsi_init_hw(struct tegra_dc *dc, |
2855 | struct tegra_dc_dsi_data *dsi) | 2932 | struct tegra_dc_dsi_data *dsi) |
2856 | { | 2933 | { |
@@ -2867,6 +2944,9 @@ static int tegra_dsi_init_hw(struct tegra_dc *dc, | |||
2867 | tegra_dsi_clk_enable(dsi); | 2944 | tegra_dsi_clk_enable(dsi); |
2868 | tegra_dsi_set_dsi_clk(dc, dsi, dsi->target_lp_clk_khz); | 2945 | tegra_dsi_set_dsi_clk(dc, dsi, dsi->target_lp_clk_khz); |
2869 | 2946 | ||
2947 | #ifdef CONFIG_TEGRA_NVDISPLAY | ||
2948 | tegra_dsi_pad_calibration(dsi); | ||
2949 | #endif | ||
2870 | /* Stop DC stream before configuring DSI registers | 2950 | /* Stop DC stream before configuring DSI registers |
2871 | * to avoid visible glitches on panel during transition | 2951 | * to avoid visible glitches on panel during transition |
2872 | * from bootloader to kernel driver | 2952 | * from bootloader to kernel driver |
@@ -2878,10 +2958,10 @@ static int tegra_dsi_init_hw(struct tegra_dc *dc, | |||
2878 | DSI_POWER_CONTROL); | 2958 | DSI_POWER_CONTROL); |
2879 | /* stabilization delay */ | 2959 | /* stabilization delay */ |
2880 | udelay(300); | 2960 | udelay(300); |
2881 | 2961 | #if !defined(CONFIG_ARCH_TEGRA_18x_SOC) | |
2882 | if (dsi->info.dsi_instance || dsi->info.ganged_type) | 2962 | if (dsi->info.dsi_instance || dsi->info.ganged_type) |
2883 | tegra_dsi_panelB_enable(); | 2963 | tegra_dsi_panelB_enable(); |
2884 | 2964 | #endif | |
2885 | tegra_dsi_set_phy_timing(dsi, DSI_LPHS_IN_LP_MODE); | 2965 | tegra_dsi_set_phy_timing(dsi, DSI_LPHS_IN_LP_MODE); |
2886 | 2966 | ||
2887 | /* Initialize DSI registers */ | 2967 | /* Initialize DSI registers */ |
@@ -2902,7 +2982,9 @@ static int tegra_dsi_init_hw(struct tegra_dc *dc, | |||
2902 | } | 2982 | } |
2903 | #endif | 2983 | #endif |
2904 | 2984 | ||
2985 | #ifndef CONFIG_TEGRA_NVDISPLAY | ||
2905 | tegra_dsi_pad_calibration(dsi); | 2986 | tegra_dsi_pad_calibration(dsi); |
2987 | #endif | ||
2906 | 2988 | ||
2907 | tegra_dsi_writel(dsi, | 2989 | tegra_dsi_writel(dsi, |
2908 | DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_ENABLE), | 2990 | DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_ENABLE), |
@@ -4057,7 +4139,8 @@ int tegra_dsi_read_data(struct tegra_dc *dc, | |||
4057 | tegra_dc_dsi_hold_host(dc); | 4139 | tegra_dc_dsi_hold_host(dc); |
4058 | mutex_lock(&dsi->lock); | 4140 | mutex_lock(&dsi->lock); |
4059 | tegra_dc_io_start(dc); | 4141 | tegra_dc_io_start(dc); |
4060 | tegra_disp_clk_prepare_enable(dsi->dsi_fixed_clk); | 4142 | if (dsi->dsi_fixed_clk) |
4143 | tegra_disp_clk_prepare_enable(dsi->dsi_fixed_clk); | ||
4061 | tegra_dsi_lp_clk_enable(dsi); | 4144 | tegra_dsi_lp_clk_enable(dsi); |
4062 | init_status = tegra_dsi_prepare_host_transmission( | 4145 | init_status = tegra_dsi_prepare_host_transmission( |
4063 | dc, dsi, DSI_LP_OP_WRITE); | 4146 | dc, dsi, DSI_LP_OP_WRITE); |
@@ -4116,7 +4199,8 @@ fail: | |||
4116 | if (err < 0) | 4199 | if (err < 0) |
4117 | dev_err(&dc->ndev->dev, "Failed to restore prev state\n"); | 4200 | dev_err(&dc->ndev->dev, "Failed to restore prev state\n"); |
4118 | tegra_dsi_lp_clk_disable(dsi); | 4201 | tegra_dsi_lp_clk_disable(dsi); |
4119 | tegra_disp_clk_disable_unprepare(dsi->dsi_fixed_clk); | 4202 | if (dsi->dsi_fixed_clk) |
4203 | tegra_disp_clk_disable_unprepare(dsi->dsi_fixed_clk); | ||
4120 | tegra_dc_io_end(dc); | 4204 | tegra_dc_io_end(dc); |
4121 | mutex_unlock(&dsi->lock); | 4205 | mutex_unlock(&dsi->lock); |
4122 | tegra_dc_dsi_release_host(dc); | 4206 | tegra_dc_dsi_release_host(dc); |
@@ -4431,6 +4515,14 @@ static void tegra_dc_dsi_enable(struct tegra_dc *dc) | |||
4431 | goto fail; | 4515 | goto fail; |
4432 | } | 4516 | } |
4433 | 4517 | ||
4518 | #if defined(CONFIG_ARCH_TEGRA_18x_SOC) | ||
4519 | dsi->pad_ctrl = tegra_dsi_padctrl_init(dc); | ||
4520 | if (IS_ERR(dsi->pad_ctrl)) { | ||
4521 | dev_err(&dc->ndev->dev, "dsi: Padctrl init failed\n"); | ||
4522 | err = PTR_ERR(dsi->pad_ctrl); | ||
4523 | goto fail; | ||
4524 | } | ||
4525 | #endif | ||
4434 | /* Stop DC stream before configuring DSI registers | 4526 | /* Stop DC stream before configuring DSI registers |
4435 | * to avoid visible glitches on panel during transition | 4527 | * to avoid visible glitches on panel during transition |
4436 | * from bootloader to kernel driver | 4528 | * from bootloader to kernel driver |
@@ -4747,14 +4839,22 @@ static int _tegra_dc_dsi_init(struct tegra_dc *dc) | |||
4747 | struct clk *dsi_clk; | 4839 | struct clk *dsi_clk; |
4748 | struct clk *dsi_fixed_clk = NULL; | 4840 | struct clk *dsi_fixed_clk = NULL; |
4749 | struct clk *dsi_lp_clk = NULL; | 4841 | struct clk *dsi_lp_clk = NULL; |
4842 | struct reset_control *dsi_reset = NULL; | ||
4843 | |||
4750 | struct tegra_dsi_out *dsi_pdata = NULL; | 4844 | struct tegra_dsi_out *dsi_pdata = NULL; |
4751 | int err = 0, i; | 4845 | int err = 0, i; |
4752 | int dsi_instance; | 4846 | int dsi_instance; |
4753 | char *ganged_reg_name[2] = {"ganged_dsia_regs", "ganged_dsib_regs"}; | 4847 | char *ganged_reg_name[2] = {"ganged_dsia_regs", "ganged_dsib_regs"}; |
4754 | char *split_link_reg_name[4] = {"split_dsia_regs", "split_disb_regs", | 4848 | char *split_link_reg_name[4] = {"split_dsia_regs", "split_disb_regs", |
4755 | "split_dsic_regs", "split_dsid_regs"}; | 4849 | "split_dsic_regs", "split_dsid_regs"}; |
4850 | #ifdef CONFIG_TEGRA_NVDISPLAY | ||
4851 | char *dsi_clk_name[4] = {"dsi", "dsib", "dsic", "dsid"}; | ||
4852 | char *dsi_lp_clk_name[4] = {"dsia_lp", "dsib_lp", "dsic_lp", "dsid_lp"}; | ||
4853 | char *dsi_reset_name[4] = {"dsia", "dsib", "dsic", "dsid"}; | ||
4854 | #else | ||
4756 | char *dsi_clk_name[4] = {"dsia", "dsib", "dsic", "dsid"}; | 4855 | char *dsi_clk_name[4] = {"dsia", "dsib", "dsic", "dsid"}; |
4757 | char *dsi_lp_clk_name[4] = {"dsialp", "dsiblp", "dsiclp", "dsidlp"}; | 4856 | char *dsi_lp_clk_name[4] = {"dsialp", "dsiblp", "dsiclp", "dsidlp"}; |
4857 | #endif | ||
4758 | struct device_node *np = dc->ndev->dev.of_node; | 4858 | struct device_node *np = dc->ndev->dev.of_node; |
4759 | #ifdef CONFIG_OF | 4859 | #ifdef CONFIG_OF |
4760 | struct device_node *np_dsi = | 4860 | struct device_node *np_dsi = |
@@ -4824,6 +4924,19 @@ static int _tegra_dc_dsi_init(struct tegra_dc *dc) | |||
4824 | goto err_release_regs; | 4924 | goto err_release_regs; |
4825 | } | 4925 | } |
4826 | 4926 | ||
4927 | #ifdef CONFIG_TEGRA_NVDISPLAY | ||
4928 | dsi_clk = dsi_pdata->dsi_instance ? | ||
4929 | tegra_disp_of_clk_get_by_name(np_dsi, | ||
4930 | dsi_clk_name[DSI_INSTANCE_1]) : | ||
4931 | tegra_disp_of_clk_get_by_name(np_dsi, | ||
4932 | dsi_clk_name[i]); | ||
4933 | dsi_lp_clk = dsi_pdata->dsi_instance ? | ||
4934 | tegra_disp_of_clk_get_by_name(np_dsi, | ||
4935 | dsi_lp_clk_name[DSI_INSTANCE_1]) : | ||
4936 | tegra_disp_of_clk_get_by_name(np_dsi, | ||
4937 | dsi_lp_clk_name[i]); | ||
4938 | |||
4939 | #else | ||
4827 | dsi_clk = dsi_pdata->dsi_instance ? | 4940 | dsi_clk = dsi_pdata->dsi_instance ? |
4828 | clk_get(&dc->ndev->dev, | 4941 | clk_get(&dc->ndev->dev, |
4829 | dsi_clk_name[DSI_INSTANCE_1]) : | 4942 | dsi_clk_name[DSI_INSTANCE_1]) : |
@@ -4832,6 +4945,7 @@ static int _tegra_dc_dsi_init(struct tegra_dc *dc) | |||
4832 | clk_get(&dc->ndev->dev, | 4945 | clk_get(&dc->ndev->dev, |
4833 | dsi_lp_clk_name[DSI_INSTANCE_1]) : | 4946 | dsi_lp_clk_name[DSI_INSTANCE_1]) : |
4834 | clk_get(&dc->ndev->dev, dsi_lp_clk_name[i]); | 4947 | clk_get(&dc->ndev->dev, dsi_lp_clk_name[i]); |
4948 | #endif | ||
4835 | 4949 | ||
4836 | if (IS_ERR_OR_NULL(dsi_clk) || IS_ERR_OR_NULL(dsi_lp_clk)) { | 4950 | if (IS_ERR_OR_NULL(dsi_clk) || IS_ERR_OR_NULL(dsi_lp_clk)) { |
4837 | dev_err(&dc->ndev->dev, "dsi: can't get clock\n"); | 4951 | dev_err(&dc->ndev->dev, "dsi: can't get clock\n"); |
@@ -4839,10 +4953,24 @@ static int _tegra_dc_dsi_init(struct tegra_dc *dc) | |||
4839 | goto err_dsi_clk_put; | 4953 | goto err_dsi_clk_put; |
4840 | } | 4954 | } |
4841 | 4955 | ||
4956 | #ifdef CONFIG_TEGRA_NVDISPLAY | ||
4957 | if (tegra_bpmp_running()) { | ||
4958 | dsi_reset = of_reset_control_get(np_dsi, | ||
4959 | dsi_reset_name[i]); | ||
4960 | if (IS_ERR_OR_NULL(dsi_reset)) { | ||
4961 | dev_err(&dc->ndev->dev, | ||
4962 | "dsi: can't get reset control\n"); | ||
4963 | err = -EBUSY; | ||
4964 | goto err_dsi_clk_put; | ||
4965 | } | ||
4966 | reset_control_reset(dsi_reset); | ||
4967 | } | ||
4968 | #endif | ||
4842 | dsi->base[i] = base; | 4969 | dsi->base[i] = base; |
4843 | dsi->base_res[i] = base_res; | 4970 | dsi->base_res[i] = base_res; |
4844 | dsi->dsi_clk[i] = dsi_clk; | 4971 | dsi->dsi_clk[i] = dsi_clk; |
4845 | dsi->dsi_lp_clk[i] = dsi_lp_clk; | 4972 | dsi->dsi_lp_clk[i] = dsi_lp_clk; |
4973 | dsi->dsi_reset[i] = dsi_reset; | ||
4846 | } | 4974 | } |
4847 | 4975 | ||
4848 | /* Initialise pad registers needed for split link */ | 4976 | /* Initialise pad registers needed for split link */ |
@@ -4888,6 +5016,7 @@ static int _tegra_dc_dsi_init(struct tegra_dc *dc) | |||
4888 | dsi->pad_control_base_res = base_res; | 5016 | dsi->pad_control_base_res = base_res; |
4889 | } | 5017 | } |
4890 | 5018 | ||
5019 | #ifndef CONFIG_TEGRA_NVDISPLAY | ||
4891 | dsi_fixed_clk = clk_get(&dc->ndev->dev, "dsi-fixed"); | 5020 | dsi_fixed_clk = clk_get(&dc->ndev->dev, "dsi-fixed"); |
4892 | 5021 | ||
4893 | if (IS_ERR_OR_NULL(dsi_fixed_clk)) { | 5022 | if (IS_ERR_OR_NULL(dsi_fixed_clk)) { |
@@ -4895,8 +5024,19 @@ static int _tegra_dc_dsi_init(struct tegra_dc *dc) | |||
4895 | err = -EBUSY; | 5024 | err = -EBUSY; |
4896 | goto err_release_regs; | 5025 | goto err_release_regs; |
4897 | } | 5026 | } |
5027 | #else | ||
5028 | dsi_fixed_clk = tegra_disp_clk_get(&dc->ndev->dev, "pllp_display"); | ||
5029 | dsi_fixed_clk = NULL; | ||
5030 | #endif | ||
4898 | 5031 | ||
5032 | /* TO DO - check out which clock is needed here for T186 | ||
5033 | * Temporarily passing the nvdisplay head0 clock | ||
5034 | */ | ||
5035 | #ifdef CONFIG_TEGRA_NVDISPLAY | ||
5036 | dc_clk = tegra_disp_clk_get(&dc->ndev->dev, "nvdisplay_p0"); | ||
5037 | #else | ||
4899 | dc_clk = clk_get_sys(dev_name(&dc->ndev->dev), NULL); | 5038 | dc_clk = clk_get_sys(dev_name(&dc->ndev->dev), NULL); |
5039 | #endif | ||
4900 | if (IS_ERR_OR_NULL(dc_clk)) { | 5040 | if (IS_ERR_OR_NULL(dc_clk)) { |
4901 | dev_err(&dc->ndev->dev, "dsi: dc clock %s unavailable\n", | 5041 | dev_err(&dc->ndev->dev, "dsi: dc clock %s unavailable\n", |
4902 | dev_name(&dc->ndev->dev)); | 5042 | dev_name(&dc->ndev->dev)); |
@@ -5000,6 +5140,7 @@ static void _tegra_dc_dsi_destroy(struct tegra_dc *dc) | |||
5000 | static void tegra_dsi_config_phy_clk(struct tegra_dc_dsi_data *dsi, | 5140 | static void tegra_dsi_config_phy_clk(struct tegra_dc_dsi_data *dsi, |
5001 | u32 settings) | 5141 | u32 settings) |
5002 | { | 5142 | { |
5143 | #if !defined(CONFIG_ARCH_TEGRA_18x_SOC) | ||
5003 | struct clk *parent_clk = NULL; | 5144 | struct clk *parent_clk = NULL; |
5004 | struct clk *base_clk = NULL; | 5145 | struct clk *base_clk = NULL; |
5005 | int i = 0; | 5146 | int i = 0; |
@@ -5018,11 +5159,12 @@ static void tegra_dsi_config_phy_clk(struct tegra_dc_dsi_data *dsi, | |||
5018 | TEGRA_CLK_PLLD_DSI_OUT_ENB, | 5159 | TEGRA_CLK_PLLD_DSI_OUT_ENB, |
5019 | settings); | 5160 | settings); |
5020 | #else | 5161 | #else |
5021 | tegra_clk_cfg_ex(base_clk, | 5162 | tegra_clk_cfg_ex(base_clk ? base_clk : parent_clk, |
5022 | TEGRA_CLK_PLLD_DSI_OUT_ENB, | 5163 | TEGRA_CLK_PLLD_DSI_OUT_ENB, |
5023 | settings); | 5164 | settings); |
5024 | #endif | 5165 | #endif |
5025 | } | 5166 | } |
5167 | #endif | ||
5026 | } | 5168 | } |
5027 | 5169 | ||
5028 | static int tegra_dsi_te_on_off(struct tegra_dc_dsi_data *dsi, bool flag) | 5170 | static int tegra_dsi_te_on_off(struct tegra_dc_dsi_data *dsi, bool flag) |
@@ -5158,7 +5300,6 @@ static int _tegra_dsi_host_resume(struct tegra_dc *dc, | |||
5158 | } | 5300 | } |
5159 | 5301 | ||
5160 | tegra_dvfs_set_rate(dc->clk, dc->mode.pclk); | 5302 | tegra_dvfs_set_rate(dc->clk, dc->mode.pclk); |
5161 | |||
5162 | return 0; | 5303 | return 0; |
5163 | fail: | 5304 | fail: |
5164 | return err; | 5305 | return err; |
@@ -5492,13 +5633,23 @@ static int tegra_dc_dsi_init(struct tegra_dc *dc) | |||
5492 | } | 5633 | } |
5493 | 5634 | ||
5494 | dsi = tegra_dc_get_outdata(dc); | 5635 | dsi = tegra_dc_get_outdata(dc); |
5495 | 5636 | #ifdef CONFIG_TEGRA_NVDISPLAY | |
5496 | dsi->avdd_dsi_csi = regulator_get(&dc->ndev->dev, "avdd_dsi_csi"); | 5637 | if (tegra_bpmp_running()) { |
5497 | if (IS_ERR_OR_NULL(dsi->avdd_dsi_csi)) { | 5638 | #endif |
5498 | dev_err(&dc->ndev->dev, "dsi: avdd_dsi_csi reg get failed\n"); | 5639 | dsi->avdd_dsi_csi = regulator_get(&dc->ndev->dev, |
5499 | err = -ENODEV; | 5640 | "avdd_dsi_csi"); |
5500 | goto err_reg; | 5641 | if (IS_ERR_OR_NULL(dsi->avdd_dsi_csi)) { |
5642 | dev_err(&dc->ndev->dev, | ||
5643 | "dsi: avdd_dsi_csi reg get failed\n"); | ||
5644 | err = -ENODEV; | ||
5645 | dsi->avdd_dsi_csi = NULL; | ||
5646 | goto err_reg; | ||
5647 | } | ||
5648 | #ifdef CONFIG_TEGRA_NVDISPLAY | ||
5649 | } else { | ||
5650 | dsi->avdd_dsi_csi = NULL; | ||
5501 | } | 5651 | } |
5652 | #endif | ||
5502 | 5653 | ||
5503 | dsi->mipi_cal = tegra_mipi_cal_init_sw(dc); | 5654 | dsi->mipi_cal = tegra_mipi_cal_init_sw(dc); |
5504 | if (IS_ERR(dsi->mipi_cal)) { | 5655 | if (IS_ERR(dsi->mipi_cal)) { |
@@ -5528,6 +5679,9 @@ static void tegra_dc_dsi_destroy(struct tegra_dc *dc) | |||
5528 | 5679 | ||
5529 | avdd_dsi_csi = dsi->avdd_dsi_csi; | 5680 | avdd_dsi_csi = dsi->avdd_dsi_csi; |
5530 | 5681 | ||
5682 | #if defined(CONFIG_ARCH_TEGRA_18x_SOC) | ||
5683 | tegra_dsi_padctrl_shutdown(dc); | ||
5684 | #endif | ||
5531 | _tegra_dc_dsi_destroy(dc); | 5685 | _tegra_dc_dsi_destroy(dc); |
5532 | regulator_put(avdd_dsi_csi); | 5686 | regulator_put(avdd_dsi_csi); |
5533 | tegra_mipi_cal_destroy(dc); | 5687 | tegra_mipi_cal_destroy(dc); |
@@ -5536,21 +5690,54 @@ static void tegra_dc_dsi_destroy(struct tegra_dc *dc) | |||
5536 | static long tegra_dc_dsi_setup_clk(struct tegra_dc *dc, struct clk *clk) | 5690 | static long tegra_dc_dsi_setup_clk(struct tegra_dc *dc, struct clk *clk) |
5537 | { | 5691 | { |
5538 | unsigned long rate; | 5692 | unsigned long rate; |
5539 | struct clk *parent_clk; | 5693 | struct clk *parent_clk = NULL; |
5540 | struct clk *base_clk; | 5694 | struct clk *base_clk = NULL; |
5695 | bool shift_clk_div_avail = true; | ||
5541 | struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc); | 5696 | struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc); |
5697 | #if defined(CONFIG_ARCH_TEGRA_18x_SOC) | ||
5698 | u8 i; | ||
5699 | struct clk *hubparent_clk; | ||
5700 | |||
5701 | shift_clk_div_avail = false; | ||
5702 | |||
5703 | /* Enable the hubparent clock */ | ||
5704 | hubparent_clk = tegra_disp_clk_get(&dc->ndev->dev, | ||
5705 | "pllp_display"); | ||
5706 | tegra_disp_clk_prepare_enable(hubparent_clk); | ||
5707 | for (i = 0; i < dsi->max_instances; i++) | ||
5708 | tegra_disp_clk_prepare_enable(dsi->dsi_clk[i]); | ||
5542 | 5709 | ||
5543 | 5710 | #endif | |
5544 | /* divide by 1000 to avoid overflow */ | 5711 | /* divide by 1000 to avoid overflow */ |
5545 | dc->mode.pclk /= 1000; | 5712 | dc->mode.pclk /= 1000; |
5546 | rate = (dc->mode.pclk * dc->shift_clk_div.mul * 2) | 5713 | |
5547 | / dc->shift_clk_div.div; | 5714 | if (shift_clk_div_avail) |
5715 | rate = (dc->mode.pclk * dc->shift_clk_div.mul * 2) | ||
5716 | / dc->shift_clk_div.div; | ||
5717 | else | ||
5718 | rate = dc->mode.pclk; | ||
5719 | |||
5548 | rate *= 1000; | 5720 | rate *= 1000; |
5549 | dc->mode.pclk *= 1000; | 5721 | dc->mode.pclk *= 1000; |
5550 | 5722 | ||
5551 | if (dc->initialized) | 5723 | if (dc->initialized) |
5552 | goto skip_setup; | 5724 | goto skip_setup; |
5553 | 5725 | ||
5726 | #ifdef CONFIG_TEGRA_NVDISPLAY | ||
5727 | if (clk == dc->clk) { | ||
5728 | base_clk = tegra_disp_clk_get(&dc->ndev->dev, | ||
5729 | "pll_d"); | ||
5730 | } else { | ||
5731 | if (dc->pdata->default_out->dsi->dsi_instance) { | ||
5732 | parent_clk = tegra_disp_clk_get(&dc->ndev->dev, | ||
5733 | dc->out->parent_clk ? : "pll_d"); | ||
5734 | } else { | ||
5735 | parent_clk = tegra_disp_clk_get(&dc->ndev->dev, | ||
5736 | "pll_d_out1"); | ||
5737 | base_clk = clk_get_parent(parent_clk); | ||
5738 | } | ||
5739 | } | ||
5740 | #else | ||
5554 | if (clk == dc->clk) { | 5741 | if (clk == dc->clk) { |
5555 | parent_clk = clk_get_sys(NULL, | 5742 | parent_clk = clk_get_sys(NULL, |
5556 | dc->out->parent_clk ? : "pll_d_out0"); | 5743 | dc->out->parent_clk ? : "pll_d_out0"); |
@@ -5567,16 +5754,25 @@ static long tegra_dc_dsi_setup_clk(struct tegra_dc *dc, struct clk *clk) | |||
5567 | } | 5754 | } |
5568 | } | 5755 | } |
5569 | tegra_dsi_config_phy_clk(dsi, TEGRA_DSI_ENABLE); | 5756 | tegra_dsi_config_phy_clk(dsi, TEGRA_DSI_ENABLE); |
5757 | #endif | ||
5570 | 5758 | ||
5759 | /* Fix me: Revert bpmp check once bpmp FW is fixed */ | ||
5760 | #ifdef CONFIG_TEGRA_NVDISPLAY | ||
5761 | if (!tegra_bpmp_running() && base_clk && rate != clk_get_rate(base_clk)) | ||
5762 | #else | ||
5571 | if (rate != clk_get_rate(base_clk)) | 5763 | if (rate != clk_get_rate(base_clk)) |
5764 | #endif | ||
5572 | clk_set_rate(base_clk, rate); | 5765 | clk_set_rate(base_clk, rate); |
5573 | 5766 | ||
5767 | #ifdef CONFIG_TEGRA_NVDISPLAY | ||
5768 | if (parent_clk && (clk_get_parent(clk) != parent_clk)) | ||
5769 | #else | ||
5574 | if (clk_get_parent(clk) != parent_clk) | 5770 | if (clk_get_parent(clk) != parent_clk) |
5771 | #endif | ||
5575 | clk_set_parent(clk, parent_clk); | 5772 | clk_set_parent(clk, parent_clk); |
5576 | 5773 | ||
5577 | skip_setup: | 5774 | skip_setup: |
5578 | tegra_dvfs_set_rate(dc->clk, dc->mode.pclk); | 5775 | tegra_dvfs_set_rate(dc->clk, dc->mode.pclk); |
5579 | |||
5580 | return tegra_dc_pclk_round_rate(dc, dc->mode.pclk); | 5776 | return tegra_dc_pclk_round_rate(dc, dc->mode.pclk); |
5581 | } | 5777 | } |
5582 | 5778 | ||