Rev 1129 | Rev 1182 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1129 | Rev 1179 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * Copyright 2007-8 Advanced Micro Devices, Inc. |
2 | * Copyright 2007-8 Advanced Micro Devices, Inc. |
3 | * Copyright 2008 Red Hat Inc. |
3 | * Copyright 2008 Red Hat Inc. |
4 | * |
4 | * |
5 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * Permission is hereby granted, free of charge, to any person obtaining a |
6 | * copy of this software and associated documentation files (the "Software"), |
6 | * copy of this software and associated documentation files (the "Software"), |
7 | * to deal in the Software without restriction, including without limitation |
7 | * to deal in the Software without restriction, including without limitation |
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
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 |
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: |
10 | * Software is furnished to do so, subject to the following conditions: |
11 | * |
11 | * |
12 | * The above copyright notice and this permission notice shall be included in |
12 | * The above copyright notice and this permission notice shall be included in |
13 | * all copies or substantial portions of the Software. |
13 | * all copies or substantial portions of the Software. |
14 | * |
14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
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, |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
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 |
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, |
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 |
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
21 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | * OTHER DEALINGS IN THE SOFTWARE. |
22 | * |
22 | * |
23 | * Authors: Dave Airlie |
23 | * Authors: Dave Airlie |
24 | * Alex Deucher |
24 | * Alex Deucher |
25 | */ |
25 | */ |
26 | #include |
26 | #include |
27 | #include |
27 | #include |
28 | #include "radeon_drm.h" |
28 | #include |
29 | #include "radeon_fixed.h" |
29 | #include "radeon_fixed.h" |
30 | #include "radeon.h" |
30 | #include "radeon.h" |
31 | #include "atom.h" |
31 | #include "atom.h" |
32 | #include "atom-bits.h" |
32 | #include "atom-bits.h" |
- | 33 | ||
- | 34 | /* evil but including atombios.h is much worse */ |
|
- | 35 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, |
|
- | 36 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, |
|
- | 37 | int32_t *pixel_clock); |
|
- | 38 | static void atombios_overscan_setup(struct drm_crtc *crtc, |
|
- | 39 | struct drm_display_mode *mode, |
|
- | 40 | struct drm_display_mode *adjusted_mode) |
|
- | 41 | { |
|
- | 42 | struct drm_device *dev = crtc->dev; |
|
- | 43 | struct radeon_device *rdev = dev->dev_private; |
|
- | 44 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
|
- | 45 | SET_CRTC_OVERSCAN_PS_ALLOCATION args; |
|
- | 46 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan); |
|
- | 47 | int a1, a2; |
|
- | 48 | ||
- | 49 | memset(&args, 0, sizeof(args)); |
|
- | 50 | ||
- | 51 | args.usOverscanRight = 0; |
|
- | 52 | args.usOverscanLeft = 0; |
|
- | 53 | args.usOverscanBottom = 0; |
|
- | 54 | args.usOverscanTop = 0; |
|
- | 55 | args.ucCRTC = radeon_crtc->crtc_id; |
|
- | 56 | ||
- | 57 | switch (radeon_crtc->rmx_type) { |
|
- | 58 | case RMX_CENTER: |
|
- | 59 | args.usOverscanTop = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; |
|
- | 60 | args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; |
|
- | 61 | args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; |
|
- | 62 | args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; |
|
- | 63 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
- | 64 | break; |
|
- | 65 | case RMX_ASPECT: |
|
- | 66 | a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; |
|
- | 67 | a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay; |
|
- | 68 | ||
- | 69 | if (a1 > a2) { |
|
- | 70 | args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; |
|
- | 71 | args.usOverscanRight = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; |
|
- | 72 | } else if (a2 > a1) { |
|
- | 73 | args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; |
|
- | 74 | args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; |
|
- | 75 | } |
|
- | 76 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
- | 77 | break; |
|
- | 78 | case RMX_FULL: |
|
- | 79 | default: |
|
- | 80 | args.usOverscanRight = 0; |
|
- | 81 | args.usOverscanLeft = 0; |
|
- | 82 | args.usOverscanBottom = 0; |
|
- | 83 | args.usOverscanTop = 0; |
|
- | 84 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
- | 85 | break; |
|
- | 86 | } |
|
- | 87 | } |
|
- | 88 | ||
- | 89 | static void atombios_scaler_setup(struct drm_crtc *crtc) |
|
- | 90 | { |
|
- | 91 | struct drm_device *dev = crtc->dev; |
|
- | 92 | struct radeon_device *rdev = dev->dev_private; |
|
- | 93 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
|
- | 94 | ENABLE_SCALER_PS_ALLOCATION args; |
|
- | 95 | int index = GetIndexIntoMasterTable(COMMAND, EnableScaler); |
|
- | 96 | ||
- | 97 | /* fixme - fill in enc_priv for atom dac */ |
|
- | 98 | enum radeon_tv_std tv_std = TV_STD_NTSC; |
|
- | 99 | bool is_tv = false, is_cv = false; |
|
- | 100 | struct drm_encoder *encoder; |
|
- | 101 | ||
- | 102 | if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id) |
|
- | 103 | return; |
|
- | 104 | ||
- | 105 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
|
- | 106 | /* find tv std */ |
|
- | 107 | if (encoder->crtc == crtc) { |
|
- | 108 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
|
- | 109 | if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { |
|
- | 110 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; |
|
- | 111 | tv_std = tv_dac->tv_std; |
|
- | 112 | is_tv = true; |
|
- | 113 | } |
|
- | 114 | } |
|
- | 115 | } |
|
- | 116 | ||
- | 117 | memset(&args, 0, sizeof(args)); |
|
- | 118 | ||
- | 119 | args.ucScaler = radeon_crtc->crtc_id; |
|
- | 120 | ||
- | 121 | if (is_tv) { |
|
- | 122 | switch (tv_std) { |
|
- | 123 | case TV_STD_NTSC: |
|
- | 124 | default: |
|
- | 125 | args.ucTVStandard = ATOM_TV_NTSC; |
|
- | 126 | break; |
|
- | 127 | case TV_STD_PAL: |
|
- | 128 | args.ucTVStandard = ATOM_TV_PAL; |
|
- | 129 | break; |
|
- | 130 | case TV_STD_PAL_M: |
|
- | 131 | args.ucTVStandard = ATOM_TV_PALM; |
|
- | 132 | break; |
|
- | 133 | case TV_STD_PAL_60: |
|
- | 134 | args.ucTVStandard = ATOM_TV_PAL60; |
|
- | 135 | break; |
|
- | 136 | case TV_STD_NTSC_J: |
|
- | 137 | args.ucTVStandard = ATOM_TV_NTSCJ; |
|
- | 138 | break; |
|
- | 139 | case TV_STD_SCART_PAL: |
|
- | 140 | args.ucTVStandard = ATOM_TV_PAL; /* ??? */ |
|
- | 141 | break; |
|
- | 142 | case TV_STD_SECAM: |
|
- | 143 | args.ucTVStandard = ATOM_TV_SECAM; |
|
- | 144 | break; |
|
- | 145 | case TV_STD_PAL_CN: |
|
- | 146 | args.ucTVStandard = ATOM_TV_PALCN; |
|
- | 147 | break; |
|
- | 148 | } |
|
- | 149 | args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; |
|
- | 150 | } else if (is_cv) { |
|
- | 151 | args.ucTVStandard = ATOM_TV_CV; |
|
- | 152 | args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; |
|
- | 153 | } else { |
|
- | 154 | switch (radeon_crtc->rmx_type) { |
|
- | 155 | case RMX_FULL: |
|
- | 156 | args.ucEnable = ATOM_SCALER_EXPANSION; |
|
- | 157 | break; |
|
- | 158 | case RMX_CENTER: |
|
- | 159 | args.ucEnable = ATOM_SCALER_CENTER; |
|
- | 160 | break; |
|
- | 161 | case RMX_ASPECT: |
|
- | 162 | args.ucEnable = ATOM_SCALER_EXPANSION; |
|
- | 163 | break; |
|
- | 164 | default: |
|
- | 165 | if (ASIC_IS_AVIVO(rdev)) |
|
- | 166 | args.ucEnable = ATOM_SCALER_DISABLE; |
|
- | 167 | else |
|
- | 168 | args.ucEnable = ATOM_SCALER_CENTER; |
|
- | 169 | break; |
|
- | 170 | } |
|
- | 171 | } |
|
- | 172 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
- | 173 | if ((is_tv || is_cv) |
|
- | 174 | && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_R580) { |
|
- | 175 | atom_rv515_force_tv_scaler(rdev, radeon_crtc); |
|
- | 176 | } |
|
- | 177 | } |
|
33 | 178 | ||
34 | static void atombios_lock_crtc(struct drm_crtc *crtc, int lock) |
179 | static void atombios_lock_crtc(struct drm_crtc *crtc, int lock) |
35 | { |
180 | { |
36 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
181 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
37 | struct drm_device *dev = crtc->dev; |
182 | struct drm_device *dev = crtc->dev; |
38 | struct radeon_device *rdev = dev->dev_private; |
183 | struct radeon_device *rdev = dev->dev_private; |
39 | int index = |
184 | int index = |
40 | GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters); |
185 | GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters); |
41 | ENABLE_CRTC_PS_ALLOCATION args; |
186 | ENABLE_CRTC_PS_ALLOCATION args; |
42 | 187 | ||
43 | memset(&args, 0, sizeof(args)); |
188 | memset(&args, 0, sizeof(args)); |
44 | 189 | ||
45 | args.ucCRTC = radeon_crtc->crtc_id; |
190 | args.ucCRTC = radeon_crtc->crtc_id; |
46 | args.ucEnable = lock; |
191 | args.ucEnable = lock; |
47 | 192 | ||
48 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
193 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
49 | } |
194 | } |
50 | 195 | ||
51 | static void atombios_enable_crtc(struct drm_crtc *crtc, int state) |
196 | static void atombios_enable_crtc(struct drm_crtc *crtc, int state) |
52 | { |
197 | { |
53 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
198 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
54 | struct drm_device *dev = crtc->dev; |
199 | struct drm_device *dev = crtc->dev; |
55 | struct radeon_device *rdev = dev->dev_private; |
200 | struct radeon_device *rdev = dev->dev_private; |
56 | int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC); |
201 | int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC); |
57 | ENABLE_CRTC_PS_ALLOCATION args; |
202 | ENABLE_CRTC_PS_ALLOCATION args; |
58 | 203 | ||
59 | memset(&args, 0, sizeof(args)); |
204 | memset(&args, 0, sizeof(args)); |
60 | 205 | ||
61 | args.ucCRTC = radeon_crtc->crtc_id; |
206 | args.ucCRTC = radeon_crtc->crtc_id; |
62 | args.ucEnable = state; |
207 | args.ucEnable = state; |
63 | 208 | ||
64 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
209 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
65 | } |
210 | } |
66 | 211 | ||
67 | static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state) |
212 | static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state) |
68 | { |
213 | { |
69 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
214 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
70 | struct drm_device *dev = crtc->dev; |
215 | struct drm_device *dev = crtc->dev; |
71 | struct radeon_device *rdev = dev->dev_private; |
216 | struct radeon_device *rdev = dev->dev_private; |
72 | int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq); |
217 | int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq); |
73 | ENABLE_CRTC_PS_ALLOCATION args; |
218 | ENABLE_CRTC_PS_ALLOCATION args; |
74 | 219 | ||
75 | memset(&args, 0, sizeof(args)); |
220 | memset(&args, 0, sizeof(args)); |
76 | 221 | ||
77 | args.ucCRTC = radeon_crtc->crtc_id; |
222 | args.ucCRTC = radeon_crtc->crtc_id; |
78 | args.ucEnable = state; |
223 | args.ucEnable = state; |
79 | 224 | ||
80 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
225 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
81 | } |
226 | } |
82 | 227 | ||
83 | static void atombios_blank_crtc(struct drm_crtc *crtc, int state) |
228 | static void atombios_blank_crtc(struct drm_crtc *crtc, int state) |
84 | { |
229 | { |
85 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
230 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
86 | struct drm_device *dev = crtc->dev; |
231 | struct drm_device *dev = crtc->dev; |
87 | struct radeon_device *rdev = dev->dev_private; |
232 | struct radeon_device *rdev = dev->dev_private; |
88 | int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC); |
233 | int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC); |
89 | BLANK_CRTC_PS_ALLOCATION args; |
234 | BLANK_CRTC_PS_ALLOCATION args; |
90 | 235 | ||
91 | memset(&args, 0, sizeof(args)); |
236 | memset(&args, 0, sizeof(args)); |
92 | 237 | ||
93 | args.ucCRTC = radeon_crtc->crtc_id; |
238 | args.ucCRTC = radeon_crtc->crtc_id; |
94 | args.ucBlanking = state; |
239 | args.ucBlanking = state; |
95 | 240 | ||
96 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
241 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
97 | } |
242 | } |
98 | 243 | ||
99 | void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) |
244 | void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) |
100 | { |
245 | { |
101 | struct drm_device *dev = crtc->dev; |
246 | struct drm_device *dev = crtc->dev; |
102 | struct radeon_device *rdev = dev->dev_private; |
247 | struct radeon_device *rdev = dev->dev_private; |
103 | 248 | ||
104 | switch (mode) { |
249 | switch (mode) { |
105 | case DRM_MODE_DPMS_ON: |
250 | case DRM_MODE_DPMS_ON: |
106 | if (ASIC_IS_DCE3(rdev)) |
251 | if (ASIC_IS_DCE3(rdev)) |
107 | atombios_enable_crtc_memreq(crtc, 1); |
252 | atombios_enable_crtc_memreq(crtc, 1); |
108 | atombios_enable_crtc(crtc, 1); |
253 | atombios_enable_crtc(crtc, 1); |
109 | atombios_blank_crtc(crtc, 0); |
254 | atombios_blank_crtc(crtc, 0); |
110 | break; |
255 | break; |
111 | case DRM_MODE_DPMS_STANDBY: |
256 | case DRM_MODE_DPMS_STANDBY: |
112 | case DRM_MODE_DPMS_SUSPEND: |
257 | case DRM_MODE_DPMS_SUSPEND: |
113 | case DRM_MODE_DPMS_OFF: |
258 | case DRM_MODE_DPMS_OFF: |
114 | atombios_blank_crtc(crtc, 1); |
259 | atombios_blank_crtc(crtc, 1); |
115 | atombios_enable_crtc(crtc, 0); |
260 | atombios_enable_crtc(crtc, 0); |
116 | if (ASIC_IS_DCE3(rdev)) |
261 | if (ASIC_IS_DCE3(rdev)) |
117 | atombios_enable_crtc_memreq(crtc, 0); |
262 | atombios_enable_crtc_memreq(crtc, 0); |
118 | break; |
263 | break; |
119 | } |
264 | } |
120 | 265 | ||
121 | if (mode != DRM_MODE_DPMS_OFF) { |
266 | if (mode != DRM_MODE_DPMS_OFF) { |
122 | radeon_crtc_load_lut(crtc); |
267 | radeon_crtc_load_lut(crtc); |
123 | } |
268 | } |
124 | } |
269 | } |
125 | 270 | ||
126 | static void |
271 | static void |
127 | atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, |
272 | atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, |
128 | SET_CRTC_USING_DTD_TIMING_PARAMETERS * crtc_param) |
273 | SET_CRTC_USING_DTD_TIMING_PARAMETERS * crtc_param) |
129 | { |
274 | { |
130 | struct drm_device *dev = crtc->dev; |
275 | struct drm_device *dev = crtc->dev; |
131 | struct radeon_device *rdev = dev->dev_private; |
276 | struct radeon_device *rdev = dev->dev_private; |
132 | SET_CRTC_USING_DTD_TIMING_PARAMETERS conv_param; |
277 | SET_CRTC_USING_DTD_TIMING_PARAMETERS conv_param; |
133 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming); |
278 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming); |
134 | 279 | ||
135 | conv_param.usH_Size = cpu_to_le16(crtc_param->usH_Size); |
280 | conv_param.usH_Size = cpu_to_le16(crtc_param->usH_Size); |
136 | conv_param.usH_Blanking_Time = |
281 | conv_param.usH_Blanking_Time = |
137 | cpu_to_le16(crtc_param->usH_Blanking_Time); |
282 | cpu_to_le16(crtc_param->usH_Blanking_Time); |
138 | conv_param.usV_Size = cpu_to_le16(crtc_param->usV_Size); |
283 | conv_param.usV_Size = cpu_to_le16(crtc_param->usV_Size); |
139 | conv_param.usV_Blanking_Time = |
284 | conv_param.usV_Blanking_Time = |
140 | cpu_to_le16(crtc_param->usV_Blanking_Time); |
285 | cpu_to_le16(crtc_param->usV_Blanking_Time); |
141 | conv_param.usH_SyncOffset = cpu_to_le16(crtc_param->usH_SyncOffset); |
286 | conv_param.usH_SyncOffset = cpu_to_le16(crtc_param->usH_SyncOffset); |
142 | conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth); |
287 | conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth); |
143 | conv_param.usV_SyncOffset = cpu_to_le16(crtc_param->usV_SyncOffset); |
288 | conv_param.usV_SyncOffset = cpu_to_le16(crtc_param->usV_SyncOffset); |
144 | conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth); |
289 | conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth); |
145 | conv_param.susModeMiscInfo.usAccess = |
290 | conv_param.susModeMiscInfo.usAccess = |
146 | cpu_to_le16(crtc_param->susModeMiscInfo.usAccess); |
291 | cpu_to_le16(crtc_param->susModeMiscInfo.usAccess); |
147 | conv_param.ucCRTC = crtc_param->ucCRTC; |
292 | conv_param.ucCRTC = crtc_param->ucCRTC; |
148 | 293 | ||
149 | printk("executing set crtc dtd timing\n"); |
294 | printk("executing set crtc dtd timing\n"); |
150 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param); |
295 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param); |
151 | } |
296 | } |
152 | 297 | ||
153 | void atombios_crtc_set_timing(struct drm_crtc *crtc, |
298 | void atombios_crtc_set_timing(struct drm_crtc *crtc, |
154 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION * |
299 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION * |
155 | crtc_param) |
300 | crtc_param) |
156 | { |
301 | { |
157 | struct drm_device *dev = crtc->dev; |
302 | struct drm_device *dev = crtc->dev; |
158 | struct radeon_device *rdev = dev->dev_private; |
303 | struct radeon_device *rdev = dev->dev_private; |
159 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION conv_param; |
304 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION conv_param; |
160 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing); |
305 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing); |
161 | 306 | ||
162 | conv_param.usH_Total = cpu_to_le16(crtc_param->usH_Total); |
307 | conv_param.usH_Total = cpu_to_le16(crtc_param->usH_Total); |
163 | conv_param.usH_Disp = cpu_to_le16(crtc_param->usH_Disp); |
308 | conv_param.usH_Disp = cpu_to_le16(crtc_param->usH_Disp); |
164 | conv_param.usH_SyncStart = cpu_to_le16(crtc_param->usH_SyncStart); |
309 | conv_param.usH_SyncStart = cpu_to_le16(crtc_param->usH_SyncStart); |
165 | conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth); |
310 | conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth); |
166 | conv_param.usV_Total = cpu_to_le16(crtc_param->usV_Total); |
311 | conv_param.usV_Total = cpu_to_le16(crtc_param->usV_Total); |
167 | conv_param.usV_Disp = cpu_to_le16(crtc_param->usV_Disp); |
312 | conv_param.usV_Disp = cpu_to_le16(crtc_param->usV_Disp); |
168 | conv_param.usV_SyncStart = cpu_to_le16(crtc_param->usV_SyncStart); |
313 | conv_param.usV_SyncStart = cpu_to_le16(crtc_param->usV_SyncStart); |
169 | conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth); |
314 | conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth); |
170 | conv_param.susModeMiscInfo.usAccess = |
315 | conv_param.susModeMiscInfo.usAccess = |
171 | cpu_to_le16(crtc_param->susModeMiscInfo.usAccess); |
316 | cpu_to_le16(crtc_param->susModeMiscInfo.usAccess); |
172 | conv_param.ucCRTC = crtc_param->ucCRTC; |
317 | conv_param.ucCRTC = crtc_param->ucCRTC; |
173 | conv_param.ucOverscanRight = crtc_param->ucOverscanRight; |
318 | conv_param.ucOverscanRight = crtc_param->ucOverscanRight; |
174 | conv_param.ucOverscanLeft = crtc_param->ucOverscanLeft; |
319 | conv_param.ucOverscanLeft = crtc_param->ucOverscanLeft; |
175 | conv_param.ucOverscanBottom = crtc_param->ucOverscanBottom; |
320 | conv_param.ucOverscanBottom = crtc_param->ucOverscanBottom; |
176 | conv_param.ucOverscanTop = crtc_param->ucOverscanTop; |
321 | conv_param.ucOverscanTop = crtc_param->ucOverscanTop; |
177 | conv_param.ucReserved = crtc_param->ucReserved; |
322 | conv_param.ucReserved = crtc_param->ucReserved; |
178 | 323 | ||
179 | printk("executing set crtc timing\n"); |
324 | printk("executing set crtc timing\n"); |
180 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param); |
325 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param); |
181 | } |
326 | } |
182 | 327 | ||
183 | void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) |
328 | void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) |
184 | { |
329 | { |
185 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
330 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
186 | struct drm_device *dev = crtc->dev; |
331 | struct drm_device *dev = crtc->dev; |
187 | struct radeon_device *rdev = dev->dev_private; |
332 | struct radeon_device *rdev = dev->dev_private; |
188 | struct drm_encoder *encoder = NULL; |
333 | struct drm_encoder *encoder = NULL; |
189 | struct radeon_encoder *radeon_encoder = NULL; |
334 | struct radeon_encoder *radeon_encoder = NULL; |
190 | uint8_t frev, crev; |
335 | uint8_t frev, crev; |
191 | int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); |
336 | int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); |
192 | SET_PIXEL_CLOCK_PS_ALLOCATION args; |
337 | SET_PIXEL_CLOCK_PS_ALLOCATION args; |
193 | PIXEL_CLOCK_PARAMETERS *spc1_ptr; |
338 | PIXEL_CLOCK_PARAMETERS *spc1_ptr; |
194 | PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr; |
339 | PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr; |
195 | PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr; |
340 | PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr; |
196 | uint32_t sclock = mode->clock; |
341 | uint32_t sclock = mode->clock; |
197 | uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; |
342 | uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; |
198 | struct radeon_pll *pll; |
343 | struct radeon_pll *pll; |
199 | int pll_flags = 0; |
344 | int pll_flags = 0; |
200 | 345 | ||
201 | memset(&args, 0, sizeof(args)); |
346 | memset(&args, 0, sizeof(args)); |
202 | 347 | ||
203 | if (ASIC_IS_AVIVO(rdev)) { |
348 | if (ASIC_IS_AVIVO(rdev)) { |
204 | uint32_t ss_cntl; |
349 | uint32_t ss_cntl; |
- | 350 | ||
- | 351 | if ((rdev->family == CHIP_RS600) || |
|
- | 352 | (rdev->family == CHIP_RS690) || |
|
- | 353 | (rdev->family == CHIP_RS740)) |
|
- | 354 | pll_flags |= (RADEON_PLL_USE_FRAC_FB_DIV | |
|
- | 355 | RADEON_PLL_PREFER_CLOSEST_LOWER); |
|
205 | 356 | ||
206 | if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ |
357 | if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ |
207 | pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
358 | pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
208 | else |
359 | else |
209 | pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
360 | pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
210 | 361 | ||
211 | /* disable spread spectrum clocking for now -- thanks Hedy Lamarr */ |
362 | /* disable spread spectrum clocking for now -- thanks Hedy Lamarr */ |
212 | if (radeon_crtc->crtc_id == 0) { |
363 | if (radeon_crtc->crtc_id == 0) { |
213 | ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); |
364 | ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); |
214 | WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl & ~1); |
365 | WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl & ~1); |
215 | } else { |
366 | } else { |
216 | ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL); |
367 | ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL); |
217 | WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl & ~1); |
368 | WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl & ~1); |
218 | } |
369 | } |
219 | } else { |
370 | } else { |
220 | pll_flags |= RADEON_PLL_LEGACY; |
371 | pll_flags |= RADEON_PLL_LEGACY; |
221 | 372 | ||
222 | if (mode->clock > 200000) /* range limits??? */ |
373 | if (mode->clock > 200000) /* range limits??? */ |
223 | pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
374 | pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
224 | else |
375 | else |
225 | pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
376 | pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
226 | 377 | ||
227 | } |
378 | } |
228 | 379 | ||
229 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
380 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
230 | if (encoder->crtc == crtc) { |
381 | if (encoder->crtc == crtc) { |
231 | if (!ASIC_IS_AVIVO(rdev)) { |
382 | if (!ASIC_IS_AVIVO(rdev)) { |
232 | if (encoder->encoder_type != |
383 | if (encoder->encoder_type != |
233 | DRM_MODE_ENCODER_DAC) |
384 | DRM_MODE_ENCODER_DAC) |
234 | pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; |
385 | pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; |
235 | if (!ASIC_IS_AVIVO(rdev) |
386 | if (!ASIC_IS_AVIVO(rdev) |
236 | && (encoder->encoder_type == |
387 | && (encoder->encoder_type == |
237 | DRM_MODE_ENCODER_LVDS)) |
388 | DRM_MODE_ENCODER_LVDS)) |
238 | pll_flags |= RADEON_PLL_USE_REF_DIV; |
389 | pll_flags |= RADEON_PLL_USE_REF_DIV; |
239 | } |
390 | } |
240 | radeon_encoder = to_radeon_encoder(encoder); |
391 | radeon_encoder = to_radeon_encoder(encoder); |
- | 392 | break; |
|
241 | } |
393 | } |
242 | } |
394 | } |
243 | 395 | ||
244 | if (radeon_crtc->crtc_id == 0) |
396 | if (radeon_crtc->crtc_id == 0) |
245 | pll = &rdev->clock.p1pll; |
397 | pll = &rdev->clock.p1pll; |
246 | else |
398 | else |
247 | pll = &rdev->clock.p2pll; |
399 | pll = &rdev->clock.p2pll; |
248 | 400 | ||
249 | radeon_compute_pll(pll, mode->clock, &sclock, &fb_div, &frac_fb_div, |
401 | radeon_compute_pll(pll, mode->clock, &sclock, &fb_div, &frac_fb_div, |
250 | &ref_div, &post_div, pll_flags); |
402 | &ref_div, &post_div, pll_flags); |
251 | 403 | ||
252 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, |
404 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, |
253 | &crev); |
405 | &crev); |
254 | 406 | ||
255 | switch (frev) { |
407 | switch (frev) { |
256 | case 1: |
408 | case 1: |
257 | switch (crev) { |
409 | switch (crev) { |
258 | case 1: |
410 | case 1: |
259 | spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput; |
411 | spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput; |
260 | spc1_ptr->usPixelClock = cpu_to_le16(sclock); |
412 | spc1_ptr->usPixelClock = cpu_to_le16(sclock); |
261 | spc1_ptr->usRefDiv = cpu_to_le16(ref_div); |
413 | spc1_ptr->usRefDiv = cpu_to_le16(ref_div); |
262 | spc1_ptr->usFbDiv = cpu_to_le16(fb_div); |
414 | spc1_ptr->usFbDiv = cpu_to_le16(fb_div); |
263 | spc1_ptr->ucFracFbDiv = frac_fb_div; |
415 | spc1_ptr->ucFracFbDiv = frac_fb_div; |
264 | spc1_ptr->ucPostDiv = post_div; |
416 | spc1_ptr->ucPostDiv = post_div; |
265 | spc1_ptr->ucPpll = |
417 | spc1_ptr->ucPpll = |
266 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; |
418 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; |
267 | spc1_ptr->ucCRTC = radeon_crtc->crtc_id; |
419 | spc1_ptr->ucCRTC = radeon_crtc->crtc_id; |
268 | spc1_ptr->ucRefDivSrc = 1; |
420 | spc1_ptr->ucRefDivSrc = 1; |
269 | break; |
421 | break; |
270 | case 2: |
422 | case 2: |
271 | spc2_ptr = |
423 | spc2_ptr = |
272 | (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput; |
424 | (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput; |
273 | spc2_ptr->usPixelClock = cpu_to_le16(sclock); |
425 | spc2_ptr->usPixelClock = cpu_to_le16(sclock); |
274 | spc2_ptr->usRefDiv = cpu_to_le16(ref_div); |
426 | spc2_ptr->usRefDiv = cpu_to_le16(ref_div); |
275 | spc2_ptr->usFbDiv = cpu_to_le16(fb_div); |
427 | spc2_ptr->usFbDiv = cpu_to_le16(fb_div); |
276 | spc2_ptr->ucFracFbDiv = frac_fb_div; |
428 | spc2_ptr->ucFracFbDiv = frac_fb_div; |
277 | spc2_ptr->ucPostDiv = post_div; |
429 | spc2_ptr->ucPostDiv = post_div; |
278 | spc2_ptr->ucPpll = |
430 | spc2_ptr->ucPpll = |
279 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; |
431 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; |
280 | spc2_ptr->ucCRTC = radeon_crtc->crtc_id; |
432 | spc2_ptr->ucCRTC = radeon_crtc->crtc_id; |
281 | spc2_ptr->ucRefDivSrc = 1; |
433 | spc2_ptr->ucRefDivSrc = 1; |
282 | break; |
434 | break; |
283 | case 3: |
435 | case 3: |
284 | if (!encoder) |
436 | if (!encoder) |
285 | return; |
437 | return; |
286 | spc3_ptr = |
438 | spc3_ptr = |
287 | (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput; |
439 | (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput; |
288 | spc3_ptr->usPixelClock = cpu_to_le16(sclock); |
440 | spc3_ptr->usPixelClock = cpu_to_le16(sclock); |
289 | spc3_ptr->usRefDiv = cpu_to_le16(ref_div); |
441 | spc3_ptr->usRefDiv = cpu_to_le16(ref_div); |
290 | spc3_ptr->usFbDiv = cpu_to_le16(fb_div); |
442 | spc3_ptr->usFbDiv = cpu_to_le16(fb_div); |
291 | spc3_ptr->ucFracFbDiv = frac_fb_div; |
443 | spc3_ptr->ucFracFbDiv = frac_fb_div; |
292 | spc3_ptr->ucPostDiv = post_div; |
444 | spc3_ptr->ucPostDiv = post_div; |
293 | spc3_ptr->ucPpll = |
445 | spc3_ptr->ucPpll = |
294 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; |
446 | radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; |
295 | spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2); |
447 | spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2); |
296 | spc3_ptr->ucTransmitterId = radeon_encoder->encoder_id; |
448 | spc3_ptr->ucTransmitterId = radeon_encoder->encoder_id; |
297 | spc3_ptr->ucEncoderMode = |
449 | spc3_ptr->ucEncoderMode = |
298 | atombios_get_encoder_mode(encoder); |
450 | atombios_get_encoder_mode(encoder); |
299 | break; |
451 | break; |
300 | default: |
452 | default: |
301 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
453 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
302 | return; |
454 | return; |
303 | } |
455 | } |
304 | break; |
456 | break; |
305 | default: |
457 | default: |
306 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
458 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
307 | return; |
459 | return; |
308 | } |
460 | } |
309 | 461 | ||
310 | printk("executing set pll\n"); |
462 | printk("executing set pll\n"); |
311 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
463 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
312 | } |
464 | } |
313 | 465 | ||
314 | int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
466 | int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
315 | struct drm_framebuffer *old_fb) |
467 | struct drm_framebuffer *old_fb) |
316 | { |
468 | { |
317 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
469 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
318 | struct drm_device *dev = crtc->dev; |
470 | struct drm_device *dev = crtc->dev; |
319 | struct radeon_device *rdev = dev->dev_private; |
471 | struct radeon_device *rdev = dev->dev_private; |
320 | struct radeon_framebuffer *radeon_fb; |
472 | struct radeon_framebuffer *radeon_fb; |
321 | struct drm_gem_object *obj; |
473 | struct drm_gem_object *obj; |
322 | struct drm_radeon_gem_object *obj_priv; |
474 | struct drm_radeon_gem_object *obj_priv; |
323 | uint64_t fb_location; |
475 | uint64_t fb_location; |
324 | uint32_t fb_format, fb_pitch_pixels; |
476 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; |
325 | - | ||
326 | ENTRY(); |
- | |
327 | 477 | ||
328 | if (!crtc->fb) |
478 | if (!crtc->fb) |
329 | return -EINVAL; |
479 | return -EINVAL; |
- | 480 | ||
- | 481 | dbgprintf("x = %d y = %d width = %d height = %d\n", |
|
- | 482 | x, y, crtc->fb->width, crtc->fb->height); |
|
- | 483 | dbgprintf("hdisplay = %d\n", crtc->mode.hdisplay); |
|
330 | 484 | ||
331 | radeon_fb = to_radeon_framebuffer(crtc->fb); |
485 | radeon_fb = to_radeon_framebuffer(crtc->fb); |
332 | 486 | ||
333 | obj = radeon_fb->obj; |
487 | obj = radeon_fb->obj; |
334 | obj_priv = obj->driver_private; |
488 | obj_priv = obj->driver_private; |
335 | 489 | ||
336 | //if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &fb_location)) { |
490 | // if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &fb_location)) { |
337 | // return -EINVAL; |
491 | // return -EINVAL; |
338 | //} |
492 | // } |
339 | 493 | ||
340 | fb_location = 0; //rdev->mc.vram_location; |
494 | fb_location = 0; //rdev->mc.vram_location; |
341 | 495 | ||
342 | dbgprintf("fb_location %x\n", fb_location); |
496 | dbgprintf("fb_location %x\n", fb_location); |
343 | dbgprintf("bpp %x\n", crtc->fb->bits_per_pixel); |
497 | dbgprintf("bpp %d\n", crtc->fb->bits_per_pixel); |
344 | 498 | ||
- | 499 | switch (crtc->fb->bits_per_pixel) { |
|
- | 500 | case 8: |
|
- | 501 | fb_format = |
|
- | 502 | AVIVO_D1GRPH_CONTROL_DEPTH_8BPP | |
|
- | 503 | AVIVO_D1GRPH_CONTROL_8BPP_INDEXED; |
|
345 | switch (crtc->fb->bits_per_pixel) { |
504 | break; |
346 | case 15: |
505 | case 15: |
347 | fb_format = |
506 | fb_format = |
348 | AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | |
507 | AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | |
349 | AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555; |
508 | AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555; |
350 | break; |
509 | break; |
351 | case 16: |
510 | case 16: |
352 | fb_format = |
511 | fb_format = |
353 | AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | |
512 | AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | |
354 | AVIVO_D1GRPH_CONTROL_16BPP_RGB565; |
513 | AVIVO_D1GRPH_CONTROL_16BPP_RGB565; |
355 | break; |
514 | break; |
356 | case 24: |
515 | case 24: |
357 | case 32: |
516 | case 32: |
358 | fb_format = |
517 | fb_format = |
359 | AVIVO_D1GRPH_CONTROL_DEPTH_32BPP | |
518 | AVIVO_D1GRPH_CONTROL_DEPTH_32BPP | |
360 | AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888; |
519 | AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888; |
361 | break; |
520 | break; |
362 | default: |
521 | default: |
363 | DRM_ERROR("Unsupported screen depth %d\n", |
522 | DRM_ERROR("Unsupported screen depth %d\n", |
364 | crtc->fb->bits_per_pixel); |
523 | crtc->fb->bits_per_pixel); |
365 | return -EINVAL; |
524 | return -EINVAL; |
366 | } |
525 | } |
- | 526 | ||
367 | 527 | // radeon_object_get_tiling_flags(obj->driver_private, |
|
- | 528 | // &tiling_flags, NULL); |
|
- | 529 | // if (tiling_flags & RADEON_TILING_MACRO) |
|
- | 530 | // fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE; |
|
- | 531 | ||
- | 532 | // if (tiling_flags & RADEON_TILING_MICRO) |
|
- | 533 | // fb_format |= AVIVO_D1GRPH_TILED; |
|
368 | /* TODO tiling */ |
534 | |
369 | if (radeon_crtc->crtc_id == 0) |
535 | if (radeon_crtc->crtc_id == 0) |
370 | WREG32(AVIVO_D1VGA_CONTROL, 0); |
536 | WREG32(AVIVO_D1VGA_CONTROL, 0); |
371 | else |
537 | else |
372 | WREG32(AVIVO_D2VGA_CONTROL, 0); |
538 | WREG32(AVIVO_D2VGA_CONTROL, 0); |
373 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
539 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
374 | (u32) fb_location); |
540 | (u32) fb_location); |
375 | WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + |
541 | WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + |
376 | radeon_crtc->crtc_offset, (u32) fb_location); |
542 | radeon_crtc->crtc_offset, (u32) fb_location); |
377 | WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); |
543 | WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); |
378 | 544 | ||
379 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); |
545 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); |
380 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); |
546 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); |
381 | WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0); |
547 | WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0); |
382 | WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0); |
548 | WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0); |
383 | WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width); |
549 | WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width); |
384 | WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height); |
550 | WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height); |
385 | 551 | ||
386 | fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8); |
552 | fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8); |
387 | WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); |
553 | WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); |
388 | WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
554 | WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
389 | 555 | ||
390 | WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, |
556 | WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, |
391 | crtc->mode.vdisplay); |
557 | crtc->mode.vdisplay); |
392 | x &= ~3; |
558 | x &= ~3; |
393 | y &= ~1; |
559 | y &= ~1; |
394 | WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, |
560 | WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, |
395 | (x << 16) | y); |
561 | (x << 16) | y); |
396 | WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, |
562 | WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, |
397 | (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); |
563 | (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); |
398 | 564 | ||
399 | if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) |
565 | if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) |
400 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, |
566 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, |
401 | AVIVO_D1MODE_INTERLEAVE_EN); |
567 | AVIVO_D1MODE_INTERLEAVE_EN); |
402 | else |
568 | else |
403 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); |
569 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); |
404 | 570 | ||
405 | if (old_fb && old_fb != crtc->fb) { |
571 | if (old_fb && old_fb != crtc->fb) { |
406 | radeon_fb = to_radeon_framebuffer(old_fb); |
572 | // radeon_fb = to_radeon_framebuffer(old_fb); |
407 | // radeon_gem_object_unpin(radeon_fb->obj); |
573 | // radeon_gem_object_unpin(radeon_fb->obj); |
408 | } |
574 | } |
409 | LEAVE(); |
- | |
410 | return 0; |
575 | return 0; |
411 | } |
576 | } |
412 | 577 | ||
413 | int atombios_crtc_mode_set(struct drm_crtc *crtc, |
578 | int atombios_crtc_mode_set(struct drm_crtc *crtc, |
414 | struct drm_display_mode *mode, |
579 | struct drm_display_mode *mode, |
415 | struct drm_display_mode *adjusted_mode, |
580 | struct drm_display_mode *adjusted_mode, |
416 | int x, int y, struct drm_framebuffer *old_fb) |
581 | int x, int y, struct drm_framebuffer *old_fb) |
417 | { |
582 | { |
418 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
583 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
419 | struct drm_device *dev = crtc->dev; |
584 | struct drm_device *dev = crtc->dev; |
420 | struct radeon_device *rdev = dev->dev_private; |
585 | struct radeon_device *rdev = dev->dev_private; |
421 | struct drm_encoder *encoder; |
586 | struct drm_encoder *encoder; |
422 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing; |
587 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing; |
423 | - | ||
- | 588 | int need_tv_timings = 0; |
|
424 | ENTRY(); |
589 | bool ret; |
425 | 590 | ||
426 | /* TODO color tiling */ |
591 | /* TODO color tiling */ |
427 | memset(&crtc_timing, 0, sizeof(crtc_timing)); |
592 | memset(&crtc_timing, 0, sizeof(crtc_timing)); |
428 | - | ||
429 | /* TODO tv */ |
593 | |
- | 594 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
|
- | 595 | /* find tv std */ |
|
- | 596 | if (encoder->crtc == crtc) { |
|
- | 597 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
|
- | 598 | ||
- | 599 | if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { |
|
- | 600 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; |
|
- | 601 | if (tv_dac) { |
|
- | 602 | if (tv_dac->tv_std == TV_STD_NTSC || |
|
- | 603 | tv_dac->tv_std == TV_STD_NTSC_J || |
|
- | 604 | tv_dac->tv_std == TV_STD_PAL_M) |
|
- | 605 | need_tv_timings = 1; |
|
- | 606 | else |
|
- | 607 | need_tv_timings = 2; |
|
- | 608 | break; |
|
- | 609 | } |
|
430 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
610 | } |
431 | 611 | } |
|
432 | } |
612 | } |
433 | 613 | ||
434 | crtc_timing.ucCRTC = radeon_crtc->crtc_id; |
614 | crtc_timing.ucCRTC = radeon_crtc->crtc_id; |
- | 615 | if (need_tv_timings) { |
|
- | 616 | ret = radeon_atom_get_tv_timings(rdev, need_tv_timings - 1, |
|
- | 617 | &crtc_timing, &adjusted_mode->clock); |
|
- | 618 | if (ret == false) |
|
- | 619 | need_tv_timings = 0; |
|
- | 620 | } |
|
- | 621 | ||
- | 622 | if (!need_tv_timings) { |
|
435 | crtc_timing.usH_Total = adjusted_mode->crtc_htotal; |
623 | crtc_timing.usH_Total = adjusted_mode->crtc_htotal; |
436 | crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay; |
624 | crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay; |
437 | crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start; |
625 | crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start; |
438 | crtc_timing.usH_SyncWidth = |
626 | crtc_timing.usH_SyncWidth = |
439 | adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; |
627 | adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; |
440 | 628 | ||
441 | crtc_timing.usV_Total = adjusted_mode->crtc_vtotal; |
629 | crtc_timing.usV_Total = adjusted_mode->crtc_vtotal; |
442 | crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay; |
630 | crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay; |
443 | crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start; |
631 | crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start; |
444 | crtc_timing.usV_SyncWidth = |
632 | crtc_timing.usV_SyncWidth = |
445 | adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; |
633 | adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; |
446 | 634 | ||
447 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) |
635 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) |
448 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; |
636 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; |
449 | 637 | ||
450 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) |
638 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) |
451 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; |
639 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; |
452 | 640 | ||
453 | if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) |
641 | if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) |
454 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC; |
642 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC; |
455 | 643 | ||
456 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) |
644 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) |
457 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE; |
645 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE; |
458 | 646 | ||
459 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) |
647 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) |
460 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE; |
648 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE; |
- | 649 | } |
|
461 | 650 | ||
462 | atombios_crtc_set_pll(crtc, adjusted_mode); |
651 | atombios_crtc_set_pll(crtc, adjusted_mode); |
463 | atombios_crtc_set_timing(crtc, &crtc_timing); |
652 | atombios_crtc_set_timing(crtc, &crtc_timing); |
464 | 653 | ||
465 | if (ASIC_IS_AVIVO(rdev)) |
654 | if (ASIC_IS_AVIVO(rdev)) |
466 | atombios_crtc_set_base(crtc, x, y, old_fb); |
655 | atombios_crtc_set_base(crtc, x, y, old_fb); |
467 | else { |
656 | else { |
468 | if (radeon_crtc->crtc_id == 0) { |
657 | if (radeon_crtc->crtc_id == 0) { |
469 | SET_CRTC_USING_DTD_TIMING_PARAMETERS crtc_dtd_timing; |
658 | SET_CRTC_USING_DTD_TIMING_PARAMETERS crtc_dtd_timing; |
470 | memset(&crtc_dtd_timing, 0, sizeof(crtc_dtd_timing)); |
659 | memset(&crtc_dtd_timing, 0, sizeof(crtc_dtd_timing)); |
471 | 660 | ||
472 | /* setup FP shadow regs on R4xx */ |
661 | /* setup FP shadow regs on R4xx */ |
473 | crtc_dtd_timing.ucCRTC = radeon_crtc->crtc_id; |
662 | crtc_dtd_timing.ucCRTC = radeon_crtc->crtc_id; |
474 | crtc_dtd_timing.usH_Size = adjusted_mode->crtc_hdisplay; |
663 | crtc_dtd_timing.usH_Size = adjusted_mode->crtc_hdisplay; |
475 | crtc_dtd_timing.usV_Size = adjusted_mode->crtc_vdisplay; |
664 | crtc_dtd_timing.usV_Size = adjusted_mode->crtc_vdisplay; |
476 | crtc_dtd_timing.usH_Blanking_Time = |
665 | crtc_dtd_timing.usH_Blanking_Time = |
477 | adjusted_mode->crtc_hblank_end - |
666 | adjusted_mode->crtc_hblank_end - |
478 | adjusted_mode->crtc_hdisplay; |
667 | adjusted_mode->crtc_hdisplay; |
479 | crtc_dtd_timing.usV_Blanking_Time = |
668 | crtc_dtd_timing.usV_Blanking_Time = |
480 | adjusted_mode->crtc_vblank_end - |
669 | adjusted_mode->crtc_vblank_end - |
481 | adjusted_mode->crtc_vdisplay; |
670 | adjusted_mode->crtc_vdisplay; |
482 | crtc_dtd_timing.usH_SyncOffset = |
671 | crtc_dtd_timing.usH_SyncOffset = |
483 | adjusted_mode->crtc_hsync_start - |
672 | adjusted_mode->crtc_hsync_start - |
484 | adjusted_mode->crtc_hdisplay; |
673 | adjusted_mode->crtc_hdisplay; |
485 | crtc_dtd_timing.usV_SyncOffset = |
674 | crtc_dtd_timing.usV_SyncOffset = |
486 | adjusted_mode->crtc_vsync_start - |
675 | adjusted_mode->crtc_vsync_start - |
487 | adjusted_mode->crtc_vdisplay; |
676 | adjusted_mode->crtc_vdisplay; |
488 | crtc_dtd_timing.usH_SyncWidth = |
677 | crtc_dtd_timing.usH_SyncWidth = |
489 | adjusted_mode->crtc_hsync_end - |
678 | adjusted_mode->crtc_hsync_end - |
490 | adjusted_mode->crtc_hsync_start; |
679 | adjusted_mode->crtc_hsync_start; |
491 | crtc_dtd_timing.usV_SyncWidth = |
680 | crtc_dtd_timing.usV_SyncWidth = |
492 | adjusted_mode->crtc_vsync_end - |
681 | adjusted_mode->crtc_vsync_end - |
493 | adjusted_mode->crtc_vsync_start; |
682 | adjusted_mode->crtc_vsync_start; |
494 | /* crtc_dtd_timing.ucH_Border = adjusted_mode->crtc_hborder; */ |
683 | /* crtc_dtd_timing.ucH_Border = adjusted_mode->crtc_hborder; */ |
495 | /* crtc_dtd_timing.ucV_Border = adjusted_mode->crtc_vborder; */ |
684 | /* crtc_dtd_timing.ucV_Border = adjusted_mode->crtc_vborder; */ |
496 | 685 | ||
497 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) |
686 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) |
498 | crtc_dtd_timing.susModeMiscInfo.usAccess |= |
687 | crtc_dtd_timing.susModeMiscInfo.usAccess |= |
499 | ATOM_VSYNC_POLARITY; |
688 | ATOM_VSYNC_POLARITY; |
500 | 689 | ||
501 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) |
690 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) |
502 | crtc_dtd_timing.susModeMiscInfo.usAccess |= |
691 | crtc_dtd_timing.susModeMiscInfo.usAccess |= |
503 | ATOM_HSYNC_POLARITY; |
692 | ATOM_HSYNC_POLARITY; |
504 | 693 | ||
505 | if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) |
694 | if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) |
506 | crtc_dtd_timing.susModeMiscInfo.usAccess |= |
695 | crtc_dtd_timing.susModeMiscInfo.usAccess |= |
507 | ATOM_COMPOSITESYNC; |
696 | ATOM_COMPOSITESYNC; |
508 | 697 | ||
509 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) |
698 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) |
510 | crtc_dtd_timing.susModeMiscInfo.usAccess |= |
699 | crtc_dtd_timing.susModeMiscInfo.usAccess |= |
511 | ATOM_INTERLACE; |
700 | ATOM_INTERLACE; |
512 | 701 | ||
513 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) |
702 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) |
514 | crtc_dtd_timing.susModeMiscInfo.usAccess |= |
703 | crtc_dtd_timing.susModeMiscInfo.usAccess |= |
515 | ATOM_DOUBLE_CLOCK_MODE; |
704 | ATOM_DOUBLE_CLOCK_MODE; |
516 | 705 | ||
517 | atombios_set_crtc_dtd_timing(crtc, &crtc_dtd_timing); |
706 | atombios_set_crtc_dtd_timing(crtc, &crtc_dtd_timing); |
518 | } |
707 | } |
519 | radeon_crtc_set_base(crtc, x, y, old_fb); |
708 | radeon_crtc_set_base(crtc, x, y, old_fb); |
520 | radeon_legacy_atom_set_surface(crtc); |
709 | radeon_legacy_atom_set_surface(crtc); |
521 | } |
710 | } |
- | 711 | atombios_overscan_setup(crtc, mode, adjusted_mode); |
|
522 | LEAVE(); |
712 | atombios_scaler_setup(crtc); |
523 | - | ||
- | 713 | radeon_bandwidth_update(rdev); |
|
524 | return 0; |
714 | return 0; |
525 | } |
715 | } |
526 | 716 | ||
527 | static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, |
717 | static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, |
528 | struct drm_display_mode *mode, |
718 | struct drm_display_mode *mode, |
529 | struct drm_display_mode *adjusted_mode) |
719 | struct drm_display_mode *adjusted_mode) |
530 | { |
720 | { |
- | 721 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) |
|
- | 722 | return false; |
|
531 | return true; |
723 | return true; |
532 | } |
724 | } |
533 | 725 | ||
534 | static void atombios_crtc_prepare(struct drm_crtc *crtc) |
726 | static void atombios_crtc_prepare(struct drm_crtc *crtc) |
535 | { |
727 | { |
536 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
728 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
537 | atombios_lock_crtc(crtc, 1); |
729 | atombios_lock_crtc(crtc, 1); |
538 | } |
730 | } |
539 | 731 | ||
540 | static void atombios_crtc_commit(struct drm_crtc *crtc) |
732 | static void atombios_crtc_commit(struct drm_crtc *crtc) |
541 | { |
733 | { |
542 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); |
734 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); |
543 | atombios_lock_crtc(crtc, 0); |
735 | atombios_lock_crtc(crtc, 0); |
544 | } |
736 | } |
545 | 737 | ||
546 | static const struct drm_crtc_helper_funcs atombios_helper_funcs = { |
738 | static const struct drm_crtc_helper_funcs atombios_helper_funcs = { |
547 | .dpms = atombios_crtc_dpms, |
739 | .dpms = atombios_crtc_dpms, |
548 | .mode_fixup = atombios_crtc_mode_fixup, |
740 | .mode_fixup = atombios_crtc_mode_fixup, |
549 | .mode_set = atombios_crtc_mode_set, |
741 | .mode_set = atombios_crtc_mode_set, |
550 | .mode_set_base = atombios_crtc_set_base, |
742 | .mode_set_base = atombios_crtc_set_base, |
551 | .prepare = atombios_crtc_prepare, |
743 | .prepare = atombios_crtc_prepare, |
552 | .commit = atombios_crtc_commit, |
744 | .commit = atombios_crtc_commit, |
553 | }; |
745 | }; |
554 | 746 | ||
555 | void radeon_atombios_init_crtc(struct drm_device *dev, |
747 | void radeon_atombios_init_crtc(struct drm_device *dev, |
556 | struct radeon_crtc *radeon_crtc) |
748 | struct radeon_crtc *radeon_crtc) |
557 | { |
749 | { |
558 | if (radeon_crtc->crtc_id == 1) |
750 | if (radeon_crtc->crtc_id == 1) |
559 | radeon_crtc->crtc_offset = |
751 | radeon_crtc->crtc_offset = |
560 | AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL; |
752 | AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL; |
561 | drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); |
753 | drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); |
562 | } |
754 | }><>><>><>=> |
563 | - | ||
564 | void radeon_init_disp_bw_avivo(struct drm_device *dev, |
- | |
565 | struct drm_display_mode *mode1, |
- | |
566 | uint32_t pixel_bytes1, |
- | |
567 | struct drm_display_mode *mode2, |
- | |
568 | uint32_t pixel_bytes2) |
- | |
569 | { |
- | |
570 | struct radeon_device *rdev = dev->dev_private; |
- | |
571 | fixed20_12 min_mem_eff; |
- | |
572 | fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff; |
- | |
573 | fixed20_12 sclk_ff, mclk_ff; |
- | |
574 | uint32_t dc_lb_memory_split, temp; |
- | |
575 | - | ||
576 | min_mem_eff.full = rfixed_const_8(0); |
- | |
577 | if (rdev->disp_priority == 2) { |
- | |
578 | uint32_t mc_init_misc_lat_timer = 0; |
- | |
579 | if (rdev->family == CHIP_RV515) |
- | |
580 | mc_init_misc_lat_timer = |
- | |
581 | RREG32_MC(RV515_MC_INIT_MISC_LAT_TIMER); |
- | |
582 | else if (rdev->family == CHIP_RS690) |
- | |
583 | mc_init_misc_lat_timer = |
- | |
584 | RREG32_MC(RS690_MC_INIT_MISC_LAT_TIMER); |
- | |
585 | - | ||
586 | mc_init_misc_lat_timer &= |
- | |
587 | ~(R300_MC_DISP1R_INIT_LAT_MASK << |
- | |
588 | R300_MC_DISP1R_INIT_LAT_SHIFT); |
- | |
589 | mc_init_misc_lat_timer &= |
- | |
590 | ~(R300_MC_DISP0R_INIT_LAT_MASK << |
- | |
591 | R300_MC_DISP0R_INIT_LAT_SHIFT); |
- | |
592 | - | ||
593 | if (mode2) |
- | |
594 | mc_init_misc_lat_timer |= |
- | |
595 | (1 << R300_MC_DISP1R_INIT_LAT_SHIFT); |
- | |
596 | if (mode1) |
- | |
597 | mc_init_misc_lat_timer |= |
- | |
598 | (1 << R300_MC_DISP0R_INIT_LAT_SHIFT); |
- | |
599 | - | ||
600 | if (rdev->family == CHIP_RV515) |
- | |
601 | WREG32_MC(RV515_MC_INIT_MISC_LAT_TIMER, |
- | |
602 | mc_init_misc_lat_timer); |
- | |
603 | else if (rdev->family == CHIP_RS690) |
- | |
604 | WREG32_MC(RS690_MC_INIT_MISC_LAT_TIMER, |
- | |
605 | mc_init_misc_lat_timer); |
- | |
606 | } |
- | |
607 | - | ||
608 | /* |
- | |
609 | * determine is there is enough bw for current mode |
- | |
610 | */ |
- | |
611 | temp_ff.full = rfixed_const(100); |
- | |
612 | mclk_ff.full = rfixed_const(rdev->clock.default_mclk); |
- | |
613 | mclk_ff.full = rfixed_div(mclk_ff, temp_ff); |
- | |
614 | sclk_ff.full = rfixed_const(rdev->clock.default_sclk); |
- | |
615 | sclk_ff.full = rfixed_div(sclk_ff, temp_ff); |
- | |
616 | - | ||
617 | temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1); |
- | |
618 | temp_ff.full = rfixed_const(temp); |
- | |
619 | mem_bw.full = rfixed_mul(mclk_ff, temp_ff); |
- | |
620 | mem_bw.full = rfixed_mul(mem_bw, min_mem_eff); |
- | |
621 | - | ||
622 | pix_clk.full = 0; |
- | |
623 | pix_clk2.full = 0; |
- | |
624 | peak_disp_bw.full = 0; |
- | |
625 | if (mode1) { |
- | |
626 | temp_ff.full = rfixed_const(1000); |
- | |
627 | pix_clk.full = rfixed_const(mode1->clock); /* convert to fixed point */ |
- | |
628 | pix_clk.full = rfixed_div(pix_clk, temp_ff); |
- | |
629 | temp_ff.full = rfixed_const(pixel_bytes1); |
- | |
630 | peak_disp_bw.full += rfixed_mul(pix_clk, temp_ff); |
- | |
631 | } |
- | |
632 | if (mode2) { |
- | |
633 | temp_ff.full = rfixed_const(1000); |
- | |
634 | pix_clk2.full = rfixed_const(mode2->clock); /* convert to fixed point */ |
- | |
635 | pix_clk2.full = rfixed_div(pix_clk2, temp_ff); |
- | |
636 | temp_ff.full = rfixed_const(pixel_bytes2); |
- | |
637 | peak_disp_bw.full += rfixed_mul(pix_clk2, temp_ff); |
- | |
638 | } |
- | |
639 | - | ||
640 | if (peak_disp_bw.full >= mem_bw.full) { |
- | |
641 | DRM_ERROR |
- | |
642 | ("You may not have enough display bandwidth for current mode\n" |
- | |
643 | "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n"); |
- | |
644 | printk("peak disp bw %d, mem_bw %d\n", |
- | |
645 | rfixed_trunc(peak_disp_bw), rfixed_trunc(mem_bw)); |
- | |
646 | } |
- | |
647 | - | ||
648 | /* |
- | |
649 | * Line Buffer Setup |
- | |
650 | * There is a single line buffer shared by both display controllers. |
- | |
651 | * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between the display |
- | |
652 | * controllers. The paritioning can either be done manually or via one of four |
- | |
653 | * preset allocations specified in bits 1:0: |
- | |
654 | * 0 - line buffer is divided in half and shared between each display controller |
- | |
655 | * 1 - D1 gets 3/4 of the line buffer, D2 gets 1/4 |
- | |
656 | * 2 - D1 gets the whole buffer |
- | |
657 | * 3 - D1 gets 1/4 of the line buffer, D2 gets 3/4 |
- | |
658 | * Setting bit 2 of DC_LB_MEMORY_SPLIT controls switches to manual allocation mode. |
- | |
659 | * In manual allocation mode, D1 always starts at 0, D1 end/2 is specified in bits |
- | |
660 | * 14:4; D2 allocation follows D1. |
- | |
661 | */ |
- | |
662 | - | ||
663 | /* is auto or manual better ? */ |
- | |
664 | dc_lb_memory_split = |
- | |
665 | RREG32(AVIVO_DC_LB_MEMORY_SPLIT) & ~AVIVO_DC_LB_MEMORY_SPLIT_MASK; |
- | |
666 | dc_lb_memory_split &= ~AVIVO_DC_LB_MEMORY_SPLIT_SHIFT_MODE; |
- | |
667 | #if 1 |
- | |
668 | /* auto */ |
- | |
669 | if (mode1 && mode2) { |
- | |
670 | if (mode1->hdisplay > mode2->hdisplay) { |
- | |
671 | if (mode1->hdisplay > 2560) |
- | |
672 | dc_lb_memory_split |= |
- | |
673 | AVIVO_DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q; |
- | |
674 | else |
- | |
675 | dc_lb_memory_split |= |
- | |
676 | AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF; |
- | |
677 | } else if (mode2->hdisplay > mode1->hdisplay) { |
- | |
678 | if (mode2->hdisplay > 2560) |
- | |
679 | dc_lb_memory_split |= |
- | |
680 | AVIVO_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q; |
- | |
681 | else |
- | |
682 | dc_lb_memory_split |= |
- | |
683 | AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF; |
- | |
684 | } else |
- | |
685 | dc_lb_memory_split |= |
- | |
686 | AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF; |
- | |
687 | } else if (mode1) { |
- | |
688 | dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1_ONLY; |
- | |
689 | } else if (mode2) { |
- | |
690 | dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q; |
- | |
691 | } |
- | |
692 | #else |
- | |
693 | /* manual */ |
- | |
694 | dc_lb_memory_split |= AVIVO_DC_LB_MEMORY_SPLIT_SHIFT_MODE; |
- | |
695 | dc_lb_memory_split &= |
- | |
696 | ~(AVIVO_DC_LB_DISP1_END_ADR_MASK << |
- | |
697 | AVIVO_DC_LB_DISP1_END_ADR_SHIFT); |
- | |
698 | if (mode1) { |
- | |
699 | dc_lb_memory_split |= |
- | |
700 | ((((mode1->hdisplay / 2) + 64) & AVIVO_DC_LB_DISP1_END_ADR_MASK) |
- | |
701 | << AVIVO_DC_LB_DISP1_END_ADR_SHIFT); |
- | |
702 | } else if (mode2) { |
- | |
703 | dc_lb_memory_split |= (0 << AVIVO_DC_LB_DISP1_END_ADR_SHIFT); |
- | |
704 | } |
- | |
705 | #endif |
- | |
706 | WREG32(AVIVO_DC_LB_MEMORY_SPLIT, dc_lb_memory_split); |
- | |
707 | }><>><> |
- | |
708 | >< |
- | |
709 | >><>><> |
- | |
710 | >< |
- | |
711 | > |
- | |
712 | >< |
- | |
713 | >><>><>><> |
- |