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