File: | dev/pci/drm/radeon/radeon_legacy_encoders.c |
Warning: | line 1823, column 1 Potential leak of memory pointed to by 'radeon_encoder' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * Copyright 2007-8 Advanced Micro Devices, Inc. | |||
3 | * Copyright 2008 Red Hat Inc. | |||
4 | * | |||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | |||
6 | * copy of this software and associated documentation files (the "Software"), | |||
7 | * to deal in the Software without restriction, including without limitation | |||
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
9 | * and/or sell copies of the Software, and to permit persons to whom the | |||
10 | * Software is furnished to do so, subject to the following conditions: | |||
11 | * | |||
12 | * The above copyright notice and this permission notice shall be included in | |||
13 | * all copies or substantial portions of the Software. | |||
14 | * | |||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
18 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |||
19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |||
21 | * OTHER DEALINGS IN THE SOFTWARE. | |||
22 | * | |||
23 | * Authors: Dave Airlie | |||
24 | * Alex Deucher | |||
25 | */ | |||
26 | ||||
27 | #include <linux/backlight.h> | |||
28 | #include <linux/pci.h> | |||
29 | ||||
30 | #include <drm/drm_crtc_helper.h> | |||
31 | #include <drm/drm_device.h> | |||
32 | #include <drm/drm_file.h> | |||
33 | #include <drm/drm_util.h> | |||
34 | #include <drm/radeon_drm.h> | |||
35 | ||||
36 | #include "radeon.h" | |||
37 | #include "radeon_asic.h" | |||
38 | #include "atom.h" | |||
39 | #ifdef CONFIG_PMAC_BACKLIGHT | |||
40 | #include <asm/backlight.h> | |||
41 | #endif | |||
42 | ||||
43 | static void radeon_legacy_encoder_disable(struct drm_encoder *encoder) | |||
44 | { | |||
45 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
46 | const struct drm_encoder_helper_funcs *encoder_funcs; | |||
47 | ||||
48 | encoder_funcs = encoder->helper_private; | |||
49 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF3); | |||
50 | radeon_encoder->active_device = 0; | |||
51 | } | |||
52 | ||||
53 | static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) | |||
54 | { | |||
55 | struct drm_device *dev = encoder->dev; | |||
56 | struct radeon_device *rdev = dev->dev_private; | |||
57 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
58 | uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man; | |||
59 | int panel_pwr_delay = 2000; | |||
60 | bool_Bool is_mac = false0; | |||
61 | uint8_t backlight_level; | |||
62 | DRM_DEBUG_KMS("\n")__drm_dbg(DRM_UT_KMS, "\n"); | |||
63 | ||||
64 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL)r100_mm_rreg(rdev, (0x02d0), 0); | |||
65 | backlight_level = (lvds_gen_cntl >> RADEON_LVDS_BL_MOD_LEVEL_SHIFT8) & 0xff; | |||
66 | ||||
67 | if (radeon_encoder->enc_priv) { | |||
68 | if (rdev->is_atom_bios) { | |||
69 | struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; | |||
70 | panel_pwr_delay = lvds->panel_pwr_delay; | |||
71 | if (lvds->bl_dev) | |||
72 | backlight_level = lvds->backlight_level; | |||
73 | } else { | |||
74 | struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; | |||
75 | panel_pwr_delay = lvds->panel_pwr_delay; | |||
76 | if (lvds->bl_dev) | |||
77 | backlight_level = lvds->backlight_level; | |||
78 | } | |||
79 | } | |||
80 | ||||
81 | /* macs (and possibly some x86 oem systems?) wire up LVDS strangely | |||
82 | * Taken from radeonfb. | |||
83 | */ | |||
84 | if ((rdev->mode_info.connector_table == CT_IBOOK) || | |||
85 | (rdev->mode_info.connector_table == CT_POWERBOOK_EXTERNAL) || | |||
86 | (rdev->mode_info.connector_table == CT_POWERBOOK_INTERNAL) || | |||
87 | (rdev->mode_info.connector_table == CT_POWERBOOK_VGA)) | |||
88 | is_mac = true1; | |||
89 | ||||
90 | switch (mode) { | |||
91 | case DRM_MODE_DPMS_ON0: | |||
92 | disp_pwr_man = RREG32(RADEON_DISP_PWR_MAN)r100_mm_rreg(rdev, (0x0d08), 0); | |||
93 | disp_pwr_man |= RADEON_AUTO_PWRUP_EN(1 << 26); | |||
94 | WREG32(RADEON_DISP_PWR_MAN, disp_pwr_man)r100_mm_wreg(rdev, (0x0d08), (disp_pwr_man), 0); | |||
95 | lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL)r100_mm_rreg(rdev, (0x02d4), 0); | |||
96 | lvds_pll_cntl |= RADEON_LVDS_PLL_EN(1 << 16); | |||
97 | WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl)r100_mm_wreg(rdev, (0x02d4), (lvds_pll_cntl), 0); | |||
98 | mdelay(1); | |||
99 | ||||
100 | lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL)r100_mm_rreg(rdev, (0x02d4), 0); | |||
101 | lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET(1 << 17); | |||
102 | WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl)r100_mm_wreg(rdev, (0x02d4), (lvds_pll_cntl), 0); | |||
103 | ||||
104 | lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS(1 << 1) | | |||
105 | RADEON_LVDS_BL_MOD_LEVEL_MASK(0xff << 8)); | |||
106 | lvds_gen_cntl |= (RADEON_LVDS_ON(1 << 0) | RADEON_LVDS_EN(1 << 7) | | |||
107 | RADEON_LVDS_DIGON(1 << 18) | RADEON_LVDS_BLON(1 << 19) | | |||
108 | (backlight_level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT8)); | |||
109 | if (is_mac) | |||
110 | lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN(1 << 16); | |||
111 | mdelay(panel_pwr_delay); | |||
112 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl)r100_mm_wreg(rdev, (0x02d0), (lvds_gen_cntl), 0); | |||
113 | break; | |||
114 | case DRM_MODE_DPMS_STANDBY1: | |||
115 | case DRM_MODE_DPMS_SUSPEND2: | |||
116 | case DRM_MODE_DPMS_OFF3: | |||
117 | pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL)rdev->pll_rreg(rdev, (0x002d)); | |||
118 | WREG32_PLL_P(RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb)do { uint32_t tmp_ = rdev->pll_rreg(rdev, (0x002d)); tmp_ &= (~(1 << 14)); tmp_ |= ((0) & ~(~(1 << 14))); rdev->pll_wreg(rdev, (0x002d), (tmp_)); } while (0); | |||
119 | lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS(1 << 1); | |||
120 | if (is_mac) { | |||
121 | lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_EN(1 << 16); | |||
122 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl)r100_mm_wreg(rdev, (0x02d0), (lvds_gen_cntl), 0); | |||
123 | lvds_gen_cntl &= ~(RADEON_LVDS_ON(1 << 0) | RADEON_LVDS_EN(1 << 7)); | |||
124 | } else { | |||
125 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl)r100_mm_wreg(rdev, (0x02d0), (lvds_gen_cntl), 0); | |||
126 | lvds_gen_cntl &= ~(RADEON_LVDS_ON(1 << 0) | RADEON_LVDS_BLON(1 << 19) | RADEON_LVDS_EN(1 << 7) | RADEON_LVDS_DIGON(1 << 18)); | |||
127 | } | |||
128 | mdelay(panel_pwr_delay); | |||
129 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl)r100_mm_wreg(rdev, (0x02d0), (lvds_gen_cntl), 0); | |||
130 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl)rdev->pll_wreg(rdev, (0x002d), (pixclks_cntl)); | |||
131 | mdelay(panel_pwr_delay); | |||
132 | break; | |||
133 | } | |||
134 | ||||
135 | if (rdev->is_atom_bios) | |||
136 | radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON0) ? true1 : false0); | |||
137 | else | |||
138 | radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON0) ? true1 : false0); | |||
139 | ||||
140 | } | |||
141 | ||||
142 | static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
143 | { | |||
144 | struct radeon_device *rdev = encoder->dev->dev_private; | |||
145 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
146 | DRM_DEBUG("\n")__drm_dbg(DRM_UT_CORE, "\n"); | |||
147 | ||||
148 | if (radeon_encoder->enc_priv) { | |||
149 | if (rdev->is_atom_bios) { | |||
150 | struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; | |||
151 | lvds->dpms_mode = mode; | |||
152 | } else { | |||
153 | struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; | |||
154 | lvds->dpms_mode = mode; | |||
155 | } | |||
156 | } | |||
157 | ||||
158 | radeon_legacy_lvds_update(encoder, mode); | |||
159 | } | |||
160 | ||||
161 | static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder) | |||
162 | { | |||
163 | struct radeon_device *rdev = encoder->dev->dev_private; | |||
164 | ||||
165 | if (rdev->is_atom_bios) | |||
166 | radeon_atom_output_lock(encoder, true1); | |||
167 | else | |||
168 | radeon_combios_output_lock(encoder, true1); | |||
169 | radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF3); | |||
170 | } | |||
171 | ||||
172 | static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) | |||
173 | { | |||
174 | struct radeon_device *rdev = encoder->dev->dev_private; | |||
175 | ||||
176 | radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_ON0); | |||
177 | if (rdev->is_atom_bios) | |||
178 | radeon_atom_output_lock(encoder, false0); | |||
179 | else | |||
180 | radeon_combios_output_lock(encoder, false0); | |||
181 | } | |||
182 | ||||
183 | static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, | |||
184 | struct drm_display_mode *mode, | |||
185 | struct drm_display_mode *adjusted_mode) | |||
186 | { | |||
187 | struct drm_device *dev = encoder->dev; | |||
188 | struct radeon_device *rdev = dev->dev_private; | |||
189 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc)({ const __typeof( ((struct radeon_crtc *)0)->base ) *__mptr = (encoder->crtc); (struct radeon_crtc *)( (char *)__mptr - __builtin_offsetof(struct radeon_crtc, base) );}); | |||
190 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
191 | uint32_t lvds_pll_cntl, lvds_gen_cntl, lvds_ss_gen_cntl; | |||
192 | ||||
193 | DRM_DEBUG_KMS("\n")__drm_dbg(DRM_UT_KMS, "\n"); | |||
194 | ||||
195 | lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL)r100_mm_rreg(rdev, (0x02d4), 0); | |||
196 | lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN(1 << 16); | |||
197 | ||||
198 | lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL)r100_mm_rreg(rdev, (0x02ec), 0); | |||
199 | if (rdev->is_atom_bios) { | |||
200 | /* LVDS_GEN_CNTL parameters are computed in LVDSEncoderControl | |||
201 | * need to call that on resume to set up the reg properly. | |||
202 | */ | |||
203 | radeon_encoder->pixel_clock = adjusted_mode->clock; | |||
204 | atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE1); | |||
205 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL)r100_mm_rreg(rdev, (0x02d0), 0); | |||
206 | } else { | |||
207 | struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; | |||
208 | if (lvds) { | |||
209 | DRM_DEBUG_KMS("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl)__drm_dbg(DRM_UT_KMS, "bios LVDS_GEN_CNTL: 0x%x\n", lvds-> lvds_gen_cntl); | |||
210 | lvds_gen_cntl = lvds->lvds_gen_cntl; | |||
211 | lvds_ss_gen_cntl &= ~((0xf << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT16) | | |||
212 | (0xf << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT20)); | |||
213 | lvds_ss_gen_cntl |= ((lvds->panel_digon_delay << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT16) | | |||
214 | (lvds->panel_blon_delay << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT20)); | |||
215 | } else | |||
216 | lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL)r100_mm_rreg(rdev, (0x02d0), 0); | |||
217 | } | |||
218 | lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS(1 << 1); | |||
219 | lvds_gen_cntl &= ~(RADEON_LVDS_ON(1 << 0) | | |||
220 | RADEON_LVDS_BLON(1 << 19) | | |||
221 | RADEON_LVDS_EN(1 << 7) | | |||
222 | RADEON_LVDS_RST_FM(1 << 6)); | |||
223 | ||||
224 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) | |||
225 | lvds_pll_cntl &= ~(R300_LVDS_SRC_SEL_MASK(3 << 18)); | |||
226 | ||||
227 | if (radeon_crtc->crtc_id == 0) { | |||
228 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
229 | if (radeon_encoder->rmx_type != RMX_OFF) | |||
230 | lvds_pll_cntl |= R300_LVDS_SRC_SEL_RMX(2 << 18); | |||
231 | } else | |||
232 | lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2(1 << 23); | |||
233 | } else { | |||
234 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) | |||
235 | lvds_pll_cntl |= R300_LVDS_SRC_SEL_CRTC2(1 << 18); | |||
236 | else | |||
237 | lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2(1 << 23); | |||
238 | } | |||
239 | ||||
240 | WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl)r100_mm_wreg(rdev, (0x02d0), (lvds_gen_cntl), 0); | |||
241 | WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl)r100_mm_wreg(rdev, (0x02d4), (lvds_pll_cntl), 0); | |||
242 | WREG32(RADEON_LVDS_SS_GEN_CNTL, lvds_ss_gen_cntl)r100_mm_wreg(rdev, (0x02ec), (lvds_ss_gen_cntl), 0); | |||
243 | ||||
244 | if (rdev->family == CHIP_RV410) | |||
245 | WREG32(RADEON_CLOCK_CNTL_INDEX, 0)r100_mm_wreg(rdev, (0x0008), (0), 0); | |||
246 | ||||
247 | if (rdev->is_atom_bios) | |||
248 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | |||
249 | else | |||
250 | radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | |||
251 | } | |||
252 | ||||
253 | static bool_Bool radeon_legacy_mode_fixup(struct drm_encoder *encoder, | |||
254 | const struct drm_display_mode *mode, | |||
255 | struct drm_display_mode *adjusted_mode) | |||
256 | { | |||
257 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
258 | ||||
259 | /* set the active encoder to connector routing */ | |||
260 | radeon_encoder_set_active_device(encoder); | |||
261 | drm_mode_set_crtcinfo(adjusted_mode, 0); | |||
262 | ||||
263 | /* get the native mode for LVDS */ | |||
264 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT((0x1L << 0x00000001 ) | (0x1L << 0x00000005 )))) | |||
265 | radeon_panel_mode_fixup(encoder, adjusted_mode); | |||
266 | ||||
267 | return true1; | |||
268 | } | |||
269 | ||||
270 | static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = { | |||
271 | .dpms = radeon_legacy_lvds_dpms, | |||
272 | .mode_fixup = radeon_legacy_mode_fixup, | |||
273 | .prepare = radeon_legacy_lvds_prepare, | |||
274 | .mode_set = radeon_legacy_lvds_mode_set, | |||
275 | .commit = radeon_legacy_lvds_commit, | |||
276 | .disable = radeon_legacy_encoder_disable, | |||
277 | }; | |||
278 | ||||
279 | u8 | |||
280 | radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder) | |||
281 | { | |||
282 | struct drm_device *dev = radeon_encoder->base.dev; | |||
283 | struct radeon_device *rdev = dev->dev_private; | |||
284 | u8 backlight_level; | |||
285 | ||||
286 | backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL)r100_mm_rreg(rdev, (0x02d0), 0) >> | |||
287 | RADEON_LVDS_BL_MOD_LEVEL_SHIFT8) & 0xff; | |||
288 | ||||
289 | return backlight_level; | |||
290 | } | |||
291 | ||||
292 | void | |||
293 | radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level) | |||
294 | { | |||
295 | struct drm_device *dev = radeon_encoder->base.dev; | |||
296 | struct radeon_device *rdev = dev->dev_private; | |||
297 | int dpms_mode = DRM_MODE_DPMS_ON0; | |||
298 | ||||
299 | if (radeon_encoder->enc_priv) { | |||
300 | if (rdev->is_atom_bios) { | |||
301 | struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; | |||
302 | if (lvds->backlight_level > 0) | |||
303 | dpms_mode = lvds->dpms_mode; | |||
304 | else | |||
305 | dpms_mode = DRM_MODE_DPMS_OFF3; | |||
306 | lvds->backlight_level = level; | |||
307 | } else { | |||
308 | struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; | |||
309 | if (lvds->backlight_level > 0) | |||
310 | dpms_mode = lvds->dpms_mode; | |||
311 | else | |||
312 | dpms_mode = DRM_MODE_DPMS_OFF3; | |||
313 | lvds->backlight_level = level; | |||
314 | } | |||
315 | } | |||
316 | ||||
317 | radeon_legacy_lvds_update(&radeon_encoder->base, dpms_mode); | |||
318 | } | |||
319 | ||||
320 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE1) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) | |||
321 | ||||
322 | static uint8_t radeon_legacy_lvds_level(struct backlight_device *bd) | |||
323 | { | |||
324 | struct radeon_backlight_privdata *pdata = bl_get_data(bd)(bd)->data; | |||
325 | uint8_t level; | |||
326 | ||||
327 | /* Convert brightness to hardware level */ | |||
328 | if (bd->props.brightness < 0) | |||
329 | level = 0; | |||
330 | else if (bd->props.brightness > RADEON_MAX_BL_LEVEL0xFF) | |||
331 | level = RADEON_MAX_BL_LEVEL0xFF; | |||
332 | else | |||
333 | level = bd->props.brightness; | |||
334 | ||||
335 | if (pdata->negative) | |||
336 | level = RADEON_MAX_BL_LEVEL0xFF - level; | |||
337 | ||||
338 | return level; | |||
339 | } | |||
340 | ||||
341 | static int radeon_legacy_backlight_update_status(struct backlight_device *bd) | |||
342 | { | |||
343 | struct radeon_backlight_privdata *pdata = bl_get_data(bd)(bd)->data; | |||
344 | struct radeon_encoder *radeon_encoder = pdata->encoder; | |||
345 | ||||
346 | radeon_legacy_set_backlight_level(radeon_encoder, | |||
347 | radeon_legacy_lvds_level(bd)); | |||
348 | ||||
349 | return 0; | |||
350 | } | |||
351 | ||||
352 | static int radeon_legacy_backlight_get_brightness(struct backlight_device *bd) | |||
353 | { | |||
354 | struct radeon_backlight_privdata *pdata = bl_get_data(bd)(bd)->data; | |||
355 | struct radeon_encoder *radeon_encoder = pdata->encoder; | |||
356 | struct drm_device *dev = radeon_encoder->base.dev; | |||
357 | struct radeon_device *rdev = dev->dev_private; | |||
358 | uint8_t backlight_level; | |||
359 | ||||
360 | backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL)r100_mm_rreg(rdev, (0x02d0), 0) >> | |||
361 | RADEON_LVDS_BL_MOD_LEVEL_SHIFT8) & 0xff; | |||
362 | ||||
363 | return pdata->negative ? RADEON_MAX_BL_LEVEL0xFF - backlight_level : backlight_level; | |||
364 | } | |||
365 | ||||
366 | static const struct backlight_ops radeon_backlight_ops = { | |||
367 | .get_brightness = radeon_legacy_backlight_get_brightness, | |||
368 | .update_status = radeon_legacy_backlight_update_status, | |||
369 | }; | |||
370 | ||||
371 | void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, | |||
372 | struct drm_connector *drm_connector) | |||
373 | { | |||
374 | struct drm_device *dev = radeon_encoder->base.dev; | |||
375 | struct radeon_device *rdev = dev->dev_private; | |||
376 | struct backlight_device *bd; | |||
377 | struct backlight_properties props; | |||
378 | struct radeon_backlight_privdata *pdata; | |||
379 | uint8_t backlight_level; | |||
380 | char bl_name[16]; | |||
381 | ||||
382 | if (!radeon_encoder->enc_priv) | |||
383 | return; | |||
384 | ||||
385 | #ifdef CONFIG_PMAC_BACKLIGHT | |||
386 | if (!pmac_has_backlight_type("ati") && | |||
387 | !pmac_has_backlight_type("mnca")) | |||
388 | return; | |||
389 | #endif | |||
390 | ||||
391 | pdata = kmalloc(sizeof(struct radeon_backlight_privdata), GFP_KERNEL(0x0001 | 0x0004)); | |||
392 | if (!pdata) { | |||
393 | DRM_ERROR("Memory allocation failed\n")__drm_err("Memory allocation failed\n"); | |||
394 | goto error; | |||
395 | } | |||
396 | ||||
397 | memset(&props, 0, sizeof(props))__builtin_memset((&props), (0), (sizeof(props))); | |||
398 | props.max_brightness = RADEON_MAX_BL_LEVEL0xFF; | |||
399 | props.type = BACKLIGHT_RAW0; | |||
400 | snprintf(bl_name, sizeof(bl_name), | |||
401 | "radeon_bl%d", dev->primary->index); | |||
402 | bd = backlight_device_register(bl_name, drm_connector->kdev, | |||
403 | pdata, &radeon_backlight_ops, &props); | |||
404 | if (IS_ERR(bd)) { | |||
405 | DRM_ERROR("Backlight registration failed\n")__drm_err("Backlight registration failed\n"); | |||
406 | goto error; | |||
407 | } | |||
408 | ||||
409 | pdata->encoder = radeon_encoder; | |||
410 | ||||
411 | backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL)r100_mm_rreg(rdev, (0x02d0), 0) >> | |||
412 | RADEON_LVDS_BL_MOD_LEVEL_SHIFT8) & 0xff; | |||
413 | ||||
414 | /* First, try to detect backlight level sense based on the assumption | |||
415 | * that firmware set it up at full brightness | |||
416 | */ | |||
417 | if (backlight_level == 0) | |||
418 | pdata->negative = true1; | |||
419 | else if (backlight_level == 0xff) | |||
420 | pdata->negative = false0; | |||
421 | else { | |||
422 | /* XXX hack... maybe some day we can figure out in what direction | |||
423 | * backlight should work on a given panel? | |||
424 | */ | |||
425 | pdata->negative = (rdev->family != CHIP_RV200 && | |||
426 | rdev->family != CHIP_RV250 && | |||
427 | rdev->family != CHIP_RV280 && | |||
428 | rdev->family != CHIP_RV350); | |||
429 | ||||
430 | #ifdef CONFIG_PMAC_BACKLIGHT | |||
431 | pdata->negative = (pdata->negative || | |||
432 | of_machine_is_compatible("PowerBook4,3") || | |||
433 | of_machine_is_compatible("PowerBook6,3") || | |||
434 | of_machine_is_compatible("PowerBook6,5")); | |||
435 | #endif | |||
436 | } | |||
437 | ||||
438 | if (rdev->is_atom_bios) { | |||
439 | struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; | |||
440 | lvds->bl_dev = bd; | |||
441 | } else { | |||
442 | struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; | |||
443 | lvds->bl_dev = bd; | |||
444 | } | |||
445 | ||||
446 | bd->props.brightness = radeon_legacy_backlight_get_brightness(bd); | |||
447 | bd->props.power = FB_BLANK_UNBLANK0; | |||
448 | backlight_update_status(bd); | |||
449 | ||||
450 | DRM_INFO("radeon legacy LVDS backlight initialized\n")printk("\0016" "[" "drm" "] " "radeon legacy LVDS backlight initialized\n" ); | |||
451 | rdev->mode_info.bl_encoder = radeon_encoder; | |||
452 | ||||
453 | return; | |||
454 | ||||
455 | error: | |||
456 | kfree(pdata); | |||
457 | return; | |||
458 | } | |||
459 | ||||
460 | static void radeon_legacy_backlight_exit(struct radeon_encoder *radeon_encoder) | |||
461 | { | |||
462 | struct drm_device *dev = radeon_encoder->base.dev; | |||
463 | struct radeon_device *rdev = dev->dev_private; | |||
464 | struct backlight_device *bd = NULL((void *)0); | |||
465 | ||||
466 | if (!radeon_encoder->enc_priv) | |||
467 | return; | |||
468 | ||||
469 | if (rdev->is_atom_bios) { | |||
470 | struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; | |||
471 | bd = lvds->bl_dev; | |||
472 | lvds->bl_dev = NULL((void *)0); | |||
473 | } else { | |||
474 | struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; | |||
475 | bd = lvds->bl_dev; | |||
476 | lvds->bl_dev = NULL((void *)0); | |||
477 | } | |||
478 | ||||
479 | if (bd) { | |||
480 | struct radeon_backlight_privdata *pdata; | |||
481 | ||||
482 | pdata = bl_get_data(bd)(bd)->data; | |||
483 | backlight_device_unregister(bd); | |||
484 | kfree(pdata); | |||
485 | ||||
486 | DRM_INFO("radeon legacy LVDS backlight unloaded\n")printk("\0016" "[" "drm" "] " "radeon legacy LVDS backlight unloaded\n" ); | |||
487 | } | |||
488 | } | |||
489 | ||||
490 | #else /* !CONFIG_BACKLIGHT_CLASS_DEVICE */ | |||
491 | ||||
492 | void radeon_legacy_backlight_init(struct radeon_encoder *encoder) | |||
493 | { | |||
494 | } | |||
495 | ||||
496 | static void radeon_legacy_backlight_exit(struct radeon_encoder *encoder) | |||
497 | { | |||
498 | } | |||
499 | ||||
500 | #endif | |||
501 | ||||
502 | ||||
503 | static void radeon_lvds_enc_destroy(struct drm_encoder *encoder) | |||
504 | { | |||
505 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
506 | ||||
507 | if (radeon_encoder->enc_priv) { | |||
508 | radeon_legacy_backlight_exit(radeon_encoder); | |||
509 | kfree(radeon_encoder->enc_priv); | |||
510 | } | |||
511 | drm_encoder_cleanup(encoder); | |||
512 | kfree(radeon_encoder); | |||
513 | } | |||
514 | ||||
515 | static const struct drm_encoder_funcs radeon_legacy_lvds_enc_funcs = { | |||
516 | .destroy = radeon_lvds_enc_destroy, | |||
517 | }; | |||
518 | ||||
519 | static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode) | |||
520 | { | |||
521 | struct drm_device *dev = encoder->dev; | |||
522 | struct radeon_device *rdev = dev->dev_private; | |||
523 | uint32_t crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL)r100_mm_rreg(rdev, (0x0054), 0); | |||
524 | uint32_t dac_cntl = RREG32(RADEON_DAC_CNTL)r100_mm_rreg(rdev, (0x0058), 0); | |||
525 | uint32_t dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL)r100_mm_rreg(rdev, (0x0d04), 0); | |||
526 | ||||
527 | DRM_DEBUG_KMS("\n")__drm_dbg(DRM_UT_KMS, "\n"); | |||
528 | ||||
529 | switch (mode) { | |||
530 | case DRM_MODE_DPMS_ON0: | |||
531 | crtc_ext_cntl |= RADEON_CRTC_CRT_ON(1 << 15); | |||
532 | dac_cntl &= ~RADEON_DAC_PDWN(1 << 15); | |||
533 | dac_macro_cntl &= ~(RADEON_DAC_PDWN_R(1 << 16) | | |||
534 | RADEON_DAC_PDWN_G(1 << 17) | | |||
535 | RADEON_DAC_PDWN_B(1 << 18)); | |||
536 | break; | |||
537 | case DRM_MODE_DPMS_STANDBY1: | |||
538 | case DRM_MODE_DPMS_SUSPEND2: | |||
539 | case DRM_MODE_DPMS_OFF3: | |||
540 | crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON(1 << 15); | |||
541 | dac_cntl |= RADEON_DAC_PDWN(1 << 15); | |||
542 | dac_macro_cntl |= (RADEON_DAC_PDWN_R(1 << 16) | | |||
543 | RADEON_DAC_PDWN_G(1 << 17) | | |||
544 | RADEON_DAC_PDWN_B(1 << 18)); | |||
545 | break; | |||
546 | } | |||
547 | ||||
548 | /* handled in radeon_crtc_dpms() */ | |||
549 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) | |||
550 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl)r100_mm_wreg(rdev, (0x0054), (crtc_ext_cntl), 0); | |||
551 | WREG32(RADEON_DAC_CNTL, dac_cntl)r100_mm_wreg(rdev, (0x0058), (dac_cntl), 0); | |||
552 | WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl)r100_mm_wreg(rdev, (0x0d04), (dac_macro_cntl), 0); | |||
553 | ||||
554 | if (rdev->is_atom_bios) | |||
555 | radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON0) ? true1 : false0); | |||
556 | else | |||
557 | radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON0) ? true1 : false0); | |||
558 | ||||
559 | } | |||
560 | ||||
561 | static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder) | |||
562 | { | |||
563 | struct radeon_device *rdev = encoder->dev->dev_private; | |||
564 | ||||
565 | if (rdev->is_atom_bios) | |||
566 | radeon_atom_output_lock(encoder, true1); | |||
567 | else | |||
568 | radeon_combios_output_lock(encoder, true1); | |||
569 | radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF3); | |||
570 | } | |||
571 | ||||
572 | static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) | |||
573 | { | |||
574 | struct radeon_device *rdev = encoder->dev->dev_private; | |||
575 | ||||
576 | radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_ON0); | |||
577 | ||||
578 | if (rdev->is_atom_bios) | |||
579 | radeon_atom_output_lock(encoder, false0); | |||
580 | else | |||
581 | radeon_combios_output_lock(encoder, false0); | |||
582 | } | |||
583 | ||||
584 | static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, | |||
585 | struct drm_display_mode *mode, | |||
586 | struct drm_display_mode *adjusted_mode) | |||
587 | { | |||
588 | struct drm_device *dev = encoder->dev; | |||
589 | struct radeon_device *rdev = dev->dev_private; | |||
590 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc)({ const __typeof( ((struct radeon_crtc *)0)->base ) *__mptr = (encoder->crtc); (struct radeon_crtc *)( (char *)__mptr - __builtin_offsetof(struct radeon_crtc, base) );}); | |||
591 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
592 | uint32_t disp_output_cntl, dac_cntl, dac2_cntl, dac_macro_cntl; | |||
593 | ||||
594 | DRM_DEBUG_KMS("\n")__drm_dbg(DRM_UT_KMS, "\n"); | |||
595 | ||||
596 | if (radeon_crtc->crtc_id == 0) { | |||
597 | if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
598 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL)r100_mm_rreg(rdev, (0x0d64), 0) & | |||
599 | ~(RADEON_DISP_DAC_SOURCE_MASK0x03); | |||
600 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl)r100_mm_wreg(rdev, (0x0d64), (disp_output_cntl), 0); | |||
601 | } else { | |||
602 | dac2_cntl = RREG32(RADEON_DAC_CNTL2)r100_mm_rreg(rdev, (0x007c), 0) & ~(RADEON_DAC2_DAC_CLK_SEL(1 << 0)); | |||
603 | WREG32(RADEON_DAC_CNTL2, dac2_cntl)r100_mm_wreg(rdev, (0x007c), (dac2_cntl), 0); | |||
604 | } | |||
605 | } else { | |||
606 | if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
607 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL)r100_mm_rreg(rdev, (0x0d64), 0) & | |||
608 | ~(RADEON_DISP_DAC_SOURCE_MASK0x03); | |||
609 | disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC20x01; | |||
610 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl)r100_mm_wreg(rdev, (0x0d64), (disp_output_cntl), 0); | |||
611 | } else { | |||
612 | dac2_cntl = RREG32(RADEON_DAC_CNTL2)r100_mm_rreg(rdev, (0x007c), 0) | RADEON_DAC2_DAC_CLK_SEL(1 << 0); | |||
613 | WREG32(RADEON_DAC_CNTL2, dac2_cntl)r100_mm_wreg(rdev, (0x007c), (dac2_cntl), 0); | |||
614 | } | |||
615 | } | |||
616 | ||||
617 | dac_cntl = (RADEON_DAC_MASK_ALL(0xff << 24) | | |||
618 | RADEON_DAC_VGA_ADR_EN(1 << 13) | | |||
619 | /* TODO 6-bits */ | |||
620 | RADEON_DAC_8BIT_EN(1 << 8)); | |||
621 | ||||
622 | WREG32_P(RADEON_DAC_CNTL,do { uint32_t tmp_ = r100_mm_rreg(rdev, (0x0058), 0); tmp_ &= ((3 << 0) | (1 << 2)); tmp_ |= ((dac_cntl) & ~((3 << 0) | (1 << 2))); r100_mm_wreg(rdev, (0x0058 ), (tmp_), 0); } while (0) | |||
623 | dac_cntl,do { uint32_t tmp_ = r100_mm_rreg(rdev, (0x0058), 0); tmp_ &= ((3 << 0) | (1 << 2)); tmp_ |= ((dac_cntl) & ~((3 << 0) | (1 << 2))); r100_mm_wreg(rdev, (0x0058 ), (tmp_), 0); } while (0) | |||
624 | RADEON_DAC_RANGE_CNTL |do { uint32_t tmp_ = r100_mm_rreg(rdev, (0x0058), 0); tmp_ &= ((3 << 0) | (1 << 2)); tmp_ |= ((dac_cntl) & ~((3 << 0) | (1 << 2))); r100_mm_wreg(rdev, (0x0058 ), (tmp_), 0); } while (0) | |||
625 | RADEON_DAC_BLANKING)do { uint32_t tmp_ = r100_mm_rreg(rdev, (0x0058), 0); tmp_ &= ((3 << 0) | (1 << 2)); tmp_ |= ((dac_cntl) & ~((3 << 0) | (1 << 2))); r100_mm_wreg(rdev, (0x0058 ), (tmp_), 0); } while (0); | |||
626 | ||||
627 | if (radeon_encoder->enc_priv) { | |||
628 | struct radeon_encoder_primary_dac *p_dac = (struct radeon_encoder_primary_dac *)radeon_encoder->enc_priv; | |||
629 | dac_macro_cntl = p_dac->ps2_pdac_adj; | |||
630 | } else | |||
631 | dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL)r100_mm_rreg(rdev, (0x0d04), 0); | |||
632 | dac_macro_cntl |= RADEON_DAC_PDWN_R(1 << 16) | RADEON_DAC_PDWN_G(1 << 17) | RADEON_DAC_PDWN_B(1 << 18); | |||
633 | WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl)r100_mm_wreg(rdev, (0x0d04), (dac_macro_cntl), 0); | |||
634 | ||||
635 | if (rdev->is_atom_bios) | |||
636 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | |||
637 | else | |||
638 | radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | |||
639 | } | |||
640 | ||||
641 | static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_encoder *encoder, | |||
642 | struct drm_connector *connector) | |||
643 | { | |||
644 | struct drm_device *dev = encoder->dev; | |||
645 | struct radeon_device *rdev = dev->dev_private; | |||
646 | uint32_t vclk_ecp_cntl, crtc_ext_cntl; | |||
647 | uint32_t dac_ext_cntl, dac_cntl, dac_macro_cntl, tmp; | |||
648 | enum drm_connector_status found = connector_status_disconnected; | |||
649 | bool_Bool color = true1; | |||
650 | ||||
651 | /* just don't bother on RN50 those chip are often connected to remoting | |||
652 | * console hw and often we get failure to load detect those. So to make | |||
653 | * everyone happy report the encoder as always connected. | |||
654 | */ | |||
655 | if (ASIC_IS_RN50(rdev)((rdev->pdev->device == 0x515e) || (rdev->pdev->device == 0x5969))) { | |||
656 | return connector_status_connected; | |||
657 | } | |||
658 | ||||
659 | /* save the regs we need */ | |||
660 | vclk_ecp_cntl = RREG32_PLL(RADEON_VCLK_ECP_CNTL)rdev->pll_rreg(rdev, (0x0008)); | |||
661 | crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL)r100_mm_rreg(rdev, (0x0054), 0); | |||
662 | dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL)r100_mm_rreg(rdev, (0x0280), 0); | |||
663 | dac_cntl = RREG32(RADEON_DAC_CNTL)r100_mm_rreg(rdev, (0x0058), 0); | |||
664 | dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL)r100_mm_rreg(rdev, (0x0d04), 0); | |||
665 | ||||
666 | tmp = vclk_ecp_cntl & | |||
667 | ~(RADEON_PIXCLK_ALWAYS_ONb(1<<6) | RADEON_PIXCLK_DAC_ALWAYS_ONb(1<<7)); | |||
668 | WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp)rdev->pll_wreg(rdev, (0x0008), (tmp)); | |||
669 | ||||
670 | tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON(1 << 15); | |||
671 | WREG32(RADEON_CRTC_EXT_CNTL, tmp)r100_mm_wreg(rdev, (0x0054), (tmp), 0); | |||
672 | ||||
673 | tmp = RADEON_DAC_FORCE_BLANK_OFF_EN(1 << 4) | | |||
674 | RADEON_DAC_FORCE_DATA_EN(1 << 5); | |||
675 | ||||
676 | if (color) | |||
677 | tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB(3 << 6); | |||
678 | else | |||
679 | tmp |= RADEON_DAC_FORCE_DATA_SEL_G(1 << 6); | |||
680 | ||||
681 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) | |||
682 | tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT8); | |||
683 | else if (ASIC_IS_RV100(rdev)((rdev->family == CHIP_RV100) || (rdev->family == CHIP_RV200 ) || (rdev->family == CHIP_RS100) || (rdev->family == CHIP_RS200 ) || (rdev->family == CHIP_RV250) || (rdev->family == CHIP_RV280 ) || (rdev->family == CHIP_RS300))) | |||
684 | tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT8); | |||
685 | else | |||
686 | tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT8); | |||
687 | ||||
688 | WREG32(RADEON_DAC_EXT_CNTL, tmp)r100_mm_wreg(rdev, (0x0280), (tmp), 0); | |||
689 | ||||
690 | tmp = dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK0x03 | RADEON_DAC_PDWN(1 << 15)); | |||
691 | tmp |= RADEON_DAC_RANGE_CNTL_PS2(2 << 0) | RADEON_DAC_CMP_EN(1 << 3); | |||
692 | WREG32(RADEON_DAC_CNTL, tmp)r100_mm_wreg(rdev, (0x0058), (tmp), 0); | |||
693 | ||||
694 | tmp = dac_macro_cntl; | |||
695 | tmp &= ~(RADEON_DAC_PDWN_R(1 << 16) | | |||
696 | RADEON_DAC_PDWN_G(1 << 17) | | |||
697 | RADEON_DAC_PDWN_B(1 << 18)); | |||
698 | ||||
699 | WREG32(RADEON_DAC_MACRO_CNTL, tmp)r100_mm_wreg(rdev, (0x0d04), (tmp), 0); | |||
700 | ||||
701 | mdelay(2); | |||
702 | ||||
703 | if (RREG32(RADEON_DAC_CNTL)r100_mm_rreg(rdev, (0x0058), 0) & RADEON_DAC_CMP_OUTPUT(1 << 7)) | |||
704 | found = connector_status_connected; | |||
705 | ||||
706 | /* restore the regs we used */ | |||
707 | WREG32(RADEON_DAC_CNTL, dac_cntl)r100_mm_wreg(rdev, (0x0058), (dac_cntl), 0); | |||
708 | WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl)r100_mm_wreg(rdev, (0x0d04), (dac_macro_cntl), 0); | |||
709 | WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl)r100_mm_wreg(rdev, (0x0280), (dac_ext_cntl), 0); | |||
710 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl)r100_mm_wreg(rdev, (0x0054), (crtc_ext_cntl), 0); | |||
711 | WREG32_PLL(RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl)rdev->pll_wreg(rdev, (0x0008), (vclk_ecp_cntl)); | |||
712 | ||||
713 | return found; | |||
714 | } | |||
715 | ||||
716 | static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = { | |||
717 | .dpms = radeon_legacy_primary_dac_dpms, | |||
718 | .mode_fixup = radeon_legacy_mode_fixup, | |||
719 | .prepare = radeon_legacy_primary_dac_prepare, | |||
720 | .mode_set = radeon_legacy_primary_dac_mode_set, | |||
721 | .commit = radeon_legacy_primary_dac_commit, | |||
722 | .detect = radeon_legacy_primary_dac_detect, | |||
723 | .disable = radeon_legacy_encoder_disable, | |||
724 | }; | |||
725 | ||||
726 | ||||
727 | static const struct drm_encoder_funcs radeon_legacy_primary_dac_enc_funcs = { | |||
728 | .destroy = radeon_enc_destroy, | |||
729 | }; | |||
730 | ||||
731 | static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode) | |||
732 | { | |||
733 | struct drm_device *dev = encoder->dev; | |||
734 | struct radeon_device *rdev = dev->dev_private; | |||
735 | uint32_t fp_gen_cntl = RREG32(RADEON_FP_GEN_CNTL)r100_mm_rreg(rdev, (0x0284), 0); | |||
736 | DRM_DEBUG_KMS("\n")__drm_dbg(DRM_UT_KMS, "\n"); | |||
737 | ||||
738 | switch (mode) { | |||
739 | case DRM_MODE_DPMS_ON0: | |||
740 | fp_gen_cntl |= (RADEON_FP_FPON(1 << 0) | RADEON_FP_TMDS_EN(1 << 2)); | |||
741 | break; | |||
742 | case DRM_MODE_DPMS_STANDBY1: | |||
743 | case DRM_MODE_DPMS_SUSPEND2: | |||
744 | case DRM_MODE_DPMS_OFF3: | |||
745 | fp_gen_cntl &= ~(RADEON_FP_FPON(1 << 0) | RADEON_FP_TMDS_EN(1 << 2)); | |||
746 | break; | |||
747 | } | |||
748 | ||||
749 | WREG32(RADEON_FP_GEN_CNTL, fp_gen_cntl)r100_mm_wreg(rdev, (0x0284), (fp_gen_cntl), 0); | |||
750 | ||||
751 | if (rdev->is_atom_bios) | |||
752 | radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON0) ? true1 : false0); | |||
753 | else | |||
754 | radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON0) ? true1 : false0); | |||
755 | ||||
756 | } | |||
757 | ||||
758 | static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder) | |||
759 | { | |||
760 | struct radeon_device *rdev = encoder->dev->dev_private; | |||
761 | ||||
762 | if (rdev->is_atom_bios) | |||
763 | radeon_atom_output_lock(encoder, true1); | |||
764 | else | |||
765 | radeon_combios_output_lock(encoder, true1); | |||
766 | radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF3); | |||
767 | } | |||
768 | ||||
769 | static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) | |||
770 | { | |||
771 | struct radeon_device *rdev = encoder->dev->dev_private; | |||
772 | ||||
773 | radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_ON0); | |||
774 | ||||
775 | if (rdev->is_atom_bios) | |||
776 | radeon_atom_output_lock(encoder, true1); | |||
777 | else | |||
778 | radeon_combios_output_lock(encoder, true1); | |||
779 | } | |||
780 | ||||
781 | static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, | |||
782 | struct drm_display_mode *mode, | |||
783 | struct drm_display_mode *adjusted_mode) | |||
784 | { | |||
785 | struct drm_device *dev = encoder->dev; | |||
786 | struct radeon_device *rdev = dev->dev_private; | |||
787 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc)({ const __typeof( ((struct radeon_crtc *)0)->base ) *__mptr = (encoder->crtc); (struct radeon_crtc *)( (char *)__mptr - __builtin_offsetof(struct radeon_crtc, base) );}); | |||
788 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
789 | uint32_t tmp, tmds_pll_cntl, tmds_transmitter_cntl, fp_gen_cntl; | |||
790 | int i; | |||
791 | ||||
792 | DRM_DEBUG_KMS("\n")__drm_dbg(DRM_UT_KMS, "\n"); | |||
793 | ||||
794 | tmp = tmds_pll_cntl = RREG32(RADEON_TMDS_PLL_CNTL)r100_mm_rreg(rdev, (0x02a8), 0); | |||
795 | tmp &= 0xfffff; | |||
796 | if (rdev->family == CHIP_RV280) { | |||
797 | /* bit 22 of TMDS_PLL_CNTL is read-back inverted */ | |||
798 | tmp ^= (1 << 22); | |||
799 | tmds_pll_cntl ^= (1 << 22); | |||
800 | } | |||
801 | ||||
802 | if (radeon_encoder->enc_priv) { | |||
803 | struct radeon_encoder_int_tmds *tmds = (struct radeon_encoder_int_tmds *)radeon_encoder->enc_priv; | |||
804 | ||||
805 | for (i = 0; i < 4; i++) { | |||
806 | if (tmds->tmds_pll[i].freq == 0) | |||
807 | break; | |||
808 | if ((uint32_t)(mode->clock / 10) < tmds->tmds_pll[i].freq) { | |||
809 | tmp = tmds->tmds_pll[i].value ; | |||
810 | break; | |||
811 | } | |||
812 | } | |||
813 | } | |||
814 | ||||
815 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480)) || (rdev->family == CHIP_RV280)) { | |||
816 | if (tmp & 0xfff00000) | |||
817 | tmds_pll_cntl = tmp; | |||
818 | else { | |||
819 | tmds_pll_cntl &= 0xfff00000; | |||
820 | tmds_pll_cntl |= tmp; | |||
821 | } | |||
822 | } else | |||
823 | tmds_pll_cntl = tmp; | |||
824 | ||||
825 | tmds_transmitter_cntl = RREG32(RADEON_TMDS_TRANSMITTER_CNTL)r100_mm_rreg(rdev, (0x02a4), 0) & | |||
826 | ~(RADEON_TMDS_TRANSMITTER_PLLRST2); | |||
827 | ||||
828 | if (rdev->family == CHIP_R200 || | |||
829 | rdev->family == CHIP_R100 || | |||
830 | ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) | |||
831 | tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN1); | |||
832 | else /* RV chips got this bit reversed */ | |||
833 | tmds_transmitter_cntl |= RADEON_TMDS_TRANSMITTER_PLLEN1; | |||
834 | ||||
835 | fp_gen_cntl = (RREG32(RADEON_FP_GEN_CNTL)r100_mm_rreg(rdev, (0x0284), 0) | | |||
836 | (RADEON_FP_CRTC_DONT_SHADOW_VPAR(1 << 16) | | |||
837 | RADEON_FP_CRTC_DONT_SHADOW_HEND(1 << 17))); | |||
838 | ||||
839 | fp_gen_cntl &= ~(RADEON_FP_FPON(1 << 0) | RADEON_FP_TMDS_EN(1 << 2)); | |||
840 | ||||
841 | fp_gen_cntl &= ~(RADEON_FP_RMX_HVSYNC_CONTROL_EN(1 << 20) | | |||
842 | RADEON_FP_DFP_SYNC_SEL(1 << 21) | | |||
843 | RADEON_FP_CRT_SYNC_SEL(1 << 23) | | |||
844 | RADEON_FP_CRTC_LOCK_8DOT(1 << 22) | | |||
845 | RADEON_FP_USE_SHADOW_EN(1 << 24) | | |||
846 | RADEON_FP_CRTC_USE_SHADOW_VEND(1 << 18) | | |||
847 | RADEON_FP_CRT_SYNC_ALT(1 << 26)); | |||
848 | ||||
849 | if (1) /* FIXME rgbBits == 8 */ | |||
850 | fp_gen_cntl |= RADEON_FP_PANEL_FORMAT(1 << 3); /* 24 bit format */ | |||
851 | else | |||
852 | fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT(1 << 3);/* 18 bit format */ | |||
853 | ||||
854 | if (radeon_crtc->crtc_id == 0) { | |||
855 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480)) || rdev->family == CHIP_R200) { | |||
856 | fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK(3 << 10); | |||
857 | if (radeon_encoder->rmx_type != RMX_OFF) | |||
858 | fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX(2 << 10); | |||
859 | else | |||
860 | fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1(0 << 10); | |||
861 | } else | |||
862 | fp_gen_cntl &= ~RADEON_FP_SEL_CRTC2(1 << 13); | |||
863 | } else { | |||
864 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480)) || rdev->family == CHIP_R200) { | |||
865 | fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK(3 << 10); | |||
866 | fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2(1 << 10); | |||
867 | } else | |||
868 | fp_gen_cntl |= RADEON_FP_SEL_CRTC2(1 << 13); | |||
869 | } | |||
870 | ||||
871 | WREG32(RADEON_TMDS_PLL_CNTL, tmds_pll_cntl)r100_mm_wreg(rdev, (0x02a8), (tmds_pll_cntl), 0); | |||
872 | WREG32(RADEON_TMDS_TRANSMITTER_CNTL, tmds_transmitter_cntl)r100_mm_wreg(rdev, (0x02a4), (tmds_transmitter_cntl), 0); | |||
873 | WREG32(RADEON_FP_GEN_CNTL, fp_gen_cntl)r100_mm_wreg(rdev, (0x0284), (fp_gen_cntl), 0); | |||
874 | ||||
875 | if (rdev->is_atom_bios) | |||
876 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | |||
877 | else | |||
878 | radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | |||
879 | } | |||
880 | ||||
881 | static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = { | |||
882 | .dpms = radeon_legacy_tmds_int_dpms, | |||
883 | .mode_fixup = radeon_legacy_mode_fixup, | |||
884 | .prepare = radeon_legacy_tmds_int_prepare, | |||
885 | .mode_set = radeon_legacy_tmds_int_mode_set, | |||
886 | .commit = radeon_legacy_tmds_int_commit, | |||
887 | .disable = radeon_legacy_encoder_disable, | |||
888 | }; | |||
889 | ||||
890 | ||||
891 | static const struct drm_encoder_funcs radeon_legacy_tmds_int_enc_funcs = { | |||
892 | .destroy = radeon_enc_destroy, | |||
893 | }; | |||
894 | ||||
895 | static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode) | |||
896 | { | |||
897 | struct drm_device *dev = encoder->dev; | |||
898 | struct radeon_device *rdev = dev->dev_private; | |||
899 | uint32_t fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL)r100_mm_rreg(rdev, (0x0288), 0); | |||
900 | DRM_DEBUG_KMS("\n")__drm_dbg(DRM_UT_KMS, "\n"); | |||
901 | ||||
902 | switch (mode) { | |||
903 | case DRM_MODE_DPMS_ON0: | |||
904 | fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN(1 << 1); | |||
905 | fp2_gen_cntl |= (RADEON_FP2_ON(1 << 2) | RADEON_FP2_DVO_EN(1 << 25)); | |||
906 | break; | |||
907 | case DRM_MODE_DPMS_STANDBY1: | |||
908 | case DRM_MODE_DPMS_SUSPEND2: | |||
909 | case DRM_MODE_DPMS_OFF3: | |||
910 | fp2_gen_cntl |= RADEON_FP2_BLANK_EN(1 << 1); | |||
911 | fp2_gen_cntl &= ~(RADEON_FP2_ON(1 << 2) | RADEON_FP2_DVO_EN(1 << 25)); | |||
912 | break; | |||
913 | } | |||
914 | ||||
915 | WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl)r100_mm_wreg(rdev, (0x0288), (fp2_gen_cntl), 0); | |||
916 | ||||
917 | if (rdev->is_atom_bios) | |||
918 | radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON0) ? true1 : false0); | |||
919 | else | |||
920 | radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON0) ? true1 : false0); | |||
921 | ||||
922 | } | |||
923 | ||||
924 | static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder) | |||
925 | { | |||
926 | struct radeon_device *rdev = encoder->dev->dev_private; | |||
927 | ||||
928 | if (rdev->is_atom_bios) | |||
929 | radeon_atom_output_lock(encoder, true1); | |||
930 | else | |||
931 | radeon_combios_output_lock(encoder, true1); | |||
932 | radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF3); | |||
933 | } | |||
934 | ||||
935 | static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) | |||
936 | { | |||
937 | struct radeon_device *rdev = encoder->dev->dev_private; | |||
938 | radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_ON0); | |||
939 | ||||
940 | if (rdev->is_atom_bios) | |||
941 | radeon_atom_output_lock(encoder, false0); | |||
942 | else | |||
943 | radeon_combios_output_lock(encoder, false0); | |||
944 | } | |||
945 | ||||
946 | static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, | |||
947 | struct drm_display_mode *mode, | |||
948 | struct drm_display_mode *adjusted_mode) | |||
949 | { | |||
950 | struct drm_device *dev = encoder->dev; | |||
951 | struct radeon_device *rdev = dev->dev_private; | |||
952 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc)({ const __typeof( ((struct radeon_crtc *)0)->base ) *__mptr = (encoder->crtc); (struct radeon_crtc *)( (char *)__mptr - __builtin_offsetof(struct radeon_crtc, base) );}); | |||
953 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
954 | uint32_t fp2_gen_cntl; | |||
955 | ||||
956 | DRM_DEBUG_KMS("\n")__drm_dbg(DRM_UT_KMS, "\n"); | |||
957 | ||||
958 | if (rdev->is_atom_bios) { | |||
959 | radeon_encoder->pixel_clock = adjusted_mode->clock; | |||
960 | atombios_dvo_setup(encoder, ATOM_ENABLE1); | |||
961 | fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL)r100_mm_rreg(rdev, (0x0288), 0); | |||
962 | } else { | |||
963 | fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL)r100_mm_rreg(rdev, (0x0288), 0); | |||
964 | ||||
965 | if (1) /* FIXME rgbBits == 8 */ | |||
966 | fp2_gen_cntl |= RADEON_FP2_PANEL_FORMAT(1 << 3); /* 24 bit format, */ | |||
967 | else | |||
968 | fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT(1 << 3);/* 18 bit format, */ | |||
969 | ||||
970 | fp2_gen_cntl &= ~(RADEON_FP2_ON(1 << 2) | | |||
971 | RADEON_FP2_DVO_EN(1 << 25) | | |||
972 | RADEON_FP2_DVO_RATE_SEL_SDR(1 << 26)); | |||
973 | ||||
974 | /* XXX: these are oem specific */ | |||
975 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
976 | if ((dev->pdev->device == 0x4850) && | |||
977 | (dev->pdev->subsystem_vendor == 0x1028) && | |||
978 | (dev->pdev->subsystem_device == 0x2001)) /* Dell Inspiron 8600 */ | |||
979 | fp2_gen_cntl |= R300_FP2_DVO_CLOCK_MODE_SINGLE(1 << 28); | |||
980 | else | |||
981 | fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN(1 << 22) | R300_FP2_DVO_CLOCK_MODE_SINGLE(1 << 28); | |||
982 | ||||
983 | /*if (mode->clock > 165000) | |||
984 | fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/ | |||
985 | } | |||
986 | if (!radeon_combios_external_tmds_setup(encoder)) | |||
987 | radeon_external_tmds_setup(encoder); | |||
988 | } | |||
989 | ||||
990 | if (radeon_crtc->crtc_id == 0) { | |||
991 | if ((rdev->family == CHIP_R200) || ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
992 | fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK(3 << 10); | |||
993 | if (radeon_encoder->rmx_type != RMX_OFF) | |||
994 | fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX(2 << 10); | |||
995 | else | |||
996 | fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1(0 << 10); | |||
997 | } else | |||
998 | fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2(1 << 13); | |||
999 | } else { | |||
1000 | if ((rdev->family == CHIP_R200) || ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
1001 | fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK(3 << 10); | |||
1002 | fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2(1 << 10); | |||
1003 | } else | |||
1004 | fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2(1 << 13); | |||
1005 | } | |||
1006 | ||||
1007 | WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl)r100_mm_wreg(rdev, (0x0288), (fp2_gen_cntl), 0); | |||
1008 | ||||
1009 | if (rdev->is_atom_bios) | |||
1010 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | |||
1011 | else | |||
1012 | radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | |||
1013 | } | |||
1014 | ||||
1015 | static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder) | |||
1016 | { | |||
1017 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
1018 | /* don't destroy the i2c bus record here, this will be done in radeon_i2c_fini */ | |||
1019 | kfree(radeon_encoder->enc_priv); | |||
1020 | drm_encoder_cleanup(encoder); | |||
1021 | kfree(radeon_encoder); | |||
1022 | } | |||
1023 | ||||
1024 | static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = { | |||
1025 | .dpms = radeon_legacy_tmds_ext_dpms, | |||
1026 | .mode_fixup = radeon_legacy_mode_fixup, | |||
1027 | .prepare = radeon_legacy_tmds_ext_prepare, | |||
1028 | .mode_set = radeon_legacy_tmds_ext_mode_set, | |||
1029 | .commit = radeon_legacy_tmds_ext_commit, | |||
1030 | .disable = radeon_legacy_encoder_disable, | |||
1031 | }; | |||
1032 | ||||
1033 | ||||
1034 | static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = { | |||
1035 | .destroy = radeon_ext_tmds_enc_destroy, | |||
1036 | }; | |||
1037 | ||||
1038 | static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) | |||
1039 | { | |||
1040 | struct drm_device *dev = encoder->dev; | |||
1041 | struct radeon_device *rdev = dev->dev_private; | |||
1042 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
1043 | uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0; | |||
1044 | uint32_t tv_master_cntl = 0; | |||
1045 | bool_Bool is_tv; | |||
1046 | DRM_DEBUG_KMS("\n")__drm_dbg(DRM_UT_KMS, "\n"); | |||
1047 | ||||
1048 | is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT((0x1L << 0x00000002 )) ? true1 : false0; | |||
1049 | ||||
1050 | if (rdev->family == CHIP_R200) | |||
1051 | fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL)r100_mm_rreg(rdev, (0x0288), 0); | |||
1052 | else { | |||
1053 | if (is_tv) | |||
1054 | tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL)r100_mm_rreg(rdev, (0x0800), 0); | |||
1055 | else | |||
1056 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL)r100_mm_rreg(rdev, (0x03f8), 0); | |||
1057 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL)r100_mm_rreg(rdev, (0x088c), 0); | |||
1058 | } | |||
1059 | ||||
1060 | switch (mode) { | |||
1061 | case DRM_MODE_DPMS_ON0: | |||
1062 | if (rdev->family == CHIP_R200) { | |||
1063 | fp2_gen_cntl |= (RADEON_FP2_ON(1 << 2) | RADEON_FP2_DVO_EN(1 << 25)); | |||
1064 | } else { | |||
1065 | if (is_tv) | |||
1066 | tv_master_cntl |= RADEON_TV_ON(1 << 31); | |||
1067 | else | |||
1068 | crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON(1 << 7); | |||
1069 | ||||
1070 | if (rdev->family == CHIP_R420 || | |||
1071 | rdev->family == CHIP_R423 || | |||
1072 | rdev->family == CHIP_RV410) | |||
1073 | tv_dac_cntl &= ~(R420_TV_DAC_RDACPD(1 << 25) | | |||
1074 | R420_TV_DAC_GDACPD(1 << 26) | | |||
1075 | R420_TV_DAC_BDACPD(1 << 27) | | |||
1076 | RADEON_TV_DAC_BGSLEEP(1 << 6)); | |||
1077 | else | |||
1078 | tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD(1 << 24) | | |||
1079 | RADEON_TV_DAC_GDACPD(1 << 25) | | |||
1080 | RADEON_TV_DAC_BDACPD(1 << 26) | | |||
1081 | RADEON_TV_DAC_BGSLEEP(1 << 6)); | |||
1082 | } | |||
1083 | break; | |||
1084 | case DRM_MODE_DPMS_STANDBY1: | |||
1085 | case DRM_MODE_DPMS_SUSPEND2: | |||
1086 | case DRM_MODE_DPMS_OFF3: | |||
1087 | if (rdev->family == CHIP_R200) | |||
1088 | fp2_gen_cntl &= ~(RADEON_FP2_ON(1 << 2) | RADEON_FP2_DVO_EN(1 << 25)); | |||
1089 | else { | |||
1090 | if (is_tv) | |||
1091 | tv_master_cntl &= ~RADEON_TV_ON(1 << 31); | |||
1092 | else | |||
1093 | crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON(1 << 7); | |||
1094 | ||||
1095 | if (rdev->family == CHIP_R420 || | |||
1096 | rdev->family == CHIP_R423 || | |||
1097 | rdev->family == CHIP_RV410) | |||
1098 | tv_dac_cntl |= (R420_TV_DAC_RDACPD(1 << 25) | | |||
1099 | R420_TV_DAC_GDACPD(1 << 26) | | |||
1100 | R420_TV_DAC_BDACPD(1 << 27) | | |||
1101 | RADEON_TV_DAC_BGSLEEP(1 << 6)); | |||
1102 | else | |||
1103 | tv_dac_cntl |= (RADEON_TV_DAC_RDACPD(1 << 24) | | |||
1104 | RADEON_TV_DAC_GDACPD(1 << 25) | | |||
1105 | RADEON_TV_DAC_BDACPD(1 << 26) | | |||
1106 | RADEON_TV_DAC_BGSLEEP(1 << 6)); | |||
1107 | } | |||
1108 | break; | |||
1109 | } | |||
1110 | ||||
1111 | if (rdev->family == CHIP_R200) { | |||
1112 | WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl)r100_mm_wreg(rdev, (0x0288), (fp2_gen_cntl), 0); | |||
1113 | } else { | |||
1114 | if (is_tv) | |||
1115 | WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl)r100_mm_wreg(rdev, (0x0800), (tv_master_cntl), 0); | |||
1116 | /* handled in radeon_crtc_dpms() */ | |||
1117 | else if (!(rdev->flags & RADEON_SINGLE_CRTC)) | |||
1118 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl)r100_mm_wreg(rdev, (0x03f8), (crtc2_gen_cntl), 0); | |||
1119 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl)r100_mm_wreg(rdev, (0x088c), (tv_dac_cntl), 0); | |||
1120 | } | |||
1121 | ||||
1122 | if (rdev->is_atom_bios) | |||
1123 | radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON0) ? true1 : false0); | |||
1124 | else | |||
1125 | radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON0) ? true1 : false0); | |||
1126 | ||||
1127 | } | |||
1128 | ||||
1129 | static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder) | |||
1130 | { | |||
1131 | struct radeon_device *rdev = encoder->dev->dev_private; | |||
1132 | ||||
1133 | if (rdev->is_atom_bios) | |||
1134 | radeon_atom_output_lock(encoder, true1); | |||
1135 | else | |||
1136 | radeon_combios_output_lock(encoder, true1); | |||
1137 | radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF3); | |||
1138 | } | |||
1139 | ||||
1140 | static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) | |||
1141 | { | |||
1142 | struct radeon_device *rdev = encoder->dev->dev_private; | |||
1143 | ||||
1144 | radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_ON0); | |||
1145 | ||||
1146 | if (rdev->is_atom_bios) | |||
1147 | radeon_atom_output_lock(encoder, true1); | |||
1148 | else | |||
1149 | radeon_combios_output_lock(encoder, true1); | |||
1150 | } | |||
1151 | ||||
1152 | static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, | |||
1153 | struct drm_display_mode *mode, | |||
1154 | struct drm_display_mode *adjusted_mode) | |||
1155 | { | |||
1156 | struct drm_device *dev = encoder->dev; | |||
1157 | struct radeon_device *rdev = dev->dev_private; | |||
1158 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc)({ const __typeof( ((struct radeon_crtc *)0)->base ) *__mptr = (encoder->crtc); (struct radeon_crtc *)( (char *)__mptr - __builtin_offsetof(struct radeon_crtc, base) );}); | |||
1159 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
1160 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | |||
1161 | uint32_t tv_dac_cntl, gpiopad_a = 0, dac2_cntl, disp_output_cntl = 0; | |||
1162 | uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0, disp_tv_out_cntl = 0; | |||
1163 | bool_Bool is_tv = false0; | |||
1164 | ||||
1165 | DRM_DEBUG_KMS("\n")__drm_dbg(DRM_UT_KMS, "\n"); | |||
1166 | ||||
1167 | is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT((0x1L << 0x00000002 )) ? true1 : false0; | |||
1168 | ||||
1169 | if (rdev->family != CHIP_R200) { | |||
1170 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL)r100_mm_rreg(rdev, (0x088c), 0); | |||
1171 | if (rdev->family == CHIP_R420 || | |||
1172 | rdev->family == CHIP_R423 || | |||
1173 | rdev->family == CHIP_RV410) { | |||
1174 | tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK(3 << 8) | | |||
1175 | RADEON_TV_DAC_BGADJ_MASK(0xf << 16) | | |||
1176 | R420_TV_DAC_DACADJ_MASK(0x1f << 20) | | |||
1177 | R420_TV_DAC_RDACPD(1 << 25) | | |||
1178 | R420_TV_DAC_GDACPD(1 << 26) | | |||
1179 | R420_TV_DAC_BDACPD(1 << 27) | | |||
1180 | R420_TV_DAC_TVENABLE(1 << 28)); | |||
1181 | } else { | |||
1182 | tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK(3 << 8) | | |||
1183 | RADEON_TV_DAC_BGADJ_MASK(0xf << 16) | | |||
1184 | RADEON_TV_DAC_DACADJ_MASK(0xf << 20) | | |||
1185 | RADEON_TV_DAC_RDACPD(1 << 24) | | |||
1186 | RADEON_TV_DAC_GDACPD(1 << 25) | | |||
1187 | RADEON_TV_DAC_BDACPD(1 << 26)); | |||
1188 | } | |||
1189 | ||||
1190 | tv_dac_cntl |= RADEON_TV_DAC_NBLANK(1 << 0) | RADEON_TV_DAC_NHOLD(1 << 1); | |||
1191 | ||||
1192 | if (is_tv) { | |||
1193 | if (tv_dac->tv_std == TV_STD_NTSC || | |||
1194 | tv_dac->tv_std == TV_STD_NTSC_J || | |||
1195 | tv_dac->tv_std == TV_STD_PAL_M || | |||
1196 | tv_dac->tv_std == TV_STD_PAL_60) | |||
1197 | tv_dac_cntl |= tv_dac->ntsc_tvdac_adj; | |||
1198 | else | |||
1199 | tv_dac_cntl |= tv_dac->pal_tvdac_adj; | |||
1200 | ||||
1201 | if (tv_dac->tv_std == TV_STD_NTSC || | |||
1202 | tv_dac->tv_std == TV_STD_NTSC_J) | |||
1203 | tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC(1 << 8); | |||
1204 | else | |||
1205 | tv_dac_cntl |= RADEON_TV_DAC_STD_PAL(0 << 8); | |||
1206 | } else | |||
1207 | tv_dac_cntl |= (RADEON_TV_DAC_STD_PS2(2 << 8) | | |||
1208 | tv_dac->ps2_tvdac_adj); | |||
1209 | ||||
1210 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl)r100_mm_wreg(rdev, (0x088c), (tv_dac_cntl), 0); | |||
1211 | } | |||
1212 | ||||
1213 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
1214 | gpiopad_a = RREG32(RADEON_GPIOPAD_A)r100_mm_rreg(rdev, (0x019c), 0) | 1; | |||
1215 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL)r100_mm_rreg(rdev, (0x0d64), 0); | |||
1216 | } else if (rdev->family != CHIP_R200) | |||
1217 | disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG)r100_mm_rreg(rdev, (0x0d14), 0); | |||
1218 | else if (rdev->family == CHIP_R200) | |||
1219 | fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL)r100_mm_rreg(rdev, (0x0288), 0); | |||
1220 | ||||
1221 | if (rdev->family >= CHIP_R200) | |||
1222 | disp_tv_out_cntl = RREG32(RADEON_DISP_TV_OUT_CNTL)r100_mm_rreg(rdev, (0x0d6c), 0); | |||
1223 | ||||
1224 | if (is_tv) { | |||
1225 | uint32_t dac_cntl; | |||
1226 | ||||
1227 | dac_cntl = RREG32(RADEON_DAC_CNTL)r100_mm_rreg(rdev, (0x0058), 0); | |||
1228 | dac_cntl &= ~RADEON_DAC_TVO_EN(1 << 10); | |||
1229 | WREG32(RADEON_DAC_CNTL, dac_cntl)r100_mm_wreg(rdev, (0x0058), (dac_cntl), 0); | |||
1230 | ||||
1231 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) | |||
1232 | gpiopad_a = RREG32(RADEON_GPIOPAD_A)r100_mm_rreg(rdev, (0x019c), 0) & ~1; | |||
1233 | ||||
1234 | dac2_cntl = RREG32(RADEON_DAC_CNTL2)r100_mm_rreg(rdev, (0x007c), 0) & ~RADEON_DAC2_DAC2_CLK_SEL(1 << 1); | |||
1235 | if (radeon_crtc->crtc_id == 0) { | |||
1236 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
1237 | disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK(0x03 << 2); | |||
1238 | disp_output_cntl |= (RADEON_DISP_TVDAC_SOURCE_CRTC0x0 | | |||
1239 | RADEON_DISP_TV_SOURCE_CRTC(1 << 16)); | |||
1240 | } | |||
1241 | if (rdev->family >= CHIP_R200) { | |||
1242 | disp_tv_out_cntl &= ~RADEON_DISP_TV_PATH_SRC_CRTC2(1 << 16); | |||
1243 | } else { | |||
1244 | disp_hw_debug |= RADEON_CRT2_DISP1_SEL(1 << 5); | |||
1245 | } | |||
1246 | } else { | |||
1247 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
1248 | disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK(0x03 << 2); | |||
1249 | disp_output_cntl |= RADEON_DISP_TV_SOURCE_CRTC(1 << 16); | |||
1250 | } | |||
1251 | if (rdev->family >= CHIP_R200) { | |||
1252 | disp_tv_out_cntl |= RADEON_DISP_TV_PATH_SRC_CRTC2(1 << 16); | |||
1253 | } else { | |||
1254 | disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL(1 << 5); | |||
1255 | } | |||
1256 | } | |||
1257 | WREG32(RADEON_DAC_CNTL2, dac2_cntl)r100_mm_wreg(rdev, (0x007c), (dac2_cntl), 0); | |||
1258 | } else { | |||
1259 | ||||
1260 | dac2_cntl = RREG32(RADEON_DAC_CNTL2)r100_mm_rreg(rdev, (0x007c), 0) | RADEON_DAC2_DAC2_CLK_SEL(1 << 1); | |||
1261 | ||||
1262 | if (radeon_crtc->crtc_id == 0) { | |||
1263 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
1264 | disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK(0x03 << 2); | |||
1265 | disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC0x0; | |||
1266 | } else if (rdev->family == CHIP_R200) { | |||
1267 | fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK(3 << 10) | | |||
1268 | RADEON_FP2_DVO_RATE_SEL_SDR(1 << 26)); | |||
1269 | } else | |||
1270 | disp_hw_debug |= RADEON_CRT2_DISP1_SEL(1 << 5); | |||
1271 | } else { | |||
1272 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
1273 | disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK(0x03 << 2); | |||
1274 | disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2(0x01 << 2); | |||
1275 | } else if (rdev->family == CHIP_R200) { | |||
1276 | fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK(3 << 10) | | |||
1277 | RADEON_FP2_DVO_RATE_SEL_SDR(1 << 26)); | |||
1278 | fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2(1 << 10); | |||
1279 | } else | |||
1280 | disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL(1 << 5); | |||
1281 | } | |||
1282 | WREG32(RADEON_DAC_CNTL2, dac2_cntl)r100_mm_wreg(rdev, (0x007c), (dac2_cntl), 0); | |||
1283 | } | |||
1284 | ||||
1285 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
1286 | WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1)do { uint32_t tmp_ = r100_mm_rreg(rdev, (0x019c), 0); tmp_ &= (~1); tmp_ |= ((gpiopad_a) & ~(~1)); r100_mm_wreg(rdev, ( 0x019c), (tmp_), 0); } while (0); | |||
1287 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl)r100_mm_wreg(rdev, (0x0d64), (disp_output_cntl), 0); | |||
1288 | } else if (rdev->family != CHIP_R200) | |||
1289 | WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug)r100_mm_wreg(rdev, (0x0d14), (disp_hw_debug), 0); | |||
1290 | else if (rdev->family == CHIP_R200) | |||
1291 | WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl)r100_mm_wreg(rdev, (0x0288), (fp2_gen_cntl), 0); | |||
1292 | ||||
1293 | if (rdev->family >= CHIP_R200) | |||
1294 | WREG32(RADEON_DISP_TV_OUT_CNTL, disp_tv_out_cntl)r100_mm_wreg(rdev, (0x0d6c), (disp_tv_out_cntl), 0); | |||
1295 | ||||
1296 | if (is_tv) | |||
1297 | radeon_legacy_tv_mode_set(encoder, mode, adjusted_mode); | |||
1298 | ||||
1299 | if (rdev->is_atom_bios) | |||
1300 | radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | |||
1301 | else | |||
1302 | radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); | |||
1303 | ||||
1304 | } | |||
1305 | ||||
1306 | static bool_Bool r300_legacy_tv_detect(struct drm_encoder *encoder, | |||
1307 | struct drm_connector *connector) | |||
1308 | { | |||
1309 | struct drm_device *dev = encoder->dev; | |||
1310 | struct radeon_device *rdev = dev->dev_private; | |||
1311 | uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; | |||
1312 | uint32_t disp_output_cntl, gpiopad_a, tmp; | |||
1313 | bool_Bool found = false0; | |||
1314 | ||||
1315 | /* save regs needed */ | |||
1316 | gpiopad_a = RREG32(RADEON_GPIOPAD_A)r100_mm_rreg(rdev, (0x019c), 0); | |||
1317 | dac_cntl2 = RREG32(RADEON_DAC_CNTL2)r100_mm_rreg(rdev, (0x007c), 0); | |||
1318 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL)r100_mm_rreg(rdev, (0x03f8), 0); | |||
1319 | dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL)r100_mm_rreg(rdev, (0x0280), 0); | |||
1320 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL)r100_mm_rreg(rdev, (0x088c), 0); | |||
1321 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL)r100_mm_rreg(rdev, (0x0d64), 0); | |||
1322 | ||||
1323 | WREG32_P(RADEON_GPIOPAD_A, 0, ~1)do { uint32_t tmp_ = r100_mm_rreg(rdev, (0x019c), 0); tmp_ &= (~1); tmp_ |= ((0) & ~(~1)); r100_mm_wreg(rdev, (0x019c) , (tmp_), 0); } while (0); | |||
1324 | ||||
1325 | WREG32(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL)r100_mm_wreg(rdev, (0x007c), ((1 << 1)), 0); | |||
1326 | ||||
1327 | WREG32(RADEON_CRTC2_GEN_CNTL,r100_mm_wreg(rdev, (0x03f8), ((1 << 7) | (1 << 6) ), 0) | |||
1328 | RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT)r100_mm_wreg(rdev, (0x03f8), ((1 << 7) | (1 << 6) ), 0); | |||
1329 | ||||
1330 | tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK(0x03 << 2); | |||
1331 | tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2(0x01 << 2); | |||
1332 | WREG32(RADEON_DISP_OUTPUT_CNTL, tmp)r100_mm_wreg(rdev, (0x0d64), (tmp), 0); | |||
1333 | ||||
1334 | WREG32(RADEON_DAC_EXT_CNTL,r100_mm_wreg(rdev, (0x0280), ((1 << 0) | (1 << 1) | (3 << 6) | (0xec << 8)), 0) | |||
1335 | RADEON_DAC2_FORCE_BLANK_OFF_EN |r100_mm_wreg(rdev, (0x0280), ((1 << 0) | (1 << 1) | (3 << 6) | (0xec << 8)), 0) | |||
1336 | RADEON_DAC2_FORCE_DATA_EN |r100_mm_wreg(rdev, (0x0280), ((1 << 0) | (1 << 1) | (3 << 6) | (0xec << 8)), 0) | |||
1337 | RADEON_DAC_FORCE_DATA_SEL_RGB |r100_mm_wreg(rdev, (0x0280), ((1 << 0) | (1 << 1) | (3 << 6) | (0xec << 8)), 0) | |||
1338 | (0xec << RADEON_DAC_FORCE_DATA_SHIFT))r100_mm_wreg(rdev, (0x0280), ((1 << 0) | (1 << 1) | (3 << 6) | (0xec << 8)), 0); | |||
1339 | ||||
1340 | WREG32(RADEON_TV_DAC_CNTL,r100_mm_wreg(rdev, (0x088c), ((1 << 8) | (8 << 16 ) | (6 << 20)), 0) | |||
1341 | RADEON_TV_DAC_STD_NTSC |r100_mm_wreg(rdev, (0x088c), ((1 << 8) | (8 << 16 ) | (6 << 20)), 0) | |||
1342 | (8 << RADEON_TV_DAC_BGADJ_SHIFT) |r100_mm_wreg(rdev, (0x088c), ((1 << 8) | (8 << 16 ) | (6 << 20)), 0) | |||
1343 | (6 << RADEON_TV_DAC_DACADJ_SHIFT))r100_mm_wreg(rdev, (0x088c), ((1 << 8) | (8 << 16 ) | (6 << 20)), 0); | |||
1344 | ||||
1345 | RREG32(RADEON_TV_DAC_CNTL)r100_mm_rreg(rdev, (0x088c), 0); | |||
1346 | mdelay(4); | |||
1347 | ||||
1348 | WREG32(RADEON_TV_DAC_CNTL,r100_mm_wreg(rdev, (0x088c), ((1 << 0) | (1 << 1) | (1 << 4) | (1 << 8) | (8 << 16) | (6 << 20)), 0) | |||
1349 | RADEON_TV_DAC_NBLANK |r100_mm_wreg(rdev, (0x088c), ((1 << 0) | (1 << 1) | (1 << 4) | (1 << 8) | (8 << 16) | (6 << 20)), 0) | |||
1350 | RADEON_TV_DAC_NHOLD |r100_mm_wreg(rdev, (0x088c), ((1 << 0) | (1 << 1) | (1 << 4) | (1 << 8) | (8 << 16) | (6 << 20)), 0) | |||
1351 | RADEON_TV_MONITOR_DETECT_EN |r100_mm_wreg(rdev, (0x088c), ((1 << 0) | (1 << 1) | (1 << 4) | (1 << 8) | (8 << 16) | (6 << 20)), 0) | |||
1352 | RADEON_TV_DAC_STD_NTSC |r100_mm_wreg(rdev, (0x088c), ((1 << 0) | (1 << 1) | (1 << 4) | (1 << 8) | (8 << 16) | (6 << 20)), 0) | |||
1353 | (8 << RADEON_TV_DAC_BGADJ_SHIFT) |r100_mm_wreg(rdev, (0x088c), ((1 << 0) | (1 << 1) | (1 << 4) | (1 << 8) | (8 << 16) | (6 << 20)), 0) | |||
1354 | (6 << RADEON_TV_DAC_DACADJ_SHIFT))r100_mm_wreg(rdev, (0x088c), ((1 << 0) | (1 << 1) | (1 << 4) | (1 << 8) | (8 << 16) | (6 << 20)), 0); | |||
1355 | ||||
1356 | RREG32(RADEON_TV_DAC_CNTL)r100_mm_rreg(rdev, (0x088c), 0); | |||
1357 | mdelay(6); | |||
1358 | ||||
1359 | tmp = RREG32(RADEON_TV_DAC_CNTL)r100_mm_rreg(rdev, (0x088c), 0); | |||
1360 | if ((tmp & RADEON_TV_DAC_GDACDET(1 << 30)) != 0) { | |||
1361 | found = true1; | |||
1362 | DRM_DEBUG_KMS("S-video TV connection detected\n")__drm_dbg(DRM_UT_KMS, "S-video TV connection detected\n"); | |||
1363 | } else if ((tmp & RADEON_TV_DAC_BDACDET(1 << 31)) != 0) { | |||
1364 | found = true1; | |||
1365 | DRM_DEBUG_KMS("Composite TV connection detected\n")__drm_dbg(DRM_UT_KMS, "Composite TV connection detected\n"); | |||
1366 | } | |||
1367 | ||||
1368 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl)r100_mm_wreg(rdev, (0x088c), (tv_dac_cntl), 0); | |||
1369 | WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl)r100_mm_wreg(rdev, (0x0280), (dac_ext_cntl), 0); | |||
1370 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl)r100_mm_wreg(rdev, (0x03f8), (crtc2_gen_cntl), 0); | |||
1371 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl)r100_mm_wreg(rdev, (0x0d64), (disp_output_cntl), 0); | |||
1372 | WREG32(RADEON_DAC_CNTL2, dac_cntl2)r100_mm_wreg(rdev, (0x007c), (dac_cntl2), 0); | |||
1373 | WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1)do { uint32_t tmp_ = r100_mm_rreg(rdev, (0x019c), 0); tmp_ &= (~1); tmp_ |= ((gpiopad_a) & ~(~1)); r100_mm_wreg(rdev, ( 0x019c), (tmp_), 0); } while (0); | |||
1374 | return found; | |||
1375 | } | |||
1376 | ||||
1377 | static bool_Bool radeon_legacy_tv_detect(struct drm_encoder *encoder, | |||
1378 | struct drm_connector *connector) | |||
1379 | { | |||
1380 | struct drm_device *dev = encoder->dev; | |||
1381 | struct radeon_device *rdev = dev->dev_private; | |||
1382 | uint32_t tv_dac_cntl, dac_cntl2; | |||
1383 | uint32_t config_cntl, tv_pre_dac_mux_cntl, tv_master_cntl, tmp; | |||
1384 | bool_Bool found = false0; | |||
1385 | ||||
1386 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) | |||
1387 | return r300_legacy_tv_detect(encoder, connector); | |||
1388 | ||||
1389 | dac_cntl2 = RREG32(RADEON_DAC_CNTL2)r100_mm_rreg(rdev, (0x007c), 0); | |||
1390 | tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL)r100_mm_rreg(rdev, (0x0800), 0); | |||
1391 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL)r100_mm_rreg(rdev, (0x088c), 0); | |||
1392 | config_cntl = RREG32(RADEON_CONFIG_CNTL)r100_mm_rreg(rdev, (0x00e0), 0); | |||
1393 | tv_pre_dac_mux_cntl = RREG32(RADEON_TV_PRE_DAC_MUX_CNTL)r100_mm_rreg(rdev, (0x0888), 0); | |||
1394 | ||||
1395 | tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL(1 << 1); | |||
1396 | WREG32(RADEON_DAC_CNTL2, tmp)r100_mm_wreg(rdev, (0x007c), (tmp), 0); | |||
1397 | ||||
1398 | tmp = tv_master_cntl | RADEON_TV_ON(1 << 31); | |||
1399 | tmp &= ~(RADEON_TV_ASYNC_RST(1 << 0) | | |||
1400 | RADEON_RESTART_PHASE_FIX(1 << 3) | | |||
1401 | RADEON_CRT_FIFO_CE_EN(1 << 9) | | |||
1402 | RADEON_TV_FIFO_CE_EN(1 << 10) | | |||
1403 | RADEON_RE_SYNC_NOW_SEL_MASK(3 << 14)); | |||
1404 | tmp |= RADEON_TV_FIFO_ASYNC_RST(1 << 4) | RADEON_CRT_ASYNC_RST(1 << 1); | |||
1405 | WREG32(RADEON_TV_MASTER_CNTL, tmp)r100_mm_wreg(rdev, (0x0800), (tmp), 0); | |||
1406 | ||||
1407 | tmp = RADEON_TV_DAC_NBLANK(1 << 0) | RADEON_TV_DAC_NHOLD(1 << 1) | | |||
1408 | RADEON_TV_MONITOR_DETECT_EN(1 << 4) | RADEON_TV_DAC_STD_NTSC(1 << 8) | | |||
1409 | (8 << RADEON_TV_DAC_BGADJ_SHIFT16); | |||
1410 | ||||
1411 | if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK(0xf << 16)) | |||
1412 | tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT20); | |||
1413 | else | |||
1414 | tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT20); | |||
1415 | WREG32(RADEON_TV_DAC_CNTL, tmp)r100_mm_wreg(rdev, (0x088c), (tmp), 0); | |||
1416 | ||||
1417 | tmp = RADEON_C_GRN_EN(1 << 1) | RADEON_CMP_BLU_EN(1 << 2) | | |||
1418 | RADEON_RED_MX_FORCE_DAC_DATA(6 << 4) | | |||
1419 | RADEON_GRN_MX_FORCE_DAC_DATA(6 << 8) | | |||
1420 | RADEON_BLU_MX_FORCE_DAC_DATA(6 << 12) | | |||
1421 | (0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT16); | |||
1422 | WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tmp)r100_mm_wreg(rdev, (0x0888), (tmp), 0); | |||
1423 | ||||
1424 | mdelay(3); | |||
1425 | tmp = RREG32(RADEON_TV_DAC_CNTL)r100_mm_rreg(rdev, (0x088c), 0); | |||
1426 | if (tmp & RADEON_TV_DAC_GDACDET(1 << 30)) { | |||
1427 | found = true1; | |||
1428 | DRM_DEBUG_KMS("S-video TV connection detected\n")__drm_dbg(DRM_UT_KMS, "S-video TV connection detected\n"); | |||
1429 | } else if ((tmp & RADEON_TV_DAC_BDACDET(1 << 31)) != 0) { | |||
1430 | found = true1; | |||
1431 | DRM_DEBUG_KMS("Composite TV connection detected\n")__drm_dbg(DRM_UT_KMS, "Composite TV connection detected\n"); | |||
1432 | } | |||
1433 | ||||
1434 | WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl)r100_mm_wreg(rdev, (0x0888), (tv_pre_dac_mux_cntl), 0); | |||
1435 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl)r100_mm_wreg(rdev, (0x088c), (tv_dac_cntl), 0); | |||
1436 | WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl)r100_mm_wreg(rdev, (0x0800), (tv_master_cntl), 0); | |||
1437 | WREG32(RADEON_DAC_CNTL2, dac_cntl2)r100_mm_wreg(rdev, (0x007c), (dac_cntl2), 0); | |||
1438 | return found; | |||
1439 | } | |||
1440 | ||||
1441 | static bool_Bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder, | |||
1442 | struct drm_connector *connector) | |||
1443 | { | |||
1444 | struct drm_device *dev = encoder->dev; | |||
1445 | struct radeon_device *rdev = dev->dev_private; | |||
1446 | uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl; | |||
1447 | uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c; | |||
1448 | uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f; | |||
1449 | uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp; | |||
1450 | uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid; | |||
1451 | bool_Bool found = false0; | |||
1452 | int i; | |||
1453 | ||||
1454 | /* save the regs we need */ | |||
1455 | gpio_monid = RREG32(RADEON_GPIO_MONID)r100_mm_rreg(rdev, (0x0068), 0); | |||
1456 | fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL)r100_mm_rreg(rdev, (0x0288), 0); | |||
1457 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL)r100_mm_rreg(rdev, (0x0d64), 0); | |||
1458 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL)r100_mm_rreg(rdev, (0x03f8), 0); | |||
1459 | disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A)r100_mm_rreg(rdev, (0x0d80), 0); | |||
1460 | disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B)r100_mm_rreg(rdev, (0x0d84), 0); | |||
1461 | disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C)r100_mm_rreg(rdev, (0x0d88), 0); | |||
1462 | disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D)r100_mm_rreg(rdev, (0x0d8c), 0); | |||
1463 | disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E)r100_mm_rreg(rdev, (0x0d90), 0); | |||
1464 | disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F)r100_mm_rreg(rdev, (0x0d98), 0); | |||
1465 | crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP)r100_mm_rreg(rdev, (0x0300), 0); | |||
1466 | crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP)r100_mm_rreg(rdev, (0x0308), 0); | |||
1467 | crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID)r100_mm_rreg(rdev, (0x0304), 0); | |||
1468 | crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID)r100_mm_rreg(rdev, (0x030c), 0); | |||
1469 | ||||
1470 | tmp = RREG32(RADEON_GPIO_MONID)r100_mm_rreg(rdev, (0x0068), 0); | |||
1471 | tmp &= ~RADEON_GPIO_A_0(1 << 0); | |||
1472 | WREG32(RADEON_GPIO_MONID, tmp)r100_mm_wreg(rdev, (0x0068), (tmp), 0); | |||
1473 | ||||
1474 | WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON |r100_mm_wreg(rdev, (0x0288), (((1 << 2) | (1 << 3 ) | (3 << 10) | (1 << 25) | (1 << 27))), 0) | |||
1475 | RADEON_FP2_PANEL_FORMAT |r100_mm_wreg(rdev, (0x0288), (((1 << 2) | (1 << 3 ) | (3 << 10) | (1 << 25) | (1 << 27))), 0) | |||
1476 | R200_FP2_SOURCE_SEL_TRANS_UNIT |r100_mm_wreg(rdev, (0x0288), (((1 << 2) | (1 << 3 ) | (3 << 10) | (1 << 25) | (1 << 27))), 0) | |||
1477 | RADEON_FP2_DVO_EN |r100_mm_wreg(rdev, (0x0288), (((1 << 2) | (1 << 3 ) | (3 << 10) | (1 << 25) | (1 << 27))), 0) | |||
1478 | R200_FP2_DVO_RATE_SEL_SDR))r100_mm_wreg(rdev, (0x0288), (((1 << 2) | (1 << 3 ) | (3 << 10) | (1 << 25) | (1 << 27))), 0); | |||
1479 | ||||
1480 | WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX |r100_mm_wreg(rdev, (0x0d64), ((0x02 | (0x01 << 4))), 0) | |||
1481 | RADEON_DISP_TRANS_MATRIX_GRAPHICS))r100_mm_wreg(rdev, (0x0d64), ((0x02 | (0x01 << 4))), 0); | |||
1482 | ||||
1483 | WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN |r100_mm_wreg(rdev, (0x03f8), (((1 << 25) | (1 << 26 ))), 0) | |||
1484 | RADEON_CRTC2_DISP_REQ_EN_B))r100_mm_wreg(rdev, (0x03f8), (((1 << 25) | (1 << 26 ))), 0); | |||
1485 | ||||
1486 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000)r100_mm_wreg(rdev, (0x0d80), (0x00000000), 0); | |||
1487 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0)r100_mm_wreg(rdev, (0x0d84), (0x000003f0), 0); | |||
1488 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000)r100_mm_wreg(rdev, (0x0d88), (0x00000000), 0); | |||
1489 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0)r100_mm_wreg(rdev, (0x0d8c), (0x000003f0), 0); | |||
1490 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000)r100_mm_wreg(rdev, (0x0d90), (0x00000000), 0); | |||
1491 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0)r100_mm_wreg(rdev, (0x0d98), (0x000003f0), 0); | |||
1492 | ||||
1493 | WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008)r100_mm_wreg(rdev, (0x0300), (0x01000008), 0); | |||
1494 | WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800)r100_mm_wreg(rdev, (0x0304), (0x00000800), 0); | |||
1495 | WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001)r100_mm_wreg(rdev, (0x0308), (0x00080001), 0); | |||
1496 | WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080)r100_mm_wreg(rdev, (0x030c), (0x00000080), 0); | |||
1497 | ||||
1498 | for (i = 0; i < 200; i++) { | |||
1499 | tmp = RREG32(RADEON_GPIO_MONID)r100_mm_rreg(rdev, (0x0068), 0); | |||
1500 | if (tmp & RADEON_GPIO_Y_0(1 << 8)) | |||
1501 | found = true1; | |||
1502 | ||||
1503 | if (found) | |||
1504 | break; | |||
1505 | ||||
1506 | if (!drm_can_sleep()) | |||
1507 | mdelay(1); | |||
1508 | else | |||
1509 | drm_msleep(1)mdelay(1); | |||
1510 | } | |||
1511 | ||||
1512 | /* restore the regs we used */ | |||
1513 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a)r100_mm_wreg(rdev, (0x0d80), (disp_lin_trans_grph_a), 0); | |||
1514 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b)r100_mm_wreg(rdev, (0x0d84), (disp_lin_trans_grph_b), 0); | |||
1515 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c)r100_mm_wreg(rdev, (0x0d88), (disp_lin_trans_grph_c), 0); | |||
1516 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d)r100_mm_wreg(rdev, (0x0d8c), (disp_lin_trans_grph_d), 0); | |||
1517 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e)r100_mm_wreg(rdev, (0x0d90), (disp_lin_trans_grph_e), 0); | |||
1518 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f)r100_mm_wreg(rdev, (0x0d98), (disp_lin_trans_grph_f), 0); | |||
1519 | WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp)r100_mm_wreg(rdev, (0x0300), (crtc2_h_total_disp), 0); | |||
1520 | WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp)r100_mm_wreg(rdev, (0x0308), (crtc2_v_total_disp), 0); | |||
1521 | WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid)r100_mm_wreg(rdev, (0x0304), (crtc2_h_sync_strt_wid), 0); | |||
1522 | WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid)r100_mm_wreg(rdev, (0x030c), (crtc2_v_sync_strt_wid), 0); | |||
1523 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl)r100_mm_wreg(rdev, (0x03f8), (crtc2_gen_cntl), 0); | |||
1524 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl)r100_mm_wreg(rdev, (0x0d64), (disp_output_cntl), 0); | |||
1525 | WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl)r100_mm_wreg(rdev, (0x0288), (fp2_gen_cntl), 0); | |||
1526 | WREG32(RADEON_GPIO_MONID, gpio_monid)r100_mm_wreg(rdev, (0x0068), (gpio_monid), 0); | |||
1527 | ||||
1528 | return found; | |||
1529 | } | |||
1530 | ||||
1531 | static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, | |||
1532 | struct drm_connector *connector) | |||
1533 | { | |||
1534 | struct drm_device *dev = encoder->dev; | |||
1535 | struct radeon_device *rdev = dev->dev_private; | |||
1536 | uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl; | |||
1537 | uint32_t gpiopad_a = 0, pixclks_cntl, tmp; | |||
1538 | uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0; | |||
1539 | enum drm_connector_status found = connector_status_disconnected; | |||
1540 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
1541 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | |||
1542 | bool_Bool color = true1; | |||
1543 | struct drm_crtc *crtc; | |||
1544 | ||||
1545 | /* find out if crtc2 is in use or if this encoder is using it */ | |||
1546 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)for (crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->head ) *__mptr = ((&dev->mode_config.crtc_list)->next); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof(__typeof (*crtc), head) );}); &crtc->head != (&dev->mode_config .crtc_list); crtc = ({ const __typeof( ((__typeof(*crtc) *)0) ->head ) *__mptr = (crtc->head.next); (__typeof(*crtc) * )( (char *)__mptr - __builtin_offsetof(__typeof(*crtc), head) );})) { | |||
1547 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc)({ const __typeof( ((struct radeon_crtc *)0)->base ) *__mptr = (crtc); (struct radeon_crtc *)( (char *)__mptr - __builtin_offsetof (struct radeon_crtc, base) );}); | |||
1548 | if ((radeon_crtc->crtc_id == 1) && crtc->enabled) { | |||
1549 | if (encoder->crtc != crtc) { | |||
1550 | return connector_status_disconnected; | |||
1551 | } | |||
1552 | } | |||
1553 | } | |||
1554 | ||||
1555 | if (connector->connector_type == DRM_MODE_CONNECTOR_SVIDEO6 || | |||
1556 | connector->connector_type == DRM_MODE_CONNECTOR_Composite5 || | |||
1557 | connector->connector_type == DRM_MODE_CONNECTOR_9PinDIN9) { | |||
1558 | bool_Bool tv_detect; | |||
1559 | ||||
1560 | if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT((0x1L << 0x00000002 )))) | |||
1561 | return connector_status_disconnected; | |||
1562 | ||||
1563 | tv_detect = radeon_legacy_tv_detect(encoder, connector); | |||
1564 | if (tv_detect && tv_dac) | |||
1565 | found = connector_status_connected; | |||
1566 | return found; | |||
1567 | } | |||
1568 | ||||
1569 | /* don't probe if the encoder is being used for something else not CRT related */ | |||
1570 | if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_CRT_SUPPORT((0x1L << 0x00000000 ) | (0x1L << 0x00000004 )))) { | |||
1571 | DRM_INFO("not detecting due to %08x\n", radeon_encoder->active_device)printk("\0016" "[" "drm" "] " "not detecting due to %08x\n", radeon_encoder ->active_device); | |||
1572 | return connector_status_disconnected; | |||
1573 | } | |||
1574 | ||||
1575 | /* R200 uses an external DAC for secondary DAC */ | |||
1576 | if (rdev->family == CHIP_R200) { | |||
1577 | if (radeon_legacy_ext_dac_detect(encoder, connector)) | |||
1578 | found = connector_status_connected; | |||
1579 | return found; | |||
1580 | } | |||
1581 | ||||
1582 | /* save the regs we need */ | |||
1583 | pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL)rdev->pll_rreg(rdev, (0x002d)); | |||
1584 | ||||
1585 | if (rdev->flags & RADEON_SINGLE_CRTC) { | |||
1586 | crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL)r100_mm_rreg(rdev, (0x0054), 0); | |||
1587 | } else { | |||
1588 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
1589 | gpiopad_a = RREG32(RADEON_GPIOPAD_A)r100_mm_rreg(rdev, (0x019c), 0); | |||
1590 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL)r100_mm_rreg(rdev, (0x0d64), 0); | |||
1591 | } else { | |||
1592 | disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG)r100_mm_rreg(rdev, (0x0d14), 0); | |||
1593 | } | |||
1594 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL)r100_mm_rreg(rdev, (0x03f8), 0); | |||
1595 | } | |||
1596 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL)r100_mm_rreg(rdev, (0x088c), 0); | |||
1597 | dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL)r100_mm_rreg(rdev, (0x0280), 0); | |||
1598 | dac_cntl2 = RREG32(RADEON_DAC_CNTL2)r100_mm_rreg(rdev, (0x007c), 0); | |||
1599 | ||||
1600 | tmp = pixclks_cntl & ~(RADEON_PIX2CLK_ALWAYS_ONb(1<<6) | |||
1601 | | RADEON_PIX2CLK_DAC_ALWAYS_ONb(1<<7)); | |||
1602 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp)rdev->pll_wreg(rdev, (0x002d), (tmp)); | |||
1603 | ||||
1604 | if (rdev->flags & RADEON_SINGLE_CRTC) { | |||
1605 | tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON(1 << 15); | |||
1606 | WREG32(RADEON_CRTC_EXT_CNTL, tmp)r100_mm_wreg(rdev, (0x0054), (tmp), 0); | |||
1607 | } else { | |||
1608 | tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK(0xf << 8); | |||
1609 | tmp |= RADEON_CRTC2_CRT2_ON(1 << 7) | | |||
1610 | (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT8); | |||
1611 | WREG32(RADEON_CRTC2_GEN_CNTL, tmp)r100_mm_wreg(rdev, (0x03f8), (tmp), 0); | |||
1612 | ||||
1613 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
1614 | WREG32_P(RADEON_GPIOPAD_A, 1, ~1)do { uint32_t tmp_ = r100_mm_rreg(rdev, (0x019c), 0); tmp_ &= (~1); tmp_ |= ((1) & ~(~1)); r100_mm_wreg(rdev, (0x019c) , (tmp_), 0); } while (0); | |||
1615 | tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK(0x03 << 2); | |||
1616 | tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2(0x01 << 2); | |||
1617 | WREG32(RADEON_DISP_OUTPUT_CNTL, tmp)r100_mm_wreg(rdev, (0x0d64), (tmp), 0); | |||
1618 | } else { | |||
1619 | tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL(1 << 5); | |||
1620 | WREG32(RADEON_DISP_HW_DEBUG, tmp)r100_mm_wreg(rdev, (0x0d14), (tmp), 0); | |||
1621 | } | |||
1622 | } | |||
1623 | ||||
1624 | tmp = RADEON_TV_DAC_NBLANK(1 << 0) | | |||
1625 | RADEON_TV_DAC_NHOLD(1 << 1) | | |||
1626 | RADEON_TV_MONITOR_DETECT_EN(1 << 4) | | |||
1627 | RADEON_TV_DAC_STD_PS2(2 << 8); | |||
1628 | ||||
1629 | WREG32(RADEON_TV_DAC_CNTL, tmp)r100_mm_wreg(rdev, (0x088c), (tmp), 0); | |||
1630 | ||||
1631 | tmp = RADEON_DAC2_FORCE_BLANK_OFF_EN(1 << 0) | | |||
1632 | RADEON_DAC2_FORCE_DATA_EN(1 << 1); | |||
1633 | ||||
1634 | if (color) | |||
1635 | tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB(3 << 6); | |||
1636 | else | |||
1637 | tmp |= RADEON_DAC_FORCE_DATA_SEL_G(1 << 6); | |||
1638 | ||||
1639 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) | |||
1640 | tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT8); | |||
1641 | else | |||
1642 | tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT8); | |||
1643 | ||||
1644 | WREG32(RADEON_DAC_EXT_CNTL, tmp)r100_mm_wreg(rdev, (0x0280), (tmp), 0); | |||
1645 | ||||
1646 | tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL(1 << 1) | RADEON_DAC2_CMP_EN(1 << 7); | |||
1647 | WREG32(RADEON_DAC_CNTL2, tmp)r100_mm_wreg(rdev, (0x007c), (tmp), 0); | |||
1648 | ||||
1649 | mdelay(10); | |||
1650 | ||||
1651 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
1652 | if (RREG32(RADEON_DAC_CNTL2)r100_mm_rreg(rdev, (0x007c), 0) & RADEON_DAC2_CMP_OUT_B(1 << 10)) | |||
1653 | found = connector_status_connected; | |||
1654 | } else { | |||
1655 | if (RREG32(RADEON_DAC_CNTL2)r100_mm_rreg(rdev, (0x007c), 0) & RADEON_DAC2_CMP_OUTPUT(1 << 11)) | |||
1656 | found = connector_status_connected; | |||
1657 | } | |||
1658 | ||||
1659 | /* restore regs we used */ | |||
1660 | WREG32(RADEON_DAC_CNTL2, dac_cntl2)r100_mm_wreg(rdev, (0x007c), (dac_cntl2), 0); | |||
1661 | WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl)r100_mm_wreg(rdev, (0x0280), (dac_ext_cntl), 0); | |||
1662 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl)r100_mm_wreg(rdev, (0x088c), (tv_dac_cntl), 0); | |||
1663 | ||||
1664 | if (rdev->flags & RADEON_SINGLE_CRTC) { | |||
1665 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl)r100_mm_wreg(rdev, (0x0054), (crtc_ext_cntl), 0); | |||
1666 | } else { | |||
1667 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl)r100_mm_wreg(rdev, (0x03f8), (crtc2_gen_cntl), 0); | |||
1668 | if (ASIC_IS_R300(rdev)((rdev->family == CHIP_R300) || (rdev->family == CHIP_RV350 ) || (rdev->family == CHIP_R350) || (rdev->family == CHIP_RV380 ) || (rdev->family == CHIP_R420) || (rdev->family == CHIP_R423 ) || (rdev->family == CHIP_RV410) || (rdev->family == CHIP_RS400 ) || (rdev->family == CHIP_RS480))) { | |||
1669 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl)r100_mm_wreg(rdev, (0x0d64), (disp_output_cntl), 0); | |||
1670 | WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1)do { uint32_t tmp_ = r100_mm_rreg(rdev, (0x019c), 0); tmp_ &= (~1); tmp_ |= ((gpiopad_a) & ~(~1)); r100_mm_wreg(rdev, ( 0x019c), (tmp_), 0); } while (0); | |||
1671 | } else { | |||
1672 | WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug)r100_mm_wreg(rdev, (0x0d14), (disp_hw_debug), 0); | |||
1673 | } | |||
1674 | } | |||
1675 | ||||
1676 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl)rdev->pll_wreg(rdev, (0x002d), (pixclks_cntl)); | |||
1677 | ||||
1678 | return found; | |||
1679 | ||||
1680 | } | |||
1681 | ||||
1682 | static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = { | |||
1683 | .dpms = radeon_legacy_tv_dac_dpms, | |||
1684 | .mode_fixup = radeon_legacy_mode_fixup, | |||
1685 | .prepare = radeon_legacy_tv_dac_prepare, | |||
1686 | .mode_set = radeon_legacy_tv_dac_mode_set, | |||
1687 | .commit = radeon_legacy_tv_dac_commit, | |||
1688 | .detect = radeon_legacy_tv_dac_detect, | |||
1689 | .disable = radeon_legacy_encoder_disable, | |||
1690 | }; | |||
1691 | ||||
1692 | ||||
1693 | static const struct drm_encoder_funcs radeon_legacy_tv_dac_enc_funcs = { | |||
1694 | .destroy = radeon_enc_destroy, | |||
1695 | }; | |||
1696 | ||||
1697 | ||||
1698 | static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon_encoder *encoder) | |||
1699 | { | |||
1700 | struct drm_device *dev = encoder->base.dev; | |||
1701 | struct radeon_device *rdev = dev->dev_private; | |||
1702 | struct radeon_encoder_int_tmds *tmds = NULL((void *)0); | |||
1703 | bool_Bool ret; | |||
1704 | ||||
1705 | tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL(0x0001 | 0x0004)); | |||
1706 | ||||
1707 | if (!tmds) | |||
1708 | return NULL((void *)0); | |||
1709 | ||||
1710 | if (rdev->is_atom_bios) | |||
1711 | ret = radeon_atombios_get_tmds_info(encoder, tmds); | |||
1712 | else | |||
1713 | ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds); | |||
1714 | ||||
1715 | if (!ret) | |||
1716 | radeon_legacy_get_tmds_info_from_table(encoder, tmds); | |||
1717 | ||||
1718 | return tmds; | |||
1719 | } | |||
1720 | ||||
1721 | static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct radeon_encoder *encoder) | |||
1722 | { | |||
1723 | struct drm_device *dev = encoder->base.dev; | |||
1724 | struct radeon_device *rdev = dev->dev_private; | |||
1725 | struct radeon_encoder_ext_tmds *tmds = NULL((void *)0); | |||
1726 | bool_Bool ret; | |||
1727 | ||||
1728 | if (rdev->is_atom_bios) | |||
1729 | return NULL((void *)0); | |||
1730 | ||||
1731 | tmds = kzalloc(sizeof(struct radeon_encoder_ext_tmds), GFP_KERNEL(0x0001 | 0x0004)); | |||
1732 | ||||
1733 | if (!tmds) | |||
1734 | return NULL((void *)0); | |||
1735 | ||||
1736 | ret = radeon_legacy_get_ext_tmds_info_from_combios(encoder, tmds); | |||
1737 | ||||
1738 | if (!ret) | |||
1739 | radeon_legacy_get_ext_tmds_info_from_table(encoder, tmds); | |||
1740 | ||||
1741 | return tmds; | |||
1742 | } | |||
1743 | ||||
1744 | void | |||
1745 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) | |||
1746 | { | |||
1747 | struct radeon_device *rdev = dev->dev_private; | |||
1748 | struct drm_encoder *encoder; | |||
1749 | struct radeon_encoder *radeon_encoder; | |||
1750 | ||||
1751 | /* see if we already added it */ | |||
1752 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)for (encoder = ({ const __typeof( ((__typeof(*encoder) *)0)-> head ) *__mptr = ((&dev->mode_config.encoder_list)-> next); (__typeof(*encoder) *)( (char *)__mptr - __builtin_offsetof (__typeof(*encoder), head) );}); &encoder->head != (& dev->mode_config.encoder_list); encoder = ({ const __typeof ( ((__typeof(*encoder) *)0)->head ) *__mptr = (encoder-> head.next); (__typeof(*encoder) *)( (char *)__mptr - __builtin_offsetof (__typeof(*encoder), head) );})) { | |||
| ||||
1753 | radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
1754 | if (radeon_encoder->encoder_enum == encoder_enum) { | |||
1755 | radeon_encoder->devices |= supported_device; | |||
1756 | return; | |||
1757 | } | |||
1758 | ||||
1759 | } | |||
1760 | ||||
1761 | /* add a new one */ | |||
1762 | radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL(0x0001 | 0x0004)); | |||
1763 | if (!radeon_encoder) | |||
1764 | return; | |||
1765 | ||||
1766 | encoder = &radeon_encoder->base; | |||
1767 | if (rdev->flags & RADEON_SINGLE_CRTC) | |||
1768 | encoder->possible_crtcs = 0x1; | |||
1769 | else | |||
1770 | encoder->possible_crtcs = 0x3; | |||
1771 | ||||
1772 | radeon_encoder->enc_priv = NULL((void *)0); | |||
1773 | ||||
1774 | radeon_encoder->encoder_enum = encoder_enum; | |||
1775 | radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK0x00FF) >> OBJECT_ID_SHIFT0x00; | |||
1776 | radeon_encoder->devices = supported_device; | |||
1777 | radeon_encoder->rmx_type = RMX_OFF; | |||
1778 | ||||
1779 | switch (radeon_encoder->encoder_id) { | |||
1780 | case ENCODER_OBJECT_ID_INTERNAL_LVDS0x01: | |||
1781 | encoder->possible_crtcs = 0x1; | |||
1782 | drm_encoder_init(dev, encoder, &radeon_legacy_lvds_enc_funcs, | |||
1783 | DRM_MODE_ENCODER_LVDS3, NULL((void *)0)); | |||
1784 | drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs); | |||
1785 | if (rdev->is_atom_bios) | |||
1786 | radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); | |||
1787 | else | |||
1788 | radeon_encoder->enc_priv = radeon_combios_get_lvds_info(radeon_encoder); | |||
1789 | radeon_encoder->rmx_type = RMX_FULL; | |||
1790 | break; | |||
1791 | case ENCODER_OBJECT_ID_INTERNAL_TMDS10x02: | |||
1792 | drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs, | |||
1793 | DRM_MODE_ENCODER_TMDS2, NULL((void *)0)); | |||
1794 | drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs); | |||
1795 | radeon_encoder->enc_priv = radeon_legacy_get_tmds_info(radeon_encoder); | |||
1796 | break; | |||
1797 | case ENCODER_OBJECT_ID_INTERNAL_DAC10x04: | |||
1798 | drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, | |||
1799 | DRM_MODE_ENCODER_DAC1, NULL((void *)0)); | |||
1800 | drm_encoder_helper_add(encoder, &radeon_legacy_primary_dac_helper_funcs); | |||
1801 | if (rdev->is_atom_bios) | |||
1802 | radeon_encoder->enc_priv = radeon_atombios_get_primary_dac_info(radeon_encoder); | |||
1803 | else | |||
1804 | radeon_encoder->enc_priv = radeon_combios_get_primary_dac_info(radeon_encoder); | |||
1805 | break; | |||
1806 | case ENCODER_OBJECT_ID_INTERNAL_DAC20x05: | |||
1807 | drm_encoder_init(dev, encoder, &radeon_legacy_tv_dac_enc_funcs, | |||
1808 | DRM_MODE_ENCODER_TVDAC4, NULL((void *)0)); | |||
1809 | drm_encoder_helper_add(encoder, &radeon_legacy_tv_dac_helper_funcs); | |||
1810 | if (rdev->is_atom_bios) | |||
1811 | radeon_encoder->enc_priv = radeon_atombios_get_tv_dac_info(radeon_encoder); | |||
1812 | else | |||
1813 | radeon_encoder->enc_priv = radeon_combios_get_tv_dac_info(radeon_encoder); | |||
1814 | break; | |||
1815 | case ENCODER_OBJECT_ID_INTERNAL_DVO10x0B: | |||
1816 | drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, | |||
1817 | DRM_MODE_ENCODER_TMDS2, NULL((void *)0)); | |||
1818 | drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs); | |||
1819 | if (!rdev->is_atom_bios) | |||
1820 | radeon_encoder->enc_priv = radeon_legacy_get_ext_tmds_info(radeon_encoder); | |||
1821 | break; | |||
1822 | } | |||
1823 | } | |||
|
1 | /* Public domain. */ |
2 | |
3 | #ifndef _LINUX_SLAB_H |
4 | #define _LINUX_SLAB_H |
5 | |
6 | #include <sys/types.h> |
7 | #include <sys/malloc.h> |
8 | |
9 | #include <linux/types.h> |
10 | #include <linux/workqueue.h> |
11 | #include <linux/gfp.h> |
12 | |
13 | #include <linux/processor.h> /* for CACHELINESIZE */ |
14 | |
15 | static inline void * |
16 | kmalloc(size_t size, int flags) |
17 | { |
18 | return malloc(size, M_DRM145, flags); |
19 | } |
20 | |
21 | static inline void * |
22 | kmalloc_array(size_t n, size_t size, int flags) |
23 | { |
24 | if (n != 0 && SIZE_MAX0xffffffffffffffffUL / n < size) |
25 | return NULL((void *)0); |
26 | return malloc(n * size, M_DRM145, flags); |
27 | } |
28 | |
29 | static inline void * |
30 | kcalloc(size_t n, size_t size, int flags) |
31 | { |
32 | if (n != 0 && SIZE_MAX0xffffffffffffffffUL / n < size) |
33 | return NULL((void *)0); |
34 | return malloc(n * size, M_DRM145, flags | M_ZERO0x0008); |
35 | } |
36 | |
37 | static inline void * |
38 | kzalloc(size_t size, int flags) |
39 | { |
40 | return malloc(size, M_DRM145, flags | M_ZERO0x0008); |
41 | } |
42 | |
43 | static inline void |
44 | kfree(const void *objp) |
45 | { |
46 | free((void *)objp, M_DRM145, 0); |
47 | } |
48 | |
49 | #endif |