Rev 2160 | Rev 3192 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1123 | serge | 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 | */ |
||
2997 | Serge | 26 | #include |
27 | #include |
||
1123 | serge | 28 | #include "radeon.h" |
29 | |||
30 | #include "atom.h" |
||
1963 | serge | 31 | #include |
1123 | serge | 32 | |
2997 | Serge | 33 | #include |
34 | #include |
||
1123 | serge | 35 | |
36 | static void avivo_crtc_load_lut(struct drm_crtc *crtc) |
||
37 | { |
||
38 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
||
39 | struct drm_device *dev = crtc->dev; |
||
40 | struct radeon_device *rdev = dev->dev_private; |
||
41 | int i; |
||
42 | |||
1963 | serge | 43 | DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); |
1123 | serge | 44 | WREG32(AVIVO_DC_LUTA_CONTROL + radeon_crtc->crtc_offset, 0); |
45 | |||
46 | WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); |
||
47 | WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0); |
||
48 | WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0); |
||
49 | |||
50 | WREG32(AVIVO_DC_LUTA_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff); |
||
51 | WREG32(AVIVO_DC_LUTA_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff); |
||
52 | WREG32(AVIVO_DC_LUTA_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff); |
||
53 | |||
54 | WREG32(AVIVO_DC_LUT_RW_SELECT, radeon_crtc->crtc_id); |
||
55 | WREG32(AVIVO_DC_LUT_RW_MODE, 0); |
||
56 | WREG32(AVIVO_DC_LUT_WRITE_EN_MASK, 0x0000003f); |
||
57 | |||
58 | WREG8(AVIVO_DC_LUT_RW_INDEX, 0); |
||
59 | for (i = 0; i < 256; i++) { |
||
60 | WREG32(AVIVO_DC_LUT_30_COLOR, |
||
61 | (radeon_crtc->lut_r[i] << 20) | |
||
62 | (radeon_crtc->lut_g[i] << 10) | |
||
63 | (radeon_crtc->lut_b[i] << 0)); |
||
64 | } |
||
65 | |||
66 | WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id); |
||
67 | } |
||
68 | |||
1963 | serge | 69 | static void dce4_crtc_load_lut(struct drm_crtc *crtc) |
1430 | serge | 70 | { |
71 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
||
72 | struct drm_device *dev = crtc->dev; |
||
73 | struct radeon_device *rdev = dev->dev_private; |
||
74 | int i; |
||
75 | |||
1963 | serge | 76 | DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); |
1430 | serge | 77 | WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0); |
78 | |||
79 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); |
||
80 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0); |
||
81 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0); |
||
82 | |||
83 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff); |
||
84 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff); |
||
85 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff); |
||
86 | |||
1963 | serge | 87 | WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0); |
88 | WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007); |
||
1430 | serge | 89 | |
1963 | serge | 90 | WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0); |
1430 | serge | 91 | for (i = 0; i < 256; i++) { |
1963 | serge | 92 | WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset, |
1430 | serge | 93 | (radeon_crtc->lut_r[i] << 20) | |
94 | (radeon_crtc->lut_g[i] << 10) | |
||
95 | (radeon_crtc->lut_b[i] << 0)); |
||
96 | } |
||
97 | } |
||
98 | |||
1963 | serge | 99 | static void dce5_crtc_load_lut(struct drm_crtc *crtc) |
100 | { |
||
101 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
||
102 | struct drm_device *dev = crtc->dev; |
||
103 | struct radeon_device *rdev = dev->dev_private; |
||
104 | int i; |
||
105 | |||
106 | DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); |
||
107 | |||
108 | WREG32(NI_INPUT_CSC_CONTROL + radeon_crtc->crtc_offset, |
||
109 | (NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) | |
||
110 | NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS))); |
||
111 | WREG32(NI_PRESCALE_GRPH_CONTROL + radeon_crtc->crtc_offset, |
||
112 | NI_GRPH_PRESCALE_BYPASS); |
||
113 | WREG32(NI_PRESCALE_OVL_CONTROL + radeon_crtc->crtc_offset, |
||
114 | NI_OVL_PRESCALE_BYPASS); |
||
115 | WREG32(NI_INPUT_GAMMA_CONTROL + radeon_crtc->crtc_offset, |
||
116 | (NI_GRPH_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT) | |
||
117 | NI_OVL_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT))); |
||
118 | |||
119 | WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0); |
||
120 | |||
121 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); |
||
122 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0); |
||
123 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0); |
||
124 | |||
125 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff); |
||
126 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff); |
||
127 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff); |
||
128 | |||
129 | WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0); |
||
130 | WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007); |
||
131 | |||
132 | WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0); |
||
133 | for (i = 0; i < 256; i++) { |
||
134 | WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset, |
||
135 | (radeon_crtc->lut_r[i] << 20) | |
||
136 | (radeon_crtc->lut_g[i] << 10) | |
||
137 | (radeon_crtc->lut_b[i] << 0)); |
||
138 | } |
||
139 | |||
140 | WREG32(NI_DEGAMMA_CONTROL + radeon_crtc->crtc_offset, |
||
141 | (NI_GRPH_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | |
||
142 | NI_OVL_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | |
||
143 | NI_ICON_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | |
||
144 | NI_CURSOR_DEGAMMA_MODE(NI_DEGAMMA_BYPASS))); |
||
145 | WREG32(NI_GAMUT_REMAP_CONTROL + radeon_crtc->crtc_offset, |
||
146 | (NI_GRPH_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS) | |
||
147 | NI_OVL_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS))); |
||
148 | WREG32(NI_REGAMMA_CONTROL + radeon_crtc->crtc_offset, |
||
149 | (NI_GRPH_REGAMMA_MODE(NI_REGAMMA_BYPASS) | |
||
150 | NI_OVL_REGAMMA_MODE(NI_REGAMMA_BYPASS))); |
||
151 | WREG32(NI_OUTPUT_CSC_CONTROL + radeon_crtc->crtc_offset, |
||
152 | (NI_OUTPUT_CSC_GRPH_MODE(NI_OUTPUT_CSC_BYPASS) | |
||
153 | NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS))); |
||
154 | /* XXX match this to the depth of the crtc fmt block, move to modeset? */ |
||
155 | WREG32(0x6940 + radeon_crtc->crtc_offset, 0); |
||
156 | |||
157 | } |
||
158 | |||
1123 | serge | 159 | static void legacy_crtc_load_lut(struct drm_crtc *crtc) |
160 | { |
||
161 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
||
162 | struct drm_device *dev = crtc->dev; |
||
163 | struct radeon_device *rdev = dev->dev_private; |
||
164 | int i; |
||
165 | uint32_t dac2_cntl; |
||
166 | |||
167 | dac2_cntl = RREG32(RADEON_DAC_CNTL2); |
||
168 | if (radeon_crtc->crtc_id == 0) |
||
169 | dac2_cntl &= (uint32_t)~RADEON_DAC2_PALETTE_ACC_CTL; |
||
170 | else |
||
171 | dac2_cntl |= RADEON_DAC2_PALETTE_ACC_CTL; |
||
172 | WREG32(RADEON_DAC_CNTL2, dac2_cntl); |
||
173 | |||
174 | WREG8(RADEON_PALETTE_INDEX, 0); |
||
175 | for (i = 0; i < 256; i++) { |
||
176 | WREG32(RADEON_PALETTE_30_DATA, |
||
177 | (radeon_crtc->lut_r[i] << 20) | |
||
178 | (radeon_crtc->lut_g[i] << 10) | |
||
179 | (radeon_crtc->lut_b[i] << 0)); |
||
180 | } |
||
181 | } |
||
182 | |||
183 | void radeon_crtc_load_lut(struct drm_crtc *crtc) |
||
184 | { |
||
185 | struct drm_device *dev = crtc->dev; |
||
186 | struct radeon_device *rdev = dev->dev_private; |
||
187 | |||
188 | if (!crtc->enabled) |
||
189 | return; |
||
190 | |||
1963 | serge | 191 | if (ASIC_IS_DCE5(rdev)) |
192 | dce5_crtc_load_lut(crtc); |
||
193 | else if (ASIC_IS_DCE4(rdev)) |
||
194 | dce4_crtc_load_lut(crtc); |
||
1430 | serge | 195 | else if (ASIC_IS_AVIVO(rdev)) |
1123 | serge | 196 | avivo_crtc_load_lut(crtc); |
197 | else |
||
198 | legacy_crtc_load_lut(crtc); |
||
199 | } |
||
200 | |||
1221 | serge | 201 | /** Sets the color ramps on behalf of fbcon */ |
1123 | serge | 202 | void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, |
203 | u16 blue, int regno) |
||
204 | { |
||
205 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
||
206 | |||
207 | radeon_crtc->lut_r[regno] = red >> 6; |
||
208 | radeon_crtc->lut_g[regno] = green >> 6; |
||
209 | radeon_crtc->lut_b[regno] = blue >> 6; |
||
210 | } |
||
211 | |||
1221 | serge | 212 | /** Gets the color ramps on behalf of fbcon */ |
213 | void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, |
||
214 | u16 *blue, int regno) |
||
215 | { |
||
216 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
||
217 | |||
218 | *red = radeon_crtc->lut_r[regno] << 6; |
||
219 | *green = radeon_crtc->lut_g[regno] << 6; |
||
220 | *blue = radeon_crtc->lut_b[regno] << 6; |
||
221 | } |
||
222 | |||
1123 | serge | 223 | static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, |
1963 | serge | 224 | u16 *blue, uint32_t start, uint32_t size) |
1123 | serge | 225 | { |
226 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
||
1963 | serge | 227 | int end = (start + size > 256) ? 256 : start + size, i; |
1123 | serge | 228 | |
1221 | serge | 229 | /* userspace palettes are always correct as is */ |
1963 | serge | 230 | for (i = start; i < end; i++) { |