aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2013-12-12 05:06:55 -0500
committerThierry Reding <treding@nvidia.com>2013-12-20 09:56:07 -0500
commit72d302861530bcdb780ea57ebfc3dff6ec4f802c (patch)
tree07651dcd966b1502a18c1944268b8d31a8abdb0e
parent8620fc629aeec02ac3b3735703940696386a3039 (diff)
drm/tegra: Relocate some output-specific code
Some of the code in the CRTC's mode setting code is specific to the RGB output or needs to be called slightly differently depending on the type of output. Push that code down into the output drivers. Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/drm/tegra/dc.c18
-rw-r--r--drivers/gpu/drm/tegra/dc.h2
-rw-r--r--drivers/gpu/drm/tegra/dsi.c22
-rw-r--r--drivers/gpu/drm/tegra/hdmi.c45
-rw-r--r--drivers/gpu/drm/tegra/rgb.c45
5 files changed, 97 insertions, 35 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index f89445d3cab7..386f3b4b0094 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -669,20 +669,6 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc,
669 tegra_dc_writel(dc, value, DC_DISP_INTERLACE_CONTROL); 669 tegra_dc_writel(dc, value, DC_DISP_INTERLACE_CONTROL);
670 } 670 }
671 671
672 value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL;
673 tegra_dc_writel(dc, value, DC_DISP_DATA_ENABLE_OPTIONS);
674
675 value = tegra_dc_readl(dc, DC_COM_PIN_OUTPUT_POLARITY(1));
676 value &= ~LVS_OUTPUT_POLARITY_LOW;
677 value &= ~LHS_OUTPUT_POLARITY_LOW;
678 tegra_dc_writel(dc, value, DC_COM_PIN_OUTPUT_POLARITY(1));
679
680 value = DISP_DATA_FORMAT_DF1P1C | DISP_ALIGNMENT_MSB |
681 DISP_ORDER_RED_BLUE;
682 tegra_dc_writel(dc, value, DC_DISP_DISP_INTERFACE_CONTROL);
683
684 tegra_dc_writel(dc, 0x00010001, DC_DISP_SHIFT_CLOCK_OPTIONS);
685
686 value = SHIFT_CLK_DIVIDER(div) | PIXEL_CLK_DIVIDER_PCD1; 672 value = SHIFT_CLK_DIVIDER(div) | PIXEL_CLK_DIVIDER_PCD1;
687 tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL); 673 tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL);
688 674
@@ -746,10 +732,6 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc)
746 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE; 732 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
747 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL); 733 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
748 734
749 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
750 value |= DISP_CTRL_MODE_C_DISPLAY;
751 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
752
753 /* initialize timer */ 735 /* initialize timer */
754 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) | 736 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) |
755 WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20); 737 WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20);
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index e6a9df0abe68..3c2c0ea1cd87 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -240,6 +240,8 @@
240#define DITHER_CONTROL_ERRDIFF (3 << 8) 240#define DITHER_CONTROL_ERRDIFF (3 << 8)
241 241
242#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431 242#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
243#define SC1_H_QUALIFIER_NONE (1 << 16)
244#define SC0_H_QUALIFIER_NONE (1 << 0)
243 245
244#define DC_DISP_DATA_ENABLE_OPTIONS 0x432 246#define DC_DISP_DATA_ENABLE_OPTIONS 0x432
245#define DE_SELECT_ACTIVE_BLANK (0 << 0) 247#define DE_SELECT_ACTIVE_BLANK (0 << 0)
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index 844818f3e2d5..d452faab0235 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -450,15 +450,16 @@ static int tegra_output_dsi_enable(struct tegra_output *output)
450 value |= DSI_ENABLE; 450 value |= DSI_ENABLE;
451 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); 451 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
452 452
453 value = PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
454 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
455 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
456
457 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND); 453 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
458 value &= ~DISP_CTRL_MODE_MASK; 454 value &= ~DISP_CTRL_MODE_MASK;
459 value |= DISP_CTRL_MODE_C_DISPLAY; 455 value |= DISP_CTRL_MODE_C_DISPLAY;
460 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND); 456 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
461 457
458 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
459 value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
460 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
461 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
462
462 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); 463 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
463 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); 464 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
464 465
@@ -482,11 +483,15 @@ static int tegra_output_dsi_disable(struct tegra_output *output)
482 tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL); 483 tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL);
483 484
484 /* 485 /*
485 * FIXME: The output isn't attached to any CRTC when it's being 486 * The following accesses registers of the display controller, so make
486 * disabled, so the following will never be executed. 487 * sure it's only executed when the output is attached to one.
487 */ 488 */
488 if (dc) { 489 if (dc) {
489 /* disable display controller */ 490 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
491 value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
492 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE);
493 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
494
490 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND); 495 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
491 value &= ~DISP_CTRL_MODE_MASK; 496 value &= ~DISP_CTRL_MODE_MASK;
492 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND); 497 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
@@ -494,6 +499,9 @@ static int tegra_output_dsi_disable(struct tegra_output *output)
494 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); 499 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
495 value &= ~DSI_ENABLE; 500 value &= ~DSI_ENABLE;
496 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); 501 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
502
503 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
504 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
497 } 505 }
498 506
499 clk_disable(dsi->clk); 507 clk_disable(dsi->clk);
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index 19ce750e4856..bc9cb1ac709b 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -843,10 +843,6 @@ static int tegra_output_hdmi_enable(struct tegra_output *output)
843 value |= SOR_CSTM_ROTCLK(2); 843 value |= SOR_CSTM_ROTCLK(2);
844 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_CSTM); 844 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_CSTM);
845 845
846 tegra_dc_writel(dc, DISP_CTRL_MODE_STOP, DC_CMD_DISPLAY_COMMAND);
847 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
848 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
849
850 /* start SOR */ 846 /* start SOR */
851 tegra_hdmi_writel(hdmi, 847 tegra_hdmi_writel(hdmi,
852 SOR_PWR_NORMAL_STATE_PU | 848 SOR_PWR_NORMAL_STATE_PU |
@@ -896,15 +892,20 @@ static int tegra_output_hdmi_enable(struct tegra_output *output)
896 HDMI_NV_PDISP_SOR_STATE1); 892 HDMI_NV_PDISP_SOR_STATE1);
897 tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_SOR_STATE0); 893 tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_SOR_STATE0);
898 894
899 tegra_dc_writel(dc, HDMI_ENABLE, DC_DISP_DISP_WIN_OPTIONS); 895 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
896 value |= HDMI_ENABLE;
897 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
900 898
901 value = PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | 899 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
902 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE; 900 value &= ~DISP_CTRL_MODE_MASK;
903 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL); 901 value |= DISP_CTRL_MODE_C_DISPLAY;
904
905 value = DISP_CTRL_MODE_C_DISPLAY;
906 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND); 902 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
907 903
904 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
905 value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
906 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
907 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
908
908 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); 909 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
909 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); 910 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
910 911
@@ -917,11 +918,35 @@ static int tegra_output_hdmi_enable(struct tegra_output *output)
917 918
918static int tegra_output_hdmi_disable(struct tegra_output *output) 919static int tegra_output_hdmi_disable(struct tegra_output *output)
919{ 920{
921 struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
920 struct tegra_hdmi *hdmi = to_hdmi(output); 922 struct tegra_hdmi *hdmi = to_hdmi(output);
923 unsigned long value;
921 924
922 if (!hdmi->enabled) 925 if (!hdmi->enabled)
923 return 0; 926 return 0;
924 927
928 /*
929 * The following accesses registers of the display controller, so make
930 * sure it's only executed when the output is attached to one.
931 */
932 if (dc) {
933 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
934 value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
935 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE);
936 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
937
938 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
939 value &= ~DISP_CTRL_MODE_MASK;
940 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
941
942 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
943 value &= ~HDMI_ENABLE;
944 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
945
946 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
947 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
948 }
949
925 reset_control_assert(hdmi->rst); 950 reset_control_assert(hdmi->rst);
926 clk_disable(hdmi->clk); 951 clk_disable(hdmi->clk);
927 regulator_disable(hdmi->pll); 952 regulator_disable(hdmi->pll);
diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
index 3b29018913a5..03885bb8dcc0 100644
--- a/drivers/gpu/drm/tegra/rgb.c
+++ b/drivers/gpu/drm/tegra/rgb.c
@@ -87,15 +87,60 @@ static void tegra_dc_write_regs(struct tegra_dc *dc,
87static int tegra_output_rgb_enable(struct tegra_output *output) 87static int tegra_output_rgb_enable(struct tegra_output *output)
88{ 88{
89 struct tegra_rgb *rgb = to_rgb(output); 89 struct tegra_rgb *rgb = to_rgb(output);
90 unsigned long value;
90 91
91 tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable)); 92 tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable));
92 93
94 value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL;
95 tegra_dc_writel(rgb->dc, value, DC_DISP_DATA_ENABLE_OPTIONS);
96
97 /* XXX: parameterize? */
98 value = tegra_dc_readl(rgb->dc, DC_COM_PIN_OUTPUT_POLARITY(1));
99 value &= ~LVS_OUTPUT_POLARITY_LOW;
100 value &= ~LHS_OUTPUT_POLARITY_LOW;
101 tegra_dc_writel(rgb->dc, value, DC_COM_PIN_OUTPUT_POLARITY(1));
102
103 /* XXX: parameterize? */
104 value = DISP_DATA_FORMAT_DF1P1C | DISP_ALIGNMENT_MSB |
105 DISP_ORDER_RED_BLUE;
106 tegra_dc_writel(rgb->dc, value, DC_DISP_DISP_INTERFACE_CONTROL);
107
108 /* XXX: parameterize? */
109 value = SC0_H_QUALIFIER_NONE | SC1_H_QUALIFIER_NONE;
110 tegra_dc_writel(rgb->dc, value, DC_DISP_SHIFT_CLOCK_OPTIONS);
111
112 value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_COMMAND);
113 value &= ~DISP_CTRL_MODE_MASK;
114 value |= DISP_CTRL_MODE_C_DISPLAY;
115 tegra_dc_writel(rgb->dc, value, DC_CMD_DISPLAY_COMMAND);
116
117 value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_POWER_CONTROL);
118 value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
119 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
120 tegra_dc_writel(rgb->dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
121
122 tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
123 tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
124
93 return 0; 125 return 0;
94} 126}
95 127
96static int tegra_output_rgb_disable(struct tegra_output *output) 128static int tegra_output_rgb_disable(struct tegra_output *output)
97{ 129{
98 struct tegra_rgb *rgb = to_rgb(output); 130 struct tegra_rgb *rgb = to_rgb(output);
131 unsigned long value;
132
133 value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_POWER_CONTROL);
134 value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
135 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE);
136 tegra_dc_writel(rgb->dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
137
138 value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_COMMAND);
139 value &= ~DISP_CTRL_MODE_MASK;
140 tegra_dc_writel(rgb->dc, value, DC_CMD_DISPLAY_COMMAND);
141
142 tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
143 tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
99 144
100 tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable)); 145 tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable));
101 146