diff options
Diffstat (limited to 'drivers/gpu/drm/tegra/rgb.c')
-rw-r--r-- | drivers/gpu/drm/tegra/rgb.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c index 3b29018913a5..0266fb40479e 100644 --- a/drivers/gpu/drm/tegra/rgb.c +++ b/drivers/gpu/drm/tegra/rgb.c | |||
@@ -15,6 +15,7 @@ | |||
15 | struct tegra_rgb { | 15 | struct tegra_rgb { |
16 | struct tegra_output output; | 16 | struct tegra_output output; |
17 | struct tegra_dc *dc; | 17 | struct tegra_dc *dc; |
18 | bool enabled; | ||
18 | 19 | ||
19 | struct clk *clk_parent; | 20 | struct clk *clk_parent; |
20 | struct clk *clk; | 21 | struct clk *clk; |
@@ -87,18 +88,73 @@ static void tegra_dc_write_regs(struct tegra_dc *dc, | |||
87 | static int tegra_output_rgb_enable(struct tegra_output *output) | 88 | static int tegra_output_rgb_enable(struct tegra_output *output) |
88 | { | 89 | { |
89 | struct tegra_rgb *rgb = to_rgb(output); | 90 | struct tegra_rgb *rgb = to_rgb(output); |
91 | unsigned long value; | ||
92 | |||
93 | if (rgb->enabled) | ||
94 | return 0; | ||
90 | 95 | ||
91 | tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable)); | 96 | tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable)); |
92 | 97 | ||
98 | value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL; | ||
99 | tegra_dc_writel(rgb->dc, value, DC_DISP_DATA_ENABLE_OPTIONS); | ||
100 | |||
101 | /* XXX: parameterize? */ | ||
102 | value = tegra_dc_readl(rgb->dc, DC_COM_PIN_OUTPUT_POLARITY(1)); | ||
103 | value &= ~LVS_OUTPUT_POLARITY_LOW; | ||
104 | value &= ~LHS_OUTPUT_POLARITY_LOW; | ||
105 | tegra_dc_writel(rgb->dc, value, DC_COM_PIN_OUTPUT_POLARITY(1)); | ||
106 | |||
107 | /* XXX: parameterize? */ | ||
108 | value = DISP_DATA_FORMAT_DF1P1C | DISP_ALIGNMENT_MSB | | ||
109 | DISP_ORDER_RED_BLUE; | ||
110 | tegra_dc_writel(rgb->dc, value, DC_DISP_DISP_INTERFACE_CONTROL); | ||
111 | |||
112 | /* XXX: parameterize? */ | ||
113 | value = SC0_H_QUALIFIER_NONE | SC1_H_QUALIFIER_NONE; | ||
114 | tegra_dc_writel(rgb->dc, value, DC_DISP_SHIFT_CLOCK_OPTIONS); | ||
115 | |||
116 | value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_COMMAND); | ||
117 | value &= ~DISP_CTRL_MODE_MASK; | ||
118 | value |= DISP_CTRL_MODE_C_DISPLAY; | ||
119 | tegra_dc_writel(rgb->dc, value, DC_CMD_DISPLAY_COMMAND); | ||
120 | |||
121 | value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_POWER_CONTROL); | ||
122 | value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | | ||
123 | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE; | ||
124 | tegra_dc_writel(rgb->dc, value, DC_CMD_DISPLAY_POWER_CONTROL); | ||
125 | |||
126 | tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); | ||
127 | tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); | ||
128 | |||
129 | rgb->enabled = true; | ||
130 | |||
93 | return 0; | 131 | return 0; |
94 | } | 132 | } |
95 | 133 | ||
96 | static int tegra_output_rgb_disable(struct tegra_output *output) | 134 | static int tegra_output_rgb_disable(struct tegra_output *output) |
97 | { | 135 | { |
98 | struct tegra_rgb *rgb = to_rgb(output); | 136 | struct tegra_rgb *rgb = to_rgb(output); |
137 | unsigned long value; | ||
138 | |||
139 | if (!rgb->enabled) | ||
140 | return 0; | ||
141 | |||
142 | value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_POWER_CONTROL); | ||
143 | value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | | ||
144 | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE); | ||
145 | tegra_dc_writel(rgb->dc, value, DC_CMD_DISPLAY_POWER_CONTROL); | ||
146 | |||
147 | value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_COMMAND); | ||
148 | value &= ~DISP_CTRL_MODE_MASK; | ||
149 | tegra_dc_writel(rgb->dc, value, DC_CMD_DISPLAY_COMMAND); | ||
150 | |||
151 | tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); | ||
152 | tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); | ||
99 | 153 | ||
100 | tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable)); | 154 | tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable)); |
101 | 155 | ||
156 | rgb->enabled = false; | ||
157 | |||
102 | return 0; | 158 | return 0; |
103 | } | 159 | } |
104 | 160 | ||
@@ -213,7 +269,7 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc) | |||
213 | * RGB outputs are an exception, so we make sure they can be attached | 269 | * RGB outputs are an exception, so we make sure they can be attached |
214 | * to only their parent display controller. | 270 | * to only their parent display controller. |
215 | */ | 271 | */ |
216 | rgb->output.encoder.possible_crtcs = 1 << dc->pipe; | 272 | rgb->output.encoder.possible_crtcs = drm_crtc_mask(&dc->base); |
217 | 273 | ||
218 | return 0; | 274 | return 0; |
219 | } | 275 | } |