File: | dev/pci/drm/i915/display/intel_backlight.c |
Warning: | line 51, column 15 Division by zero |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | // SPDX-License-Identifier: MIT | |||
2 | /* | |||
3 | * Copyright © 2021 Intel Corporation | |||
4 | */ | |||
5 | ||||
6 | #include <linux/backlight.h> | |||
7 | #include <linux/kernel.h> | |||
8 | #include <linux/pwm.h> | |||
9 | #include <linux/string_helpers.h> | |||
10 | ||||
11 | #include <acpi/video.h> | |||
12 | ||||
13 | #include "intel_backlight.h" | |||
14 | #include "intel_backlight_regs.h" | |||
15 | #include "intel_connector.h" | |||
16 | #include "intel_de.h" | |||
17 | #include "intel_display_types.h" | |||
18 | #include "intel_dp_aux_backlight.h" | |||
19 | #include "intel_dsi_dcs_backlight.h" | |||
20 | #include "intel_panel.h" | |||
21 | #include "intel_pci_config.h" | |||
22 | #include "intel_pps.h" | |||
23 | #include "intel_quirks.h" | |||
24 | ||||
25 | /** | |||
26 | * scale - scale values from one range to another | |||
27 | * @source_val: value in range [@source_min..@source_max] | |||
28 | * @source_min: minimum legal value for @source_val | |||
29 | * @source_max: maximum legal value for @source_val | |||
30 | * @target_min: corresponding target value for @source_min | |||
31 | * @target_max: corresponding target value for @source_max | |||
32 | * | |||
33 | * Return @source_val in range [@source_min..@source_max] scaled to range | |||
34 | * [@target_min..@target_max]. | |||
35 | */ | |||
36 | static u32 scale(u32 source_val, | |||
37 | u32 source_min, u32 source_max, | |||
38 | u32 target_min, u32 target_max) | |||
39 | { | |||
40 | u64 target_val; | |||
41 | ||||
42 | WARN_ON(source_min > source_max)({ int __ret = !!(source_min > source_max); if (__ret) printf ("WARNING %s failed at %s:%d\n", "source_min > source_max" , "/usr/src/sys/dev/pci/drm/i915/display/intel_backlight.c", 42 ); __builtin_expect(!!(__ret), 0); }); | |||
43 | WARN_ON(target_min > target_max)({ int __ret = !!(target_min > target_max); if (__ret) printf ("WARNING %s failed at %s:%d\n", "target_min > target_max" , "/usr/src/sys/dev/pci/drm/i915/display/intel_backlight.c", 43 ); __builtin_expect(!!(__ret), 0); }); | |||
44 | ||||
45 | /* defensive */ | |||
46 | source_val = clamp(source_val, source_min, source_max)({ __typeof(source_val) __min_a = (({ __typeof(source_val) __max_a = (source_val); __typeof(source_val) __max_b = (source_min); __max_a > __max_b ? __max_a : __max_b; })); __typeof(source_val ) __min_b = (source_max); __min_a < __min_b ? __min_a : __min_b ; }); | |||
47 | ||||
48 | /* avoid overflows */ | |||
49 | target_val = mul_u32_u32(source_val - source_min, | |||
50 | target_max - target_min); | |||
51 | target_val = DIV_ROUND_CLOSEST_ULL(target_val, source_max - source_min)(((target_val) + ((source_max - source_min) / 2)) / (source_max - source_min)); | |||
| ||||
52 | target_val += target_min; | |||
53 | ||||
54 | return target_val; | |||
55 | } | |||
56 | ||||
57 | /* | |||
58 | * Scale user_level in range [0..user_max] to [0..hw_max], clamping the result | |||
59 | * to [hw_min..hw_max]. | |||
60 | */ | |||
61 | static u32 clamp_user_to_hw(struct intel_connector *connector, | |||
62 | u32 user_level, u32 user_max) | |||
63 | { | |||
64 | struct intel_panel *panel = &connector->panel; | |||
65 | u32 hw_level; | |||
66 | ||||
67 | hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max); | |||
68 | hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max)({ __typeof(hw_level) __min_a = (({ __typeof(hw_level) __max_a = (hw_level); __typeof(hw_level) __max_b = (panel->backlight .min); __max_a > __max_b ? __max_a : __max_b; })); __typeof (hw_level) __min_b = (panel->backlight.max); __min_a < __min_b ? __min_a : __min_b; }); | |||
69 | ||||
70 | return hw_level; | |||
71 | } | |||
72 | ||||
73 | /* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */ | |||
74 | static u32 scale_hw_to_user(struct intel_connector *connector, | |||
75 | u32 hw_level, u32 user_max) | |||
76 | { | |||
77 | struct intel_panel *panel = &connector->panel; | |||
78 | ||||
79 | return scale(hw_level, panel->backlight.min, panel->backlight.max, | |||
80 | 0, user_max); | |||
81 | } | |||
82 | ||||
83 | u32 intel_backlight_invert_pwm_level(struct intel_connector *connector, u32 val) | |||
84 | { | |||
85 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
86 | struct intel_panel *panel = &connector->panel; | |||
87 | ||||
88 | drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0)({ int __ret = !!((panel->backlight.pwm_level_max == 0)); if (__ret) printf("%s %s: " "%s", dev_driver_string(((&dev_priv ->drm))->dev), "", "drm_WARN_ON(" "panel->backlight.pwm_level_max == 0" ")"); __builtin_expect(!!(__ret), 0); }); | |||
89 | ||||
90 | if (dev_priv->params.invert_brightness < 0) | |||
91 | return val; | |||
92 | ||||
93 | if (dev_priv->params.invert_brightness > 0 || | |||
94 | intel_has_quirk(dev_priv, QUIRK_INVERT_BRIGHTNESS)) { | |||
95 | return panel->backlight.pwm_level_max - val + panel->backlight.pwm_level_min; | |||
96 | } | |||
97 | ||||
98 | return val; | |||
99 | } | |||
100 | ||||
101 | void intel_backlight_set_pwm_level(const struct drm_connector_state *conn_state, u32 val) | |||
102 | { | |||
103 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
104 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev); | |||
105 | struct intel_panel *panel = &connector->panel; | |||
106 | ||||
107 | drm_dbg_kms(&i915->drm, "set backlight PWM = %d\n", val)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "set backlight PWM = %d\n" , val); | |||
108 | panel->backlight.pwm_funcs->set(conn_state, val); | |||
109 | } | |||
110 | ||||
111 | u32 intel_backlight_level_to_pwm(struct intel_connector *connector, u32 val) | |||
112 | { | |||
113 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
114 | struct intel_panel *panel = &connector->panel; | |||
115 | ||||
116 | drm_WARN_ON_ONCE(&dev_priv->drm,({ static int __warned; int __ret = !!((panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0)); if (__ret && !__warned) { printf("%s %s: " "%s", dev_driver_string(((& dev_priv->drm))->dev), "", "drm_WARN_ON_ONCE(" "panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0" ")"); __warned = 1; } __builtin_expect(!!(__ret), 0); }) | |||
| ||||
117 | panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0)({ static int __warned; int __ret = !!((panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0)); if (__ret && !__warned) { printf("%s %s: " "%s", dev_driver_string(((& dev_priv->drm))->dev), "", "drm_WARN_ON_ONCE(" "panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0" ")"); __warned = 1; } __builtin_expect(!!(__ret), 0); }); | |||
118 | ||||
119 | val = scale(val, panel->backlight.min, panel->backlight.max, | |||
120 | panel->backlight.pwm_level_min, panel->backlight.pwm_level_max); | |||
121 | ||||
122 | return intel_backlight_invert_pwm_level(connector, val); | |||
123 | } | |||
124 | ||||
125 | u32 intel_backlight_level_from_pwm(struct intel_connector *connector, u32 val) | |||
126 | { | |||
127 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
128 | struct intel_panel *panel = &connector->panel; | |||
129 | ||||
130 | drm_WARN_ON_ONCE(&dev_priv->drm,({ static int __warned; int __ret = !!((panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0)); if (__ret && !__warned) { printf("%s %s: " "%s", dev_driver_string(((& dev_priv->drm))->dev), "", "drm_WARN_ON_ONCE(" "panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0" ")"); __warned = 1; } __builtin_expect(!!(__ret), 0); }) | |||
131 | panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0)({ static int __warned; int __ret = !!((panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0)); if (__ret && !__warned) { printf("%s %s: " "%s", dev_driver_string(((& dev_priv->drm))->dev), "", "drm_WARN_ON_ONCE(" "panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0" ")"); __warned = 1; } __builtin_expect(!!(__ret), 0); }); | |||
132 | ||||
133 | if (dev_priv->params.invert_brightness > 0 || | |||
134 | (dev_priv->params.invert_brightness == 0 && intel_has_quirk(dev_priv, QUIRK_INVERT_BRIGHTNESS))) | |||
135 | val = panel->backlight.pwm_level_max - (val - panel->backlight.pwm_level_min); | |||
136 | ||||
137 | return scale(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max, | |||
138 | panel->backlight.min, panel->backlight.max); | |||
139 | } | |||
140 | ||||
141 | static u32 lpt_get_backlight(struct intel_connector *connector, enum pipe unused) | |||
142 | { | |||
143 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
144 | ||||
145 | return intel_de_read(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) })) & BACKLIGHT_DUTY_CYCLE_MASK(0xffff); | |||
146 | } | |||
147 | ||||
148 | static u32 pch_get_backlight(struct intel_connector *connector, enum pipe unused) | |||
149 | { | |||
150 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
151 | ||||
152 | return intel_de_read(dev_priv, BLC_PWM_CPU_CTL((const i915_reg_t){ .reg = (0x48254) })) & BACKLIGHT_DUTY_CYCLE_MASK(0xffff); | |||
153 | } | |||
154 | ||||
155 | static u32 i9xx_get_backlight(struct intel_connector *connector, enum pipe unused) | |||
156 | { | |||
157 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
158 | struct intel_panel *panel = &connector->panel; | |||
159 | u32 val; | |||
160 | ||||
161 | val = intel_de_read(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61254) })) & BACKLIGHT_DUTY_CYCLE_MASK(0xffff); | |||
162 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) < 4) | |||
163 | val >>= 1; | |||
164 | ||||
165 | if (panel->backlight.combination_mode) { | |||
166 | u8 lbpc; | |||
167 | ||||
168 | pci_read_config_byte(dev_priv->drm.pdev, LBPC0xf4, &lbpc); | |||
169 | val *= lbpc; | |||
170 | } | |||
171 | ||||
172 | return val; | |||
173 | } | |||
174 | ||||
175 | static u32 vlv_get_backlight(struct intel_connector *connector, enum pipe pipe) | |||
176 | { | |||
177 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
178 | ||||
179 | if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B)({ int __ret = !!((pipe != PIPE_A && pipe != PIPE_B)) ; if (__ret) printf("%s %s: " "%s", dev_driver_string(((& dev_priv->drm))->dev), "", "drm_WARN_ON(" "pipe != PIPE_A && pipe != PIPE_B" ")"); __builtin_expect(!!(__ret), 0); })) | |||
180 | return 0; | |||
181 | ||||
182 | return intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info) ->display.mmio_offset) + 0x61254)) + (pipe) * (((((&(dev_priv )->__info)->display.mmio_offset) + 0x61354)) - ((((& (dev_priv)->__info)->display.mmio_offset) + 0x61254)))) ) })) & BACKLIGHT_DUTY_CYCLE_MASK(0xffff); | |||
183 | } | |||
184 | ||||
185 | static u32 bxt_get_backlight(struct intel_connector *connector, enum pipe unused) | |||
186 | { | |||
187 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
188 | struct intel_panel *panel = &connector->panel; | |||
189 | ||||
190 | return intel_de_read(dev_priv, | |||
191 | BXT_BLC_PWM_DUTY(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8258) + (panel->backlight .controller) * ((0xC8358) - (0xC8258)))) })); | |||
192 | } | |||
193 | ||||
194 | static u32 ext_pwm_get_backlight(struct intel_connector *connector, enum pipe unused) | |||
195 | { | |||
196 | STUB()do { printf("%s: stub\n", __func__); } while(0); | |||
197 | return 0; | |||
198 | #ifdef notyet | |||
199 | struct intel_panel *panel = &connector->panel; | |||
200 | struct pwm_state state; | |||
201 | ||||
202 | pwm_get_state(panel->backlight.pwm, &state); | |||
203 | return pwm_get_relative_duty_cycle(&state, 100); | |||
204 | #endif | |||
205 | } | |||
206 | ||||
207 | static void lpt_set_backlight(const struct drm_connector_state *conn_state, u32 level) | |||
208 | { | |||
209 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
210 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
211 | ||||
212 | u32 val = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) })) & ~BACKLIGHT_DUTY_CYCLE_MASK(0xffff); | |||
213 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) }), val | level); | |||
214 | } | |||
215 | ||||
216 | static void pch_set_backlight(const struct drm_connector_state *conn_state, u32 level) | |||
217 | { | |||
218 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
219 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
220 | u32 tmp; | |||
221 | ||||
222 | tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL((const i915_reg_t){ .reg = (0x48254) })) & ~BACKLIGHT_DUTY_CYCLE_MASK(0xffff); | |||
223 | intel_de_write(dev_priv, BLC_PWM_CPU_CTL((const i915_reg_t){ .reg = (0x48254) }), tmp | level); | |||
224 | } | |||
225 | ||||
226 | static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32 level) | |||
227 | { | |||
228 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
229 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
230 | struct intel_panel *panel = &connector->panel; | |||
231 | u32 tmp, mask; | |||
232 | ||||
233 | drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0)({ int __ret = !!((panel->backlight.pwm_level_max == 0)); if (__ret) printf("%s %s: " "%s", dev_driver_string(((&dev_priv ->drm))->dev), "", "drm_WARN_ON(" "panel->backlight.pwm_level_max == 0" ")"); __builtin_expect(!!(__ret), 0); }); | |||
234 | ||||
235 | if (panel->backlight.combination_mode) { | |||
236 | u8 lbpc; | |||
237 | ||||
238 | lbpc = level * 0xfe / panel->backlight.pwm_level_max + 1; | |||
239 | level /= lbpc; | |||
240 | pci_write_config_byte(dev_priv->drm.pdev, LBPC0xf4, lbpc); | |||
241 | } | |||
242 | ||||
243 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) == 4) { | |||
244 | mask = BACKLIGHT_DUTY_CYCLE_MASK(0xffff); | |||
245 | } else { | |||
246 | level <<= 1; | |||
247 | mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV(0xfffe); | |||
248 | } | |||
249 | ||||
250 | tmp = intel_de_read(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61254) })) & ~mask; | |||
251 | intel_de_write(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61254) }), tmp | level); | |||
252 | } | |||
253 | ||||
254 | static void vlv_set_backlight(const struct drm_connector_state *conn_state, u32 level) | |||
255 | { | |||
256 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
257 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
258 | enum pipe pipe = to_intel_crtc(conn_state->crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (conn_state->crtc); (struct intel_crtc *)( (char *)__mptr - __builtin_offsetof(struct intel_crtc, base) );})->pipe; | |||
259 | u32 tmp; | |||
260 | ||||
261 | tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info) ->display.mmio_offset) + 0x61254)) + (pipe) * (((((&(dev_priv )->__info)->display.mmio_offset) + 0x61354)) - ((((& (dev_priv)->__info)->display.mmio_offset) + 0x61254)))) ) })) & ~BACKLIGHT_DUTY_CYCLE_MASK(0xffff); | |||
262 | intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info) ->display.mmio_offset) + 0x61254)) + (pipe) * (((((&(dev_priv )->__info)->display.mmio_offset) + 0x61354)) - ((((& (dev_priv)->__info)->display.mmio_offset) + 0x61254)))) ) }), tmp | level); | |||
263 | } | |||
264 | ||||
265 | static void bxt_set_backlight(const struct drm_connector_state *conn_state, u32 level) | |||
266 | { | |||
267 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
268 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
269 | struct intel_panel *panel = &connector->panel; | |||
270 | ||||
271 | intel_de_write(dev_priv, | |||
272 | BXT_BLC_PWM_DUTY(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8258) + (panel->backlight .controller) * ((0xC8358) - (0xC8258)))) }), level); | |||
273 | } | |||
274 | ||||
275 | static void ext_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level) | |||
276 | { | |||
277 | STUB()do { printf("%s: stub\n", __func__); } while(0); | |||
278 | #ifdef notyet | |||
279 | struct intel_panel *panel = &to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );})->panel; | |||
280 | ||||
281 | pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100); | |||
282 | pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); | |||
283 | #endif | |||
284 | } | |||
285 | ||||
286 | static void | |||
287 | intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, u32 level) | |||
288 | { | |||
289 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
290 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev); | |||
291 | struct intel_panel *panel = &connector->panel; | |||
292 | ||||
293 | drm_dbg_kms(&i915->drm, "set backlight level = %d\n", level)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "set backlight level = %d\n" , level); | |||
294 | ||||
295 | panel->backlight.funcs->set(conn_state, level); | |||
296 | } | |||
297 | ||||
298 | /* set backlight brightness to level in range [0..max], assuming hw min is | |||
299 | * respected. | |||
300 | */ | |||
301 | void intel_backlight_set_acpi(const struct drm_connector_state *conn_state, | |||
302 | u32 user_level, u32 user_max) | |||
303 | { | |||
304 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
305 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
306 | struct intel_panel *panel = &connector->panel; | |||
307 | u32 hw_level; | |||
308 | ||||
309 | /* | |||
310 | * Lack of crtc may occur during driver init because | |||
311 | * connection_mutex isn't held across the entire backlight | |||
312 | * setup + modeset readout, and the BIOS can issue the | |||
313 | * requests at any time. | |||
314 | */ | |||
315 | if (!panel->backlight.present || !conn_state->crtc) | |||
316 | return; | |||
317 | ||||
318 | mutex_lock(&dev_priv->display.backlight.lock)rw_enter_write(&dev_priv->display.backlight.lock); | |||
319 | ||||
320 | drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0)({ int __ret = !!((panel->backlight.max == 0)); if (__ret) printf("%s %s: " "%s", dev_driver_string(((&dev_priv-> drm))->dev), "", "drm_WARN_ON(" "panel->backlight.max == 0" ")"); __builtin_expect(!!(__ret), 0); }); | |||
321 | ||||
322 | hw_level = clamp_user_to_hw(connector, user_level, user_max); | |||
323 | panel->backlight.level = hw_level; | |||
324 | ||||
325 | if (panel->backlight.device) | |||
326 | panel->backlight.device->props.brightness = | |||
327 | scale_hw_to_user(connector, | |||
328 | panel->backlight.level, | |||
329 | panel->backlight.device->props.max_brightness); | |||
330 | ||||
331 | if (panel->backlight.enabled) | |||
332 | intel_panel_actually_set_backlight(conn_state, hw_level); | |||
333 | ||||
334 | mutex_unlock(&dev_priv->display.backlight.lock)rw_exit_write(&dev_priv->display.backlight.lock); | |||
335 | } | |||
336 | ||||
337 | static void lpt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level) | |||
338 | { | |||
339 | struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (old_conn_state->connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
340 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
341 | u32 tmp; | |||
342 | ||||
343 | intel_backlight_set_pwm_level(old_conn_state, level); | |||
344 | ||||
345 | /* | |||
346 | * Although we don't support or enable CPU PWM with LPT/SPT based | |||
347 | * systems, it may have been enabled prior to loading the | |||
348 | * driver. Disable to avoid warnings on LCPLL disable. | |||
349 | * | |||
350 | * This needs rework if we need to add support for CPU PWM on PCH split | |||
351 | * platforms. | |||
352 | */ | |||
353 | tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) })); | |||
354 | if (tmp & BLM_PWM_ENABLE(1 << 31)) { | |||
355 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "cpu backlight was enabled, disabling\n" ) | |||
356 | "cpu backlight was enabled, disabling\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "cpu backlight was enabled, disabling\n" ); | |||
357 | intel_de_write(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }), | |||
358 | tmp & ~BLM_PWM_ENABLE(1 << 31)); | |||
359 | } | |||
360 | ||||
361 | tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) })); | |||
362 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), tmp & ~BLM_PCH_PWM_ENABLE(1 << 31)); | |||
363 | } | |||
364 | ||||
365 | static void pch_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) | |||
366 | { | |||
367 | struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (old_conn_state->connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
368 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
369 | u32 tmp; | |||
370 | ||||
371 | intel_backlight_set_pwm_level(old_conn_state, val); | |||
372 | ||||
373 | tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) })); | |||
374 | intel_de_write(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }), tmp & ~BLM_PWM_ENABLE(1 << 31)); | |||
375 | ||||
376 | tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) })); | |||
377 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), tmp & ~BLM_PCH_PWM_ENABLE(1 << 31)); | |||
378 | } | |||
379 | ||||
380 | static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) | |||
381 | { | |||
382 | intel_backlight_set_pwm_level(old_conn_state, val); | |||
383 | } | |||
384 | ||||
385 | static void i965_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) | |||
386 | { | |||
387 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(old_conn_state->connector->dev); | |||
388 | u32 tmp; | |||
389 | ||||
390 | intel_backlight_set_pwm_level(old_conn_state, val); | |||
391 | ||||
392 | tmp = intel_de_read(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61250) })); | |||
393 | intel_de_write(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61250) }), tmp & ~BLM_PWM_ENABLE(1 << 31)); | |||
394 | } | |||
395 | ||||
396 | static void vlv_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) | |||
397 | { | |||
398 | struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (old_conn_state->connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
399 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
400 | enum pipe pipe = to_intel_crtc(old_conn_state->crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (old_conn_state->crtc); (struct intel_crtc *)( (char *) __mptr - __builtin_offsetof(struct intel_crtc, base) );})->pipe; | |||
401 | u32 tmp; | |||
402 | ||||
403 | intel_backlight_set_pwm_level(old_conn_state, val); | |||
404 | ||||
405 | tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info) ->display.mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv )->__info)->display.mmio_offset) + 0x61350)) - ((((& (dev_priv)->__info)->display.mmio_offset) + 0x61250)))) ) })); | |||
406 | intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info) ->display.mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv )->__info)->display.mmio_offset) + 0x61350)) - ((((& (dev_priv)->__info)->display.mmio_offset) + 0x61250)))) ) }), | |||
407 | tmp & ~BLM_PWM_ENABLE(1 << 31)); | |||
408 | } | |||
409 | ||||
410 | static void bxt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) | |||
411 | { | |||
412 | struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (old_conn_state->connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
413 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
414 | struct intel_panel *panel = &connector->panel; | |||
415 | u32 tmp; | |||
416 | ||||
417 | intel_backlight_set_pwm_level(old_conn_state, val); | |||
418 | ||||
419 | tmp = intel_de_read(dev_priv, | |||
420 | BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) })); | |||
421 | intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) }), | |||
422 | tmp & ~BXT_BLC_PWM_ENABLE(1 << 31)); | |||
423 | ||||
424 | if (panel->backlight.controller == 1) { | |||
425 | val = intel_de_read(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) })); | |||
426 | val &= ~UTIL_PIN_ENABLE(1 << 31); | |||
427 | intel_de_write(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) }), val); | |||
428 | } | |||
429 | } | |||
430 | ||||
431 | static void cnp_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) | |||
432 | { | |||
433 | struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (old_conn_state->connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
434 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
435 | struct intel_panel *panel = &connector->panel; | |||
436 | u32 tmp; | |||
437 | ||||
438 | intel_backlight_set_pwm_level(old_conn_state, val); | |||
439 | ||||
440 | tmp = intel_de_read(dev_priv, | |||
441 | BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) })); | |||
442 | intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) }), | |||
443 | tmp & ~BXT_BLC_PWM_ENABLE(1 << 31)); | |||
444 | } | |||
445 | ||||
446 | static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level) | |||
447 | { | |||
448 | STUB()do { printf("%s: stub\n", __func__); } while(0); | |||
449 | #ifdef notyet | |||
450 | struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (old_conn_state->connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
451 | struct intel_panel *panel = &connector->panel; | |||
452 | ||||
453 | intel_backlight_set_pwm_level(old_conn_state, level); | |||
454 | ||||
455 | panel->backlight.pwm_state.enabled = false0; | |||
456 | pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); | |||
457 | #endif | |||
458 | } | |||
459 | ||||
460 | void intel_backlight_disable(const struct drm_connector_state *old_conn_state) | |||
461 | { | |||
462 | struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (old_conn_state->connector); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
463 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
464 | struct intel_panel *panel = &connector->panel; | |||
465 | ||||
466 | if (!panel->backlight.present) | |||
467 | return; | |||
468 | ||||
469 | /* | |||
470 | * Do not disable backlight on the vga_switcheroo path. When switching | |||
471 | * away from i915, the other client may depend on i915 to handle the | |||
472 | * backlight. This will leave the backlight on unnecessarily when | |||
473 | * another client is not activated. | |||
474 | */ | |||
475 | if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) { | |||
476 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Skipping backlight disable on vga switch\n" ) | |||
477 | "Skipping backlight disable on vga switch\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Skipping backlight disable on vga switch\n" ); | |||
478 | return; | |||
479 | } | |||
480 | ||||
481 | mutex_lock(&dev_priv->display.backlight.lock)rw_enter_write(&dev_priv->display.backlight.lock); | |||
482 | ||||
483 | if (panel->backlight.device) | |||
484 | panel->backlight.device->props.power = FB_BLANK_POWERDOWN4; | |||
485 | panel->backlight.enabled = false0; | |||
486 | panel->backlight.funcs->disable(old_conn_state, 0); | |||
487 | ||||
488 | mutex_unlock(&dev_priv->display.backlight.lock)rw_exit_write(&dev_priv->display.backlight.lock); | |||
489 | } | |||
490 | ||||
491 | static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state, | |||
492 | const struct drm_connector_state *conn_state, u32 level) | |||
493 | { | |||
494 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
495 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
496 | struct intel_panel *panel = &connector->panel; | |||
497 | u32 pch_ctl1, pch_ctl2, schicken; | |||
498 | ||||
499 | pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) })); | |||
500 | if (pch_ctl1 & BLM_PCH_PWM_ENABLE(1 << 31)) { | |||
501 | drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "pch backlight already enabled\n" ); | |||
502 | pch_ctl1 &= ~BLM_PCH_PWM_ENABLE(1 << 31); | |||
503 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), pch_ctl1); | |||
504 | } | |||
505 | ||||
506 | if (HAS_PCH_LPT(dev_priv)(((dev_priv)->pch_type) == PCH_LPT)) { | |||
507 | schicken = intel_de_read(dev_priv, SOUTH_CHICKEN2((const i915_reg_t){ .reg = (0xc2004) })); | |||
508 | if (panel->backlight.alternate_pwm_increment) | |||
509 | schicken |= LPT_PWM_GRANULARITY(1 << 5); | |||
510 | else | |||
511 | schicken &= ~LPT_PWM_GRANULARITY(1 << 5); | |||
512 | intel_de_write(dev_priv, SOUTH_CHICKEN2((const i915_reg_t){ .reg = (0xc2004) }), schicken); | |||
513 | } else { | |||
514 | schicken = intel_de_read(dev_priv, SOUTH_CHICKEN1((const i915_reg_t){ .reg = (0xc2000) })); | |||
515 | if (panel->backlight.alternate_pwm_increment) | |||
516 | schicken |= SPT_PWM_GRANULARITY(1 << 0); | |||
517 | else | |||
518 | schicken &= ~SPT_PWM_GRANULARITY(1 << 0); | |||
519 | intel_de_write(dev_priv, SOUTH_CHICKEN1((const i915_reg_t){ .reg = (0xc2000) }), schicken); | |||
520 | } | |||
521 | ||||
522 | pch_ctl2 = panel->backlight.pwm_level_max << 16; | |||
523 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) }), pch_ctl2); | |||
524 | ||||
525 | pch_ctl1 = 0; | |||
526 | if (panel->backlight.active_low_pwm) | |||
527 | pch_ctl1 |= BLM_PCH_POLARITY(1 << 29); | |||
528 | ||||
529 | /* After LPT, override is the default. */ | |||
530 | if (HAS_PCH_LPT(dev_priv)(((dev_priv)->pch_type) == PCH_LPT)) | |||
531 | pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE(1 << 30); | |||
532 | ||||
533 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), pch_ctl1); | |||
534 | intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) })); | |||
535 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), | |||
536 | pch_ctl1 | BLM_PCH_PWM_ENABLE(1 << 31)); | |||
537 | ||||
538 | /* This won't stick until the above enable. */ | |||
539 | intel_backlight_set_pwm_level(conn_state, level); | |||
540 | } | |||
541 | ||||
542 | static void pch_enable_backlight(const struct intel_crtc_state *crtc_state, | |||
543 | const struct drm_connector_state *conn_state, u32 level) | |||
544 | { | |||
545 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
546 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
547 | struct intel_panel *panel = &connector->panel; | |||
548 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; | |||
549 | u32 cpu_ctl2, pch_ctl1, pch_ctl2; | |||
550 | ||||
551 | cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) })); | |||
552 | if (cpu_ctl2 & BLM_PWM_ENABLE(1 << 31)) { | |||
553 | drm_dbg_kms(&dev_priv->drm, "cpu backlight already enabled\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "cpu backlight already enabled\n" ); | |||
554 | cpu_ctl2 &= ~BLM_PWM_ENABLE(1 << 31); | |||
555 | intel_de_write(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }), cpu_ctl2); | |||
556 | } | |||
557 | ||||
558 | pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) })); | |||
559 | if (pch_ctl1 & BLM_PCH_PWM_ENABLE(1 << 31)) { | |||
560 | drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "pch backlight already enabled\n" ); | |||
561 | pch_ctl1 &= ~BLM_PCH_PWM_ENABLE(1 << 31); | |||
562 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), pch_ctl1); | |||
563 | } | |||
564 | ||||
565 | if (cpu_transcoder == TRANSCODER_EDP) | |||
566 | cpu_ctl2 = BLM_TRANSCODER_EDP(3 << 29); | |||
567 | else | |||
568 | cpu_ctl2 = BLM_PIPE(cpu_transcoder)((cpu_transcoder) << 29); | |||
569 | intel_de_write(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }), cpu_ctl2); | |||
570 | intel_de_posting_read(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) })); | |||
571 | intel_de_write(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }), cpu_ctl2 | BLM_PWM_ENABLE(1 << 31)); | |||
572 | ||||
573 | /* This won't stick until the above enable. */ | |||
574 | intel_backlight_set_pwm_level(conn_state, level); | |||
575 | ||||
576 | pch_ctl2 = panel->backlight.pwm_level_max << 16; | |||
577 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) }), pch_ctl2); | |||
578 | ||||
579 | pch_ctl1 = 0; | |||
580 | if (panel->backlight.active_low_pwm) | |||
581 | pch_ctl1 |= BLM_PCH_POLARITY(1 << 29); | |||
582 | ||||
583 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), pch_ctl1); | |||
584 | intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) })); | |||
585 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), | |||
586 | pch_ctl1 | BLM_PCH_PWM_ENABLE(1 << 31)); | |||
587 | } | |||
588 | ||||
589 | static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state, | |||
590 | const struct drm_connector_state *conn_state, u32 level) | |||
591 | { | |||
592 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
593 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
594 | struct intel_panel *panel = &connector->panel; | |||
595 | u32 ctl, freq; | |||
596 | ||||
597 | ctl = intel_de_read(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61254) })); | |||
598 | if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV(0xfffe)) { | |||
599 | drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "backlight already enabled\n" ); | |||
600 | intel_de_write(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61254) }), 0); | |||
601 | } | |||
602 | ||||
603 | freq = panel->backlight.pwm_level_max; | |||
604 | if (panel->backlight.combination_mode) | |||
605 | freq /= 0xff; | |||
606 | ||||
607 | ctl = freq << 17; | |||
608 | if (panel->backlight.combination_mode) | |||
609 | ctl |= BLM_LEGACY_MODE(1 << 16); | |||
610 | if (IS_PINEVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_PINEVIEW) && panel->backlight.active_low_pwm) | |||
611 | ctl |= BLM_POLARITY_PNV(1 << 0); | |||
612 | ||||
613 | intel_de_write(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61254) }), ctl); | |||
614 | intel_de_posting_read(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61254) })); | |||
615 | ||||
616 | /* XXX: combine this into above write? */ | |||
617 | intel_backlight_set_pwm_level(conn_state, level); | |||
618 | ||||
619 | /* | |||
620 | * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is | |||
621 | * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2 | |||
622 | * that has backlight. | |||
623 | */ | |||
624 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) == 2) | |||
625 | intel_de_write(dev_priv, BLC_HIST_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61260) }), BLM_HISTOGRAM_ENABLE(1 << 31)); | |||
626 | } | |||
627 | ||||
628 | static void i965_enable_backlight(const struct intel_crtc_state *crtc_state, | |||
629 | const struct drm_connector_state *conn_state, u32 level) | |||
630 | { | |||
631 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
632 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
633 | struct intel_panel *panel = &connector->panel; | |||
634 | enum pipe pipe = to_intel_crtc(conn_state->crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (conn_state->crtc); (struct intel_crtc *)( (char *)__mptr - __builtin_offsetof(struct intel_crtc, base) );})->pipe; | |||
635 | u32 ctl, ctl2, freq; | |||
636 | ||||
637 | ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61250) })); | |||
638 | if (ctl2 & BLM_PWM_ENABLE(1 << 31)) { | |||
639 | drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "backlight already enabled\n" ); | |||
640 | ctl2 &= ~BLM_PWM_ENABLE(1 << 31); | |||
641 | intel_de_write(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61250) }), ctl2); | |||
642 | } | |||
643 | ||||
644 | freq = panel->backlight.pwm_level_max; | |||
645 | if (panel->backlight.combination_mode) | |||
646 | freq /= 0xff; | |||
647 | ||||
648 | ctl = freq << 16; | |||
649 | intel_de_write(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61254) }), ctl); | |||
650 | ||||
651 | ctl2 = BLM_PIPE(pipe)((pipe) << 29); | |||
652 | if (panel->backlight.combination_mode) | |||
653 | ctl2 |= BLM_COMBINATION_MODE(1 << 30); | |||
654 | if (panel->backlight.active_low_pwm) | |||
655 | ctl2 |= BLM_POLARITY_I965(1 << 28); | |||
656 | intel_de_write(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61250) }), ctl2); | |||
657 | intel_de_posting_read(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61250) })); | |||
658 | intel_de_write(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61250) }), ctl2 | BLM_PWM_ENABLE(1 << 31)); | |||
659 | ||||
660 | intel_backlight_set_pwm_level(conn_state, level); | |||
661 | } | |||
662 | ||||
663 | static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state, | |||
664 | const struct drm_connector_state *conn_state, u32 level) | |||
665 | { | |||
666 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
667 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
668 | struct intel_panel *panel = &connector->panel; | |||
669 | enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );})->pipe; | |||
670 | u32 ctl, ctl2; | |||
671 | ||||
672 | ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info) ->display.mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv )->__info)->display.mmio_offset) + 0x61350)) - ((((& (dev_priv)->__info)->display.mmio_offset) + 0x61250)))) ) })); | |||
673 | if (ctl2 & BLM_PWM_ENABLE(1 << 31)) { | |||
674 | drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "backlight already enabled\n" ); | |||
675 | ctl2 &= ~BLM_PWM_ENABLE(1 << 31); | |||
676 | intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info) ->display.mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv )->__info)->display.mmio_offset) + 0x61350)) - ((((& (dev_priv)->__info)->display.mmio_offset) + 0x61250)))) ) }), ctl2); | |||
677 | } | |||
678 | ||||
679 | ctl = panel->backlight.pwm_level_max << 16; | |||
680 | intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info) ->display.mmio_offset) + 0x61254)) + (pipe) * (((((&(dev_priv )->__info)->display.mmio_offset) + 0x61354)) - ((((& (dev_priv)->__info)->display.mmio_offset) + 0x61254)))) ) }), ctl); | |||
681 | ||||
682 | /* XXX: combine this into above write? */ | |||
683 | intel_backlight_set_pwm_level(conn_state, level); | |||
684 | ||||
685 | ctl2 = 0; | |||
686 | if (panel->backlight.active_low_pwm) | |||
687 | ctl2 |= BLM_POLARITY_I965(1 << 28); | |||
688 | intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info) ->display.mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv )->__info)->display.mmio_offset) + 0x61350)) - ((((& (dev_priv)->__info)->display.mmio_offset) + 0x61250)))) ) }), ctl2); | |||
689 | intel_de_posting_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info) ->display.mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv )->__info)->display.mmio_offset) + 0x61350)) - ((((& (dev_priv)->__info)->display.mmio_offset) + 0x61250)))) ) })); | |||
690 | intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info) ->display.mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv )->__info)->display.mmio_offset) + 0x61350)) - ((((& (dev_priv)->__info)->display.mmio_offset) + 0x61250)))) ) }), | |||
691 | ctl2 | BLM_PWM_ENABLE(1 << 31)); | |||
692 | } | |||
693 | ||||
694 | static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state, | |||
695 | const struct drm_connector_state *conn_state, u32 level) | |||
696 | { | |||
697 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
698 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
699 | struct intel_panel *panel = &connector->panel; | |||
700 | enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );})->pipe; | |||
701 | u32 pwm_ctl, val; | |||
702 | ||||
703 | /* Controller 1 uses the utility pin. */ | |||
704 | if (panel->backlight.controller == 1) { | |||
705 | val = intel_de_read(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) })); | |||
706 | if (val & UTIL_PIN_ENABLE(1 << 31)) { | |||
707 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "util pin already enabled\n" ) | |||
708 | "util pin already enabled\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "util pin already enabled\n" ); | |||
709 | val &= ~UTIL_PIN_ENABLE(1 << 31); | |||
710 | intel_de_write(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) }), val); | |||
711 | } | |||
712 | ||||
713 | val = 0; | |||
714 | if (panel->backlight.util_pin_active_low) | |||
715 | val |= UTIL_PIN_POLARITY(1 << 22); | |||
716 | intel_de_write(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) }), | |||
717 | val | UTIL_PIN_PIPE(pipe)((pipe) << 29) | UTIL_PIN_MODE_PWM(1 << 24) | UTIL_PIN_ENABLE(1 << 31)); | |||
718 | } | |||
719 | ||||
720 | pwm_ctl = intel_de_read(dev_priv, | |||
721 | BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) })); | |||
722 | if (pwm_ctl & BXT_BLC_PWM_ENABLE(1 << 31)) { | |||
723 | drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "backlight already enabled\n" ); | |||
724 | pwm_ctl &= ~BXT_BLC_PWM_ENABLE(1 << 31); | |||
725 | intel_de_write(dev_priv, | |||
726 | BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) }), | |||
727 | pwm_ctl); | |||
728 | } | |||
729 | ||||
730 | intel_de_write(dev_priv, | |||
731 | BXT_BLC_PWM_FREQ(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8254) + (panel->backlight .controller) * ((0xC8354) - (0xC8254)))) }), | |||
732 | panel->backlight.pwm_level_max); | |||
733 | ||||
734 | intel_backlight_set_pwm_level(conn_state, level); | |||
735 | ||||
736 | pwm_ctl = 0; | |||
737 | if (panel->backlight.active_low_pwm) | |||
738 | pwm_ctl |= BXT_BLC_PWM_POLARITY(1 << 29); | |||
739 | ||||
740 | intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) }), | |||
741 | pwm_ctl); | |||
742 | intel_de_posting_read(dev_priv, | |||
743 | BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) })); | |||
744 | intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) }), | |||
745 | pwm_ctl | BXT_BLC_PWM_ENABLE(1 << 31)); | |||
746 | } | |||
747 | ||||
748 | static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state, | |||
749 | const struct drm_connector_state *conn_state, u32 level) | |||
750 | { | |||
751 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
752 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
753 | struct intel_panel *panel = &connector->panel; | |||
754 | u32 pwm_ctl; | |||
755 | ||||
756 | pwm_ctl = intel_de_read(dev_priv, | |||
757 | BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) })); | |||
758 | if (pwm_ctl & BXT_BLC_PWM_ENABLE(1 << 31)) { | |||
759 | drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "backlight already enabled\n" ); | |||
760 | pwm_ctl &= ~BXT_BLC_PWM_ENABLE(1 << 31); | |||
761 | intel_de_write(dev_priv, | |||
762 | BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) }), | |||
763 | pwm_ctl); | |||
764 | } | |||
765 | ||||
766 | intel_de_write(dev_priv, | |||
767 | BXT_BLC_PWM_FREQ(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8254) + (panel->backlight .controller) * ((0xC8354) - (0xC8254)))) }), | |||
768 | panel->backlight.pwm_level_max); | |||
769 | ||||
770 | intel_backlight_set_pwm_level(conn_state, level); | |||
771 | ||||
772 | pwm_ctl = 0; | |||
773 | if (panel->backlight.active_low_pwm) | |||
774 | pwm_ctl |= BXT_BLC_PWM_POLARITY(1 << 29); | |||
775 | ||||
776 | intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) }), | |||
777 | pwm_ctl); | |||
778 | intel_de_posting_read(dev_priv, | |||
779 | BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) })); | |||
780 | intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) }), | |||
781 | pwm_ctl | BXT_BLC_PWM_ENABLE(1 << 31)); | |||
782 | } | |||
783 | ||||
784 | static void ext_pwm_enable_backlight(const struct intel_crtc_state *crtc_state, | |||
785 | const struct drm_connector_state *conn_state, u32 level) | |||
786 | { | |||
787 | STUB()do { printf("%s: stub\n", __func__); } while(0); | |||
788 | #ifdef notyet | |||
789 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
790 | struct intel_panel *panel = &connector->panel; | |||
791 | ||||
792 | pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100); | |||
793 | panel->backlight.pwm_state.enabled = true1; | |||
794 | pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); | |||
795 | #endif | |||
796 | } | |||
797 | ||||
798 | static void __intel_backlight_enable(const struct intel_crtc_state *crtc_state, | |||
799 | const struct drm_connector_state *conn_state) | |||
800 | { | |||
801 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
802 | struct intel_panel *panel = &connector->panel; | |||
803 | ||||
804 | WARN_ON(panel->backlight.max == 0)({ int __ret = !!(panel->backlight.max == 0); if (__ret) printf ("WARNING %s failed at %s:%d\n", "panel->backlight.max == 0" , "/usr/src/sys/dev/pci/drm/i915/display/intel_backlight.c", 804 ); __builtin_expect(!!(__ret), 0); }); | |||
805 | ||||
806 | if (panel->backlight.level <= panel->backlight.min) { | |||
807 | panel->backlight.level = panel->backlight.max; | |||
808 | if (panel->backlight.device) | |||
809 | panel->backlight.device->props.brightness = | |||
810 | scale_hw_to_user(connector, | |||
811 | panel->backlight.level, | |||
812 | panel->backlight.device->props.max_brightness); | |||
813 | } | |||
814 | ||||
815 | panel->backlight.funcs->enable(crtc_state, conn_state, panel->backlight.level); | |||
816 | panel->backlight.enabled = true1; | |||
817 | if (panel->backlight.device) | |||
818 | panel->backlight.device->props.power = FB_BLANK_UNBLANK0; | |||
819 | } | |||
820 | ||||
821 | void intel_backlight_enable(const struct intel_crtc_state *crtc_state, | |||
822 | const struct drm_connector_state *conn_state) | |||
823 | { | |||
824 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
825 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
826 | struct intel_panel *panel = &connector->panel; | |||
827 | enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr = (crtc_state->uapi.crtc); (struct intel_crtc *)( (char * )__mptr - __builtin_offsetof(struct intel_crtc, base) );})->pipe; | |||
828 | ||||
829 | if (!panel->backlight.present) | |||
830 | return; | |||
831 | ||||
832 | drm_dbg_kms(&dev_priv->drm, "pipe %c\n", pipe_name(pipe))__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "pipe %c\n", ((pipe ) + 'A')); | |||
833 | ||||
834 | mutex_lock(&dev_priv->display.backlight.lock)rw_enter_write(&dev_priv->display.backlight.lock); | |||
835 | ||||
836 | __intel_backlight_enable(crtc_state, conn_state); | |||
837 | ||||
838 | mutex_unlock(&dev_priv->display.backlight.lock)rw_exit_write(&dev_priv->display.backlight.lock); | |||
839 | } | |||
840 | ||||
841 | #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)1 | |||
842 | static u32 intel_panel_get_backlight(struct intel_connector *connector) | |||
843 | { | |||
844 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
845 | struct intel_panel *panel = &connector->panel; | |||
846 | u32 val = 0; | |||
847 | ||||
848 | mutex_lock(&dev_priv->display.backlight.lock)rw_enter_write(&dev_priv->display.backlight.lock); | |||
849 | ||||
850 | if (panel->backlight.enabled) | |||
851 | val = panel->backlight.funcs->get(connector, intel_connector_get_pipe(connector)); | |||
852 | ||||
853 | mutex_unlock(&dev_priv->display.backlight.lock)rw_exit_write(&dev_priv->display.backlight.lock); | |||
854 | ||||
855 | drm_dbg_kms(&dev_priv->drm, "get backlight PWM = %d\n", val)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "get backlight PWM = %d\n" , val); | |||
856 | return val; | |||
857 | } | |||
858 | ||||
859 | /* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */ | |||
860 | static u32 scale_user_to_hw(struct intel_connector *connector, | |||
861 | u32 user_level, u32 user_max) | |||
862 | { | |||
863 | struct intel_panel *panel = &connector->panel; | |||
864 | ||||
865 | return scale(user_level, 0, user_max, | |||
866 | panel->backlight.min, panel->backlight.max); | |||
867 | } | |||
868 | ||||
869 | /* set backlight brightness to level in range [0..max], scaling wrt hw min */ | |||
870 | static void intel_panel_set_backlight(const struct drm_connector_state *conn_state, | |||
871 | u32 user_level, u32 user_max) | |||
872 | { | |||
873 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
874 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
875 | struct intel_panel *panel = &connector->panel; | |||
876 | u32 hw_level; | |||
877 | ||||
878 | if (!panel->backlight.present) | |||
879 | return; | |||
880 | ||||
881 | mutex_lock(&dev_priv->display.backlight.lock)rw_enter_write(&dev_priv->display.backlight.lock); | |||
882 | ||||
883 | drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0)({ int __ret = !!((panel->backlight.max == 0)); if (__ret) printf("%s %s: " "%s", dev_driver_string(((&dev_priv-> drm))->dev), "", "drm_WARN_ON(" "panel->backlight.max == 0" ")"); __builtin_expect(!!(__ret), 0); }); | |||
884 | ||||
885 | hw_level = scale_user_to_hw(connector, user_level, user_max); | |||
886 | panel->backlight.level = hw_level; | |||
887 | ||||
888 | if (panel->backlight.enabled) | |||
889 | intel_panel_actually_set_backlight(conn_state, hw_level); | |||
890 | ||||
891 | mutex_unlock(&dev_priv->display.backlight.lock)rw_exit_write(&dev_priv->display.backlight.lock); | |||
892 | } | |||
893 | ||||
894 | static int intel_backlight_device_update_status(struct backlight_device *bd) | |||
895 | { | |||
896 | struct intel_connector *connector = bl_get_data(bd); | |||
897 | struct intel_panel *panel = &connector->panel; | |||
898 | struct drm_device *dev = connector->base.dev; | |||
899 | ||||
900 | drm_modeset_lock(&dev->mode_config.connection_mutex, NULL((void *)0)); | |||
901 | DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",___drm_dbg(((void *)0), DRM_UT_KMS, "updating intel_backlight, brightness=%d/%d\n" , bd->props.brightness, bd->props.max_brightness) | |||
902 | bd->props.brightness, bd->props.max_brightness)___drm_dbg(((void *)0), DRM_UT_KMS, "updating intel_backlight, brightness=%d/%d\n" , bd->props.brightness, bd->props.max_brightness); | |||
903 | intel_panel_set_backlight(connector->base.state, bd->props.brightness, | |||
904 | bd->props.max_brightness); | |||
905 | ||||
906 | /* | |||
907 | * Allow flipping bl_power as a sub-state of enabled. Sadly the | |||
908 | * backlight class device does not make it easy to differentiate | |||
909 | * between callbacks for brightness and bl_power, so our backlight_power | |||
910 | * callback needs to take this into account. | |||
911 | */ | |||
912 | if (panel->backlight.enabled) { | |||
913 | if (panel->backlight.power) { | |||
914 | bool_Bool enable = bd->props.power == FB_BLANK_UNBLANK0 && | |||
915 | bd->props.brightness != 0; | |||
916 | panel->backlight.power(connector, enable); | |||
917 | } | |||
918 | } else { | |||
919 | bd->props.power = FB_BLANK_POWERDOWN4; | |||
920 | } | |||
921 | ||||
922 | drm_modeset_unlock(&dev->mode_config.connection_mutex); | |||
923 | return 0; | |||
924 | } | |||
925 | ||||
926 | static int intel_backlight_device_get_brightness(struct backlight_device *bd) | |||
927 | { | |||
928 | struct intel_connector *connector = bl_get_data(bd); | |||
929 | struct drm_device *dev = connector->base.dev; | |||
930 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); | |||
931 | intel_wakeref_t wakeref; | |||
932 | int ret = 0; | |||
933 | ||||
934 | with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref)for ((wakeref) = intel_runtime_pm_get(&dev_priv->runtime_pm ); (wakeref); intel_runtime_pm_put((&dev_priv->runtime_pm ), (wakeref)), (wakeref) = 0) { | |||
935 | u32 hw_level; | |||
936 | ||||
937 | drm_modeset_lock(&dev->mode_config.connection_mutex, NULL((void *)0)); | |||
938 | ||||
939 | hw_level = intel_panel_get_backlight(connector); | |||
940 | ret = scale_hw_to_user(connector, | |||
941 | hw_level, bd->props.max_brightness); | |||
942 | ||||
943 | drm_modeset_unlock(&dev->mode_config.connection_mutex); | |||
944 | } | |||
945 | ||||
946 | return ret; | |||
947 | } | |||
948 | ||||
949 | static const struct backlight_ops intel_backlight_device_ops = { | |||
950 | .update_status = intel_backlight_device_update_status, | |||
951 | .get_brightness = intel_backlight_device_get_brightness, | |||
952 | }; | |||
953 | ||||
954 | int intel_backlight_device_register(struct intel_connector *connector) | |||
955 | { | |||
956 | struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev); | |||
957 | struct intel_panel *panel = &connector->panel; | |||
958 | struct backlight_properties props; | |||
959 | struct backlight_device *bd; | |||
960 | const char *name; | |||
961 | int ret = 0; | |||
962 | ||||
963 | if (WARN_ON(panel->backlight.device)({ int __ret = !!(panel->backlight.device); if (__ret) printf ("WARNING %s failed at %s:%d\n", "panel->backlight.device" , "/usr/src/sys/dev/pci/drm/i915/display/intel_backlight.c", 963 ); __builtin_expect(!!(__ret), 0); })) | |||
964 | return -ENODEV19; | |||
965 | ||||
966 | if (!panel->backlight.present) | |||
967 | return 0; | |||
968 | ||||
969 | WARN_ON(panel->backlight.max == 0)({ int __ret = !!(panel->backlight.max == 0); if (__ret) printf ("WARNING %s failed at %s:%d\n", "panel->backlight.max == 0" , "/usr/src/sys/dev/pci/drm/i915/display/intel_backlight.c", 969 ); __builtin_expect(!!(__ret), 0); }); | |||
970 | ||||
971 | if (!acpi_video_backlight_use_native()) { | |||
972 | drm_info(&i915->drm, "Skipping intel_backlight registration\n")do { } while(0); | |||
973 | return 0; | |||
974 | } | |||
975 | ||||
976 | memset(&props, 0, sizeof(props))__builtin_memset((&props), (0), (sizeof(props))); | |||
977 | props.type = BACKLIGHT_RAW0; | |||
978 | ||||
979 | /* | |||
980 | * Note: Everything should work even if the backlight device max | |||
981 | * presented to the userspace is arbitrarily chosen. | |||
982 | */ | |||
983 | props.max_brightness = panel->backlight.max; | |||
984 | props.brightness = scale_hw_to_user(connector, | |||
985 | panel->backlight.level, | |||
986 | props.max_brightness); | |||
987 | ||||
988 | if (panel->backlight.enabled) | |||
989 | props.power = FB_BLANK_UNBLANK0; | |||
990 | else | |||
991 | props.power = FB_BLANK_POWERDOWN4; | |||
992 | ||||
993 | name = kstrdup("intel_backlight", GFP_KERNEL(0x0001 | 0x0004)); | |||
994 | if (!name) | |||
995 | return -ENOMEM12; | |||
996 | ||||
997 | bd = backlight_device_get_by_name(name); | |||
998 | if (bd) { | |||
999 | #ifdef __linux__ | |||
1000 | put_device(&bd->dev); | |||
1001 | #endif | |||
1002 | /* | |||
1003 | * Using the same name independent of the drm device or connector | |||
1004 | * prevents registration of multiple backlight devices in the | |||
1005 | * driver. However, we need to use the default name for backward | |||
1006 | * compatibility. Use unique names for subsequent backlight devices as a | |||
1007 | * fallback when the default name already exists. | |||
1008 | */ | |||
1009 | kfree(name); | |||
1010 | name = kasprintf(GFP_KERNEL(0x0001 | 0x0004), "card%d-%s-backlight", | |||
1011 | i915->drm.primary->index, connector->base.name); | |||
1012 | if (!name) | |||
1013 | return -ENOMEM12; | |||
1014 | } | |||
1015 | bd = backlight_device_register(name, connector->base.kdev, connector, | |||
1016 | &intel_backlight_device_ops, &props); | |||
1017 | ||||
1018 | if (IS_ERR(bd)) { | |||
1019 | drm_err(&i915->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[CONNECTOR:%d:%s] backlight device %s register failed: %ld\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , connector ->base.base.id, connector->base.name, name, PTR_ERR(bd) ) | |||
1020 | "[CONNECTOR:%d:%s] backlight device %s register failed: %ld\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[CONNECTOR:%d:%s] backlight device %s register failed: %ld\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , connector ->base.base.id, connector->base.name, name, PTR_ERR(bd) ) | |||
1021 | connector->base.base.id, connector->base.name, name, PTR_ERR(bd))printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "[CONNECTOR:%d:%s] backlight device %s register failed: %ld\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , connector ->base.base.id, connector->base.name, name, PTR_ERR(bd) ); | |||
1022 | ret = PTR_ERR(bd); | |||
1023 | goto out; | |||
1024 | } | |||
1025 | ||||
1026 | panel->backlight.device = bd; | |||
1027 | ||||
1028 | drm_dbg_kms(&i915->drm,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] backlight device %s registered\n" , connector->base.base.id, connector->base.name, name) | |||
1029 | "[CONNECTOR:%d:%s] backlight device %s registered\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] backlight device %s registered\n" , connector->base.base.id, connector->base.name, name) | |||
1030 | connector->base.base.id, connector->base.name, name)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915-> drm)->dev : ((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s] backlight device %s registered\n" , connector->base.base.id, connector->base.name, name); | |||
1031 | ||||
1032 | out: | |||
1033 | kfree(name); | |||
1034 | ||||
1035 | return ret; | |||
1036 | } | |||
1037 | ||||
1038 | void intel_backlight_device_unregister(struct intel_connector *connector) | |||
1039 | { | |||
1040 | struct intel_panel *panel = &connector->panel; | |||
1041 | ||||
1042 | if (panel->backlight.device) { | |||
1043 | backlight_device_unregister(panel->backlight.device); | |||
1044 | panel->backlight.device = NULL((void *)0); | |||
1045 | } | |||
1046 | } | |||
1047 | #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ | |||
1048 | ||||
1049 | /* | |||
1050 | * CNP: PWM clock frequency is 19.2 MHz or 24 MHz. | |||
1051 | * PWM increment = 1 | |||
1052 | */ | |||
1053 | static u32 cnp_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) | |||
1054 | { | |||
1055 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1056 | ||||
1057 | return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq),((((1000 * ((&(dev_priv)->__runtime)->rawclk_freq)) ) + ((pwm_freq_hz) / 2)) / (pwm_freq_hz)) | |||
1058 | pwm_freq_hz)((((1000 * ((&(dev_priv)->__runtime)->rawclk_freq)) ) + ((pwm_freq_hz) / 2)) / (pwm_freq_hz)); | |||
1059 | } | |||
1060 | ||||
1061 | /* | |||
1062 | * BXT: PWM clock frequency = 19.2 MHz. | |||
1063 | */ | |||
1064 | static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) | |||
1065 | { | |||
1066 | return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz)((((1000 * (19200))) + ((pwm_freq_hz) / 2)) / (pwm_freq_hz)); | |||
1067 | } | |||
1068 | ||||
1069 | /* | |||
1070 | * SPT: This value represents the period of the PWM stream in clock periods | |||
1071 | * multiplied by 16 (default increment) or 128 (alternate increment selected in | |||
1072 | * SCHICKEN_1 bit 0). PWM clock is 24 MHz. | |||
1073 | */ | |||
1074 | static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) | |||
1075 | { | |||
1076 | struct intel_panel *panel = &connector->panel; | |||
1077 | u32 mul; | |||
1078 | ||||
1079 | if (panel->backlight.alternate_pwm_increment) | |||
1080 | mul = 128; | |||
1081 | else | |||
1082 | mul = 16; | |||
1083 | ||||
1084 | return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul)((((1000 * (1000 * (24)))) + ((pwm_freq_hz * mul) / 2)) / (pwm_freq_hz * mul)); | |||
1085 | } | |||
1086 | ||||
1087 | /* | |||
1088 | * LPT: This value represents the period of the PWM stream in clock periods | |||
1089 | * multiplied by 128 (default increment) or 16 (alternate increment, selected in | |||
1090 | * LPT SOUTH_CHICKEN2 register bit 5). | |||
1091 | */ | |||
1092 | static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) | |||
1093 | { | |||
1094 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1095 | struct intel_panel *panel = &connector->panel; | |||
1096 | u32 mul, clock; | |||
1097 | ||||
1098 | if (panel->backlight.alternate_pwm_increment) | |||
1099 | mul = 16; | |||
1100 | else | |||
1101 | mul = 128; | |||
1102 | ||||
1103 | if (HAS_PCH_LPT_H(dev_priv)(((dev_priv)->pch_id) == 0x8c00 || ((dev_priv)->pch_id) == 0x8c80)) | |||
1104 | clock = MHz(135)(1000 * (1000 * (135))); /* LPT:H */ | |||
1105 | else | |||
1106 | clock = MHz(24)(1000 * (1000 * (24))); /* LPT:LP */ | |||
1107 | ||||
1108 | return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul)(((clock) + ((pwm_freq_hz * mul) / 2)) / (pwm_freq_hz * mul)); | |||
1109 | } | |||
1110 | ||||
1111 | /* | |||
1112 | * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH | |||
1113 | * display raw clocks multiplied by 128. | |||
1114 | */ | |||
1115 | static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) | |||
1116 | { | |||
1117 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1118 | ||||
1119 | return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq),((((1000 * ((&(dev_priv)->__runtime)->rawclk_freq)) ) + ((pwm_freq_hz * 128) / 2)) / (pwm_freq_hz * 128)) | |||
1120 | pwm_freq_hz * 128)((((1000 * ((&(dev_priv)->__runtime)->rawclk_freq)) ) + ((pwm_freq_hz * 128) / 2)) / (pwm_freq_hz * 128)); | |||
1121 | } | |||
1122 | ||||
1123 | /* | |||
1124 | * Gen2: This field determines the number of time base events (display core | |||
1125 | * clock frequency/32) in total for a complete cycle of modulated backlight | |||
1126 | * control. | |||
1127 | * | |||
1128 | * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock) | |||
1129 | * divided by 32. | |||
1130 | */ | |||
1131 | static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) | |||
1132 | { | |||
1133 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1134 | int clock; | |||
1135 | ||||
1136 | if (IS_PINEVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_PINEVIEW)) | |||
1137 | clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq)(1000 * ((&(dev_priv)->__runtime)->rawclk_freq)); | |||
1138 | else | |||
1139 | clock = KHz(dev_priv->display.cdclk.hw.cdclk)(1000 * (dev_priv->display.cdclk.hw.cdclk)); | |||
1140 | ||||
1141 | return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32)(((clock) + ((pwm_freq_hz * 32) / 2)) / (pwm_freq_hz * 32)); | |||
1142 | } | |||
1143 | ||||
1144 | /* | |||
1145 | * Gen4: This value represents the period of the PWM stream in display core | |||
1146 | * clocks ([DevCTG] HRAW clocks) multiplied by 128. | |||
1147 | * | |||
1148 | */ | |||
1149 | static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) | |||
1150 | { | |||
1151 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1152 | int clock; | |||
1153 | ||||
1154 | if (IS_G4X(dev_priv)(IS_PLATFORM(dev_priv, INTEL_G45) || IS_PLATFORM(dev_priv, INTEL_GM45 ))) | |||
1155 | clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq)(1000 * ((&(dev_priv)->__runtime)->rawclk_freq)); | |||
1156 | else | |||
1157 | clock = KHz(dev_priv->display.cdclk.hw.cdclk)(1000 * (dev_priv->display.cdclk.hw.cdclk)); | |||
1158 | ||||
1159 | return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128)(((clock) + ((pwm_freq_hz * 128) / 2)) / (pwm_freq_hz * 128)); | |||
1160 | } | |||
1161 | ||||
1162 | /* | |||
1163 | * VLV: This value represents the period of the PWM stream in display core | |||
1164 | * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks | |||
1165 | * multiplied by 16. CHV uses a 19.2MHz S0IX clock. | |||
1166 | */ | |||
1167 | static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) | |||
1168 | { | |||
1169 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1170 | int mul, clock; | |||
1171 | ||||
1172 | if ((intel_de_read(dev_priv, CBR1_VLV((const i915_reg_t){ .reg = (0x180000 + 0x70400) })) & CBR_PWM_CLOCK_MUX_SELECT(1 << 30)) == 0) { | |||
1173 | if (IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) | |||
1174 | clock = KHz(19200)(1000 * (19200)); | |||
1175 | else | |||
1176 | clock = MHz(25)(1000 * (1000 * (25))); | |||
1177 | mul = 16; | |||
1178 | } else { | |||
1179 | clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq)(1000 * ((&(dev_priv)->__runtime)->rawclk_freq)); | |||
1180 | mul = 128; | |||
1181 | } | |||
1182 | ||||
1183 | return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul)(((clock) + ((pwm_freq_hz * mul) / 2)) / (pwm_freq_hz * mul)); | |||
1184 | } | |||
1185 | ||||
1186 | static u16 get_vbt_pwm_freq(struct intel_connector *connector) | |||
1187 | { | |||
1188 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1189 | u16 pwm_freq_hz = connector->panel.vbt.backlight.pwm_freq_hz; | |||
1190 | ||||
1191 | if (pwm_freq_hz) { | |||
1192 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "VBT defined backlight frequency %u Hz\n" , pwm_freq_hz) | |||
1193 | "VBT defined backlight frequency %u Hz\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "VBT defined backlight frequency %u Hz\n" , pwm_freq_hz) | |||
1194 | pwm_freq_hz)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "VBT defined backlight frequency %u Hz\n" , pwm_freq_hz); | |||
1195 | } else { | |||
1196 | pwm_freq_hz = 200; | |||
1197 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "default backlight frequency %u Hz\n" , pwm_freq_hz) | |||
1198 | "default backlight frequency %u Hz\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "default backlight frequency %u Hz\n" , pwm_freq_hz) | |||
1199 | pwm_freq_hz)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "default backlight frequency %u Hz\n" , pwm_freq_hz); | |||
1200 | } | |||
1201 | ||||
1202 | return pwm_freq_hz; | |||
1203 | } | |||
1204 | ||||
1205 | static u32 get_backlight_max_vbt(struct intel_connector *connector) | |||
1206 | { | |||
1207 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1208 | struct intel_panel *panel = &connector->panel; | |||
1209 | u16 pwm_freq_hz = get_vbt_pwm_freq(connector); | |||
1210 | u32 pwm; | |||
1211 | ||||
1212 | if (!panel->backlight.pwm_funcs->hz_to_pwm) { | |||
1213 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "backlight frequency conversion not supported\n" ) | |||
1214 | "backlight frequency conversion not supported\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "backlight frequency conversion not supported\n" ); | |||
1215 | return 0; | |||
1216 | } | |||
1217 | ||||
1218 | pwm = panel->backlight.pwm_funcs->hz_to_pwm(connector, pwm_freq_hz); | |||
1219 | if (!pwm) { | |||
1220 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "backlight frequency conversion failed\n" ) | |||
1221 | "backlight frequency conversion failed\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "backlight frequency conversion failed\n" ); | |||
1222 | return 0; | |||
1223 | } | |||
1224 | ||||
1225 | return pwm; | |||
1226 | } | |||
1227 | ||||
1228 | /* | |||
1229 | * Note: The setup hooks can't assume pipe is set! | |||
1230 | */ | |||
1231 | static u32 get_backlight_min_vbt(struct intel_connector *connector) | |||
1232 | { | |||
1233 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1234 | struct intel_panel *panel = &connector->panel; | |||
1235 | int min; | |||
1236 | ||||
1237 | drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0)({ int __ret = !!((panel->backlight.pwm_level_max == 0)); if (__ret) printf("%s %s: " "%s", dev_driver_string(((&dev_priv ->drm))->dev), "", "drm_WARN_ON(" "panel->backlight.pwm_level_max == 0" ")"); __builtin_expect(!!(__ret), 0); }); | |||
1238 | ||||
1239 | /* | |||
1240 | * XXX: If the vbt value is 255, it makes min equal to max, which leads | |||
1241 | * to problems. There are such machines out there. Either our | |||
1242 | * interpretation is wrong or the vbt has bogus data. Or both. Safeguard | |||
1243 | * against this by letting the minimum be at most (arbitrarily chosen) | |||
1244 | * 25% of the max. | |||
1245 | */ | |||
1246 | min = clamp_t(int, connector->panel.vbt.backlight.min_brightness, 0, 64)({ int __min_a = (({ int __max_a = (connector->panel.vbt.backlight .min_brightness); int __max_b = (0); __max_a > __max_b ? __max_a : __max_b; })); int __min_b = (64); __min_a < __min_b ? __min_a : __min_b; }); | |||
1247 | if (min != connector->panel.vbt.backlight.min_brightness) { | |||
1248 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "clamping VBT min backlight %d/255 to %d/255\n" , connector->panel.vbt.backlight.min_brightness, min) | |||
1249 | "clamping VBT min backlight %d/255 to %d/255\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "clamping VBT min backlight %d/255 to %d/255\n" , connector->panel.vbt.backlight.min_brightness, min) | |||
1250 | connector->panel.vbt.backlight.min_brightness, min)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "clamping VBT min backlight %d/255 to %d/255\n" , connector->panel.vbt.backlight.min_brightness, min); | |||
1251 | } | |||
1252 | ||||
1253 | /* vbt value is a coefficient in range [0..255] */ | |||
1254 | return scale(min, 0, 255, 0, panel->backlight.pwm_level_max); | |||
1255 | } | |||
1256 | ||||
1257 | static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused) | |||
1258 | { | |||
1259 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1260 | struct intel_panel *panel = &connector->panel; | |||
1261 | u32 cpu_ctl2, pch_ctl1, pch_ctl2, val; | |||
1262 | bool_Bool alt, cpu_mode; | |||
1263 | ||||
1264 | if (HAS_PCH_LPT(dev_priv)(((dev_priv)->pch_type) == PCH_LPT)) | |||
1265 | alt = intel_de_read(dev_priv, SOUTH_CHICKEN2((const i915_reg_t){ .reg = (0xc2004) })) & LPT_PWM_GRANULARITY(1 << 5); | |||
1266 | else | |||
1267 | alt = intel_de_read(dev_priv, SOUTH_CHICKEN1((const i915_reg_t){ .reg = (0xc2000) })) & SPT_PWM_GRANULARITY(1 << 0); | |||
1268 | panel->backlight.alternate_pwm_increment = alt; | |||
1269 | ||||
1270 | pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) })); | |||
1271 | panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY(1 << 29); | |||
1272 | ||||
1273 | pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) })); | |||
1274 | panel->backlight.pwm_level_max = pch_ctl2 >> 16; | |||
1275 | ||||
1276 | cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) })); | |||
1277 | ||||
1278 | if (!panel->backlight.pwm_level_max) | |||
1279 | panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); | |||
1280 | ||||
1281 | if (!panel->backlight.pwm_level_max) | |||
1282 | return -ENODEV19; | |||
1283 | ||||
1284 | panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); | |||
1285 | ||||
1286 | panel->backlight.pwm_enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE(1 << 31); | |||
1287 | ||||
1288 | cpu_mode = panel->backlight.pwm_enabled && HAS_PCH_LPT(dev_priv)(((dev_priv)->pch_type) == PCH_LPT) && | |||
1289 | !(pch_ctl1 & BLM_PCH_OVERRIDE_ENABLE(1 << 30)) && | |||
1290 | (cpu_ctl2 & BLM_PWM_ENABLE(1 << 31)); | |||
1291 | ||||
1292 | if (cpu_mode) { | |||
1293 | val = pch_get_backlight(connector, unused); | |||
1294 | ||||
1295 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "CPU backlight register was enabled, switching to PCH override\n" ) | |||
1296 | "CPU backlight register was enabled, switching to PCH override\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "CPU backlight register was enabled, switching to PCH override\n" ); | |||
1297 | ||||
1298 | /* Write converted CPU PWM value to PCH override register */ | |||
1299 | lpt_set_backlight(connector->base.state, val); | |||
1300 | intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), | |||
1301 | pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE(1 << 30)); | |||
1302 | ||||
1303 | intel_de_write(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }), | |||
1304 | cpu_ctl2 & ~BLM_PWM_ENABLE(1 << 31)); | |||
1305 | } | |||
1306 | ||||
1307 | return 0; | |||
1308 | } | |||
1309 | ||||
1310 | static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused) | |||
1311 | { | |||
1312 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1313 | struct intel_panel *panel = &connector->panel; | |||
1314 | u32 cpu_ctl2, pch_ctl1, pch_ctl2; | |||
1315 | ||||
1316 | pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) })); | |||
1317 | panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY(1 << 29); | |||
1318 | ||||
1319 | pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) })); | |||
1320 | panel->backlight.pwm_level_max = pch_ctl2 >> 16; | |||
1321 | ||||
1322 | if (!panel->backlight.pwm_level_max) | |||
1323 | panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); | |||
1324 | ||||
1325 | if (!panel->backlight.pwm_level_max) | |||
1326 | return -ENODEV19; | |||
1327 | ||||
1328 | panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); | |||
1329 | ||||
1330 | cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) })); | |||
1331 | panel->backlight.pwm_enabled = (cpu_ctl2 & BLM_PWM_ENABLE(1 << 31)) && | |||
1332 | (pch_ctl1 & BLM_PCH_PWM_ENABLE(1 << 31)); | |||
1333 | ||||
1334 | return 0; | |||
1335 | } | |||
1336 | ||||
1337 | static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused) | |||
1338 | { | |||
1339 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1340 | struct intel_panel *panel = &connector->panel; | |||
1341 | u32 ctl, val; | |||
1342 | ||||
1343 | ctl = intel_de_read(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61254) })); | |||
1344 | ||||
1345 | if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) == 2 || IS_I915GM(dev_priv)IS_PLATFORM(dev_priv, INTEL_I915GM) || IS_I945GM(dev_priv)IS_PLATFORM(dev_priv, INTEL_I945GM)) | |||
1346 | panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE(1 << 16); | |||
1347 | ||||
1348 | if (IS_PINEVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_PINEVIEW)) | |||
1349 | panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV(1 << 0); | |||
1350 | ||||
1351 | panel->backlight.pwm_level_max = ctl >> 17; | |||
1352 | ||||
1353 | if (!panel->backlight.pwm_level_max) { | |||
1354 | panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); | |||
1355 | panel->backlight.pwm_level_max >>= 1; | |||
1356 | } | |||
1357 | ||||
1358 | if (!panel->backlight.pwm_level_max) | |||
1359 | return -ENODEV19; | |||
1360 | ||||
1361 | if (panel->backlight.combination_mode) | |||
1362 | panel->backlight.pwm_level_max *= 0xff; | |||
1363 | ||||
1364 | panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); | |||
1365 | ||||
1366 | val = i9xx_get_backlight(connector, unused); | |||
1367 | val = intel_backlight_invert_pwm_level(connector, val); | |||
1368 | val = clamp(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max)({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val); __typeof(val) __max_b = (panel->backlight.pwm_level_min); __max_a > __max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel->backlight.pwm_level_max); __min_a < __min_b ? __min_a : __min_b; }); | |||
1369 | ||||
1370 | panel->backlight.pwm_enabled = val != 0; | |||
1371 | ||||
1372 | return 0; | |||
1373 | } | |||
1374 | ||||
1375 | static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused) | |||
1376 | { | |||
1377 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1378 | struct intel_panel *panel = &connector->panel; | |||
1379 | u32 ctl, ctl2; | |||
1380 | ||||
1381 | ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61250) })); | |||
1382 | panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE(1 << 30); | |||
1383 | panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965(1 << 28); | |||
1384 | ||||
1385 | ctl = intel_de_read(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)-> display.mmio_offset) + 0x61254) })); | |||
1386 | panel->backlight.pwm_level_max = ctl >> 16; | |||
1387 | ||||
1388 | if (!panel->backlight.pwm_level_max) | |||
1389 | panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); | |||
1390 | ||||
1391 | if (!panel->backlight.pwm_level_max) | |||
1392 | return -ENODEV19; | |||
1393 | ||||
1394 | if (panel->backlight.combination_mode) | |||
1395 | panel->backlight.pwm_level_max *= 0xff; | |||
1396 | ||||
1397 | panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); | |||
1398 | ||||
1399 | panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE(1 << 31); | |||
1400 | ||||
1401 | return 0; | |||
1402 | } | |||
1403 | ||||
1404 | static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe) | |||
1405 | { | |||
1406 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1407 | struct intel_panel *panel = &connector->panel; | |||
1408 | u32 ctl, ctl2; | |||
1409 | ||||
1410 | if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B)({ int __ret = !!((pipe != PIPE_A && pipe != PIPE_B)) ; if (__ret) printf("%s %s: " "%s", dev_driver_string(((& dev_priv->drm))->dev), "", "drm_WARN_ON(" "pipe != PIPE_A && pipe != PIPE_B" ")"); __builtin_expect(!!(__ret), 0); })) | |||
1411 | return -ENODEV19; | |||
1412 | ||||
1413 | ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info) ->display.mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv )->__info)->display.mmio_offset) + 0x61350)) - ((((& (dev_priv)->__info)->display.mmio_offset) + 0x61250)))) ) })); | |||
1414 | panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965(1 << 28); | |||
1415 | ||||
1416 | ctl = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info) ->display.mmio_offset) + 0x61254)) + (pipe) * (((((&(dev_priv )->__info)->display.mmio_offset) + 0x61354)) - ((((& (dev_priv)->__info)->display.mmio_offset) + 0x61254)))) ) })); | |||
1417 | panel->backlight.pwm_level_max = ctl >> 16; | |||
1418 | ||||
1419 | if (!panel->backlight.pwm_level_max) | |||
1420 | panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); | |||
1421 | ||||
1422 | if (!panel->backlight.pwm_level_max) | |||
1423 | return -ENODEV19; | |||
1424 | ||||
1425 | panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); | |||
1426 | ||||
1427 | panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE(1 << 31); | |||
1428 | ||||
1429 | return 0; | |||
1430 | } | |||
1431 | ||||
1432 | static int | |||
1433 | bxt_setup_backlight(struct intel_connector *connector, enum pipe unused) | |||
1434 | { | |||
1435 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1436 | struct intel_panel *panel = &connector->panel; | |||
1437 | u32 pwm_ctl, val; | |||
1438 | ||||
1439 | panel->backlight.controller = connector->panel.vbt.backlight.controller; | |||
1440 | ||||
1441 | pwm_ctl = intel_de_read(dev_priv, | |||
1442 | BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) })); | |||
1443 | ||||
1444 | /* Controller 1 uses the utility pin. */ | |||
1445 | if (panel->backlight.controller == 1) { | |||
1446 | val = intel_de_read(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) })); | |||
1447 | panel->backlight.util_pin_active_low = | |||
1448 | val & UTIL_PIN_POLARITY(1 << 22); | |||
1449 | } | |||
1450 | ||||
1451 | panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY(1 << 29); | |||
1452 | panel->backlight.pwm_level_max = | |||
1453 | intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8254) + (panel->backlight .controller) * ((0xC8354) - (0xC8254)))) })); | |||
1454 | ||||
1455 | if (!panel->backlight.pwm_level_max) | |||
1456 | panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); | |||
1457 | ||||
1458 | if (!panel->backlight.pwm_level_max) | |||
1459 | return -ENODEV19; | |||
1460 | ||||
1461 | panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); | |||
1462 | ||||
1463 | panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE(1 << 31); | |||
1464 | ||||
1465 | return 0; | |||
1466 | } | |||
1467 | ||||
1468 | static int | |||
1469 | cnp_setup_backlight(struct intel_connector *connector, enum pipe unused) | |||
1470 | { | |||
1471 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1472 | struct intel_panel *panel = &connector->panel; | |||
1473 | u32 pwm_ctl; | |||
1474 | ||||
1475 | /* | |||
1476 | * CNP has the BXT implementation of backlight, but with only one | |||
1477 | * controller. TODO: ICP has multiple controllers but we only use | |||
1478 | * controller 0 for now. | |||
1479 | */ | |||
1480 | panel->backlight.controller = 0; | |||
1481 | ||||
1482 | pwm_ctl = intel_de_read(dev_priv, | |||
1483 | BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight .controller) * ((0xC8350) - (0xC8250)))) })); | |||
1484 | ||||
1485 | panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY(1 << 29); | |||
1486 | panel->backlight.pwm_level_max = | |||
1487 | intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8254) + (panel->backlight .controller) * ((0xC8354) - (0xC8254)))) })); | |||
1488 | ||||
1489 | if (!panel->backlight.pwm_level_max) | |||
1490 | panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); | |||
1491 | ||||
1492 | if (!panel->backlight.pwm_level_max) | |||
1493 | return -ENODEV19; | |||
1494 | ||||
1495 | panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); | |||
1496 | ||||
1497 | panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE(1 << 31); | |||
1498 | ||||
1499 | return 0; | |||
1500 | } | |||
1501 | ||||
1502 | static int ext_pwm_setup_backlight(struct intel_connector *connector, | |||
1503 | enum pipe pipe) | |||
1504 | { | |||
1505 | struct drm_device *dev = connector->base.dev; | |||
1506 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev); | |||
1507 | struct intel_panel *panel = &connector->panel; | |||
1508 | const char *desc; | |||
1509 | u32 level; | |||
1510 | ||||
1511 | /* Get the right PWM chip for DSI backlight according to VBT */ | |||
1512 | if (connector->panel.vbt.dsi.config->pwm_blc == PPS_BLC_PMIC0) { | |||
1513 | panel->backlight.pwm = pwm_get(dev->dev, "pwm_pmic_backlight"); | |||
1514 | desc = "PMIC"; | |||
1515 | } else { | |||
1516 | panel->backlight.pwm = pwm_get(dev->dev, "pwm_soc_backlight"); | |||
1517 | desc = "SoC"; | |||
1518 | } | |||
1519 | ||||
1520 | if (IS_ERR(panel->backlight.pwm)) { | |||
1521 | drm_err(&dev_priv->drm, "Failed to get the %s PWM chip\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to get the %s PWM chip\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , desc) | |||
1522 | desc)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to get the %s PWM chip\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , desc); | |||
1523 | panel->backlight.pwm = NULL((void *)0); | |||
1524 | return -ENODEV19; | |||
1525 | } | |||
1526 | ||||
1527 | panel->backlight.pwm_level_max = 100; /* 100% */ | |||
1528 | panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); | |||
1529 | ||||
1530 | #ifdef notyet | |||
1531 | if (pwm_is_enabled(panel->backlight.pwm)) { | |||
1532 | /* PWM is already enabled, use existing settings */ | |||
1533 | pwm_get_state(panel->backlight.pwm, &panel->backlight.pwm_state); | |||
1534 | ||||
1535 | level = pwm_get_relative_duty_cycle(&panel->backlight.pwm_state, | |||
1536 | 100); | |||
1537 | level = intel_backlight_invert_pwm_level(connector, level); | |||
1538 | panel->backlight.pwm_enabled = true1; | |||
1539 | ||||
1540 | drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "PWM already enabled at freq %ld, VBT freq %d, level %d\n" , 1000000000L / (unsigned long)panel->backlight.pwm_state. period, get_vbt_pwm_freq(connector), level) | |||
1541 | NSEC_PER_SEC / (unsigned long)panel->backlight.pwm_state.period,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "PWM already enabled at freq %ld, VBT freq %d, level %d\n" , 1000000000L / (unsigned long)panel->backlight.pwm_state. period, get_vbt_pwm_freq(connector), level) | |||
1542 | get_vbt_pwm_freq(connector), level)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "PWM already enabled at freq %ld, VBT freq %d, level %d\n" , 1000000000L / (unsigned long)panel->backlight.pwm_state. period, get_vbt_pwm_freq(connector), level); | |||
1543 | } else { | |||
1544 | /* Set period from VBT frequency, leave other settings at 0. */ | |||
1545 | panel->backlight.pwm_state.period = | |||
1546 | NSEC_PER_SEC1000000000L / get_vbt_pwm_freq(connector); | |||
1547 | } | |||
1548 | #else | |||
1549 | STUB()do { printf("%s: stub\n", __func__); } while(0); | |||
1550 | #endif | |||
1551 | ||||
1552 | drm_info(&dev_priv->drm, "Using %s PWM for LCD backlight control\n",do { } while(0) | |||
1553 | desc)do { } while(0); | |||
1554 | return 0; | |||
1555 | } | |||
1556 | ||||
1557 | static void intel_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level) | |||
1558 | { | |||
1559 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
1560 | struct intel_panel *panel = &connector->panel; | |||
1561 | ||||
1562 | panel->backlight.pwm_funcs->set(conn_state, | |||
1563 | intel_backlight_invert_pwm_level(connector, level)); | |||
1564 | } | |||
1565 | ||||
1566 | static u32 intel_pwm_get_backlight(struct intel_connector *connector, enum pipe pipe) | |||
1567 | { | |||
1568 | struct intel_panel *panel = &connector->panel; | |||
1569 | ||||
1570 | return intel_backlight_invert_pwm_level(connector, | |||
1571 | panel->backlight.pwm_funcs->get(connector, pipe)); | |||
1572 | } | |||
1573 | ||||
1574 | static void intel_pwm_enable_backlight(const struct intel_crtc_state *crtc_state, | |||
1575 | const struct drm_connector_state *conn_state, u32 level) | |||
1576 | { | |||
1577 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
1578 | struct intel_panel *panel = &connector->panel; | |||
1579 | ||||
1580 | panel->backlight.pwm_funcs->enable(crtc_state, conn_state, | |||
1581 | intel_backlight_invert_pwm_level(connector, level)); | |||
1582 | } | |||
1583 | ||||
1584 | static void intel_pwm_disable_backlight(const struct drm_connector_state *conn_state, u32 level) | |||
1585 | { | |||
1586 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
1587 | struct intel_panel *panel = &connector->panel; | |||
1588 | ||||
1589 | panel->backlight.pwm_funcs->disable(conn_state, | |||
1590 | intel_backlight_invert_pwm_level(connector, level)); | |||
1591 | } | |||
1592 | ||||
1593 | static int intel_pwm_setup_backlight(struct intel_connector *connector, enum pipe pipe) | |||
1594 | { | |||
1595 | struct intel_panel *panel = &connector->panel; | |||
1596 | int ret = panel->backlight.pwm_funcs->setup(connector, pipe); | |||
1597 | ||||
1598 | if (ret < 0) | |||
1599 | return ret; | |||
1600 | ||||
1601 | panel->backlight.min = panel->backlight.pwm_level_min; | |||
1602 | panel->backlight.max = panel->backlight.pwm_level_max; | |||
1603 | panel->backlight.level = intel_pwm_get_backlight(connector, pipe); | |||
1604 | panel->backlight.enabled = panel->backlight.pwm_enabled; | |||
1605 | ||||
1606 | return 0; | |||
1607 | } | |||
1608 | ||||
1609 | void intel_backlight_update(struct intel_atomic_state *state, | |||
1610 | struct intel_encoder *encoder, | |||
1611 | const struct intel_crtc_state *crtc_state, | |||
1612 | const struct drm_connector_state *conn_state) | |||
1613 | { | |||
1614 | struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) * __mptr = (conn_state->connector); (struct intel_connector * )( (char *)__mptr - __builtin_offsetof(struct intel_connector , base) );}); | |||
1615 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1616 | struct intel_panel *panel = &connector->panel; | |||
1617 | ||||
1618 | if (!panel->backlight.present) | |||
1619 | return; | |||
1620 | ||||
1621 | mutex_lock(&dev_priv->display.backlight.lock)rw_enter_write(&dev_priv->display.backlight.lock); | |||
1622 | if (!panel->backlight.enabled) | |||
1623 | __intel_backlight_enable(crtc_state, conn_state); | |||
1624 | ||||
1625 | mutex_unlock(&dev_priv->display.backlight.lock)rw_exit_write(&dev_priv->display.backlight.lock); | |||
1626 | } | |||
1627 | ||||
1628 | int intel_backlight_setup(struct intel_connector *connector, enum pipe pipe) | |||
1629 | { | |||
1630 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1631 | struct intel_panel *panel = &connector->panel; | |||
1632 | int ret; | |||
1633 | ||||
1634 | if (!connector->panel.vbt.backlight.present) { | |||
1635 | if (intel_has_quirk(dev_priv, QUIRK_BACKLIGHT_PRESENT)) { | |||
1636 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "no backlight present per VBT, but present per quirk\n" ) | |||
1637 | "no backlight present per VBT, but present per quirk\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "no backlight present per VBT, but present per quirk\n" ); | |||
1638 | } else { | |||
1639 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "no backlight present per VBT\n" ) | |||
1640 | "no backlight present per VBT\n")__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "no backlight present per VBT\n" ); | |||
1641 | return 0; | |||
1642 | } | |||
1643 | } | |||
1644 | ||||
1645 | /* ensure intel_panel has been initialized first */ | |||
1646 | if (drm_WARN_ON(&dev_priv->drm, !panel->backlight.funcs)({ int __ret = !!((!panel->backlight.funcs)); if (__ret) printf ("%s %s: " "%s", dev_driver_string(((&dev_priv->drm))-> dev), "", "drm_WARN_ON(" "!panel->backlight.funcs" ")"); __builtin_expect (!!(__ret), 0); })) | |||
1647 | return -ENODEV19; | |||
1648 | ||||
1649 | /* set level and max in panel struct */ | |||
1650 | mutex_lock(&dev_priv->display.backlight.lock)rw_enter_write(&dev_priv->display.backlight.lock); | |||
1651 | ret = panel->backlight.funcs->setup(connector, pipe); | |||
1652 | mutex_unlock(&dev_priv->display.backlight.lock)rw_exit_write(&dev_priv->display.backlight.lock); | |||
1653 | ||||
1654 | if (ret) { | |||
1655 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "failed to setup backlight for connector %s\n" , connector->base.name) | |||
1656 | "failed to setup backlight for connector %s\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "failed to setup backlight for connector %s\n" , connector->base.name) | |||
1657 | connector->base.name)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "failed to setup backlight for connector %s\n" , connector->base.name); | |||
1658 | return ret; | |||
1659 | } | |||
1660 | ||||
1661 | panel->backlight.present = true1; | |||
1662 | ||||
1663 | drm_dbg_kms(&dev_priv->drm,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Connector %s backlight initialized, %s, brightness %u/%u\n" , connector->base.name, str_enabled_disabled(panel->backlight .enabled), panel->backlight.level, panel->backlight.max ) | |||
1664 | "Connector %s backlight initialized, %s, brightness %u/%u\n",__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Connector %s backlight initialized, %s, brightness %u/%u\n" , connector->base.name, str_enabled_disabled(panel->backlight .enabled), panel->backlight.level, panel->backlight.max ) | |||
1665 | connector->base.name,__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Connector %s backlight initialized, %s, brightness %u/%u\n" , connector->base.name, str_enabled_disabled(panel->backlight .enabled), panel->backlight.level, panel->backlight.max ) | |||
1666 | str_enabled_disabled(panel->backlight.enabled),__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Connector %s backlight initialized, %s, brightness %u/%u\n" , connector->base.name, str_enabled_disabled(panel->backlight .enabled), panel->backlight.level, panel->backlight.max ) | |||
1667 | panel->backlight.level, panel->backlight.max)__drm_dev_dbg(((void *)0), (&dev_priv->drm) ? (&dev_priv ->drm)->dev : ((void *)0), DRM_UT_KMS, "Connector %s backlight initialized, %s, brightness %u/%u\n" , connector->base.name, str_enabled_disabled(panel->backlight .enabled), panel->backlight.level, panel->backlight.max ); | |||
1668 | ||||
1669 | return 0; | |||
1670 | } | |||
1671 | ||||
1672 | void intel_backlight_destroy(struct intel_panel *panel) | |||
1673 | { | |||
1674 | /* dispose of the pwm */ | |||
1675 | if (panel->backlight.pwm) | |||
1676 | pwm_put(panel->backlight.pwm); | |||
1677 | ||||
1678 | panel->backlight.present = false0; | |||
1679 | } | |||
1680 | ||||
1681 | static const struct intel_panel_bl_funcs bxt_pwm_funcs = { | |||
1682 | .setup = bxt_setup_backlight, | |||
1683 | .enable = bxt_enable_backlight, | |||
1684 | .disable = bxt_disable_backlight, | |||
1685 | .set = bxt_set_backlight, | |||
1686 | .get = bxt_get_backlight, | |||
1687 | .hz_to_pwm = bxt_hz_to_pwm, | |||
1688 | }; | |||
1689 | ||||
1690 | static const struct intel_panel_bl_funcs cnp_pwm_funcs = { | |||
1691 | .setup = cnp_setup_backlight, | |||
1692 | .enable = cnp_enable_backlight, | |||
1693 | .disable = cnp_disable_backlight, | |||
1694 | .set = bxt_set_backlight, | |||
1695 | .get = bxt_get_backlight, | |||
1696 | .hz_to_pwm = cnp_hz_to_pwm, | |||
1697 | }; | |||
1698 | ||||
1699 | static const struct intel_panel_bl_funcs lpt_pwm_funcs = { | |||
1700 | .setup = lpt_setup_backlight, | |||
1701 | .enable = lpt_enable_backlight, | |||
1702 | .disable = lpt_disable_backlight, | |||
1703 | .set = lpt_set_backlight, | |||
1704 | .get = lpt_get_backlight, | |||
1705 | .hz_to_pwm = lpt_hz_to_pwm, | |||
1706 | }; | |||
1707 | ||||
1708 | static const struct intel_panel_bl_funcs spt_pwm_funcs = { | |||
1709 | .setup = lpt_setup_backlight, | |||
1710 | .enable = lpt_enable_backlight, | |||
1711 | .disable = lpt_disable_backlight, | |||
1712 | .set = lpt_set_backlight, | |||
1713 | .get = lpt_get_backlight, | |||
1714 | .hz_to_pwm = spt_hz_to_pwm, | |||
1715 | }; | |||
1716 | ||||
1717 | static const struct intel_panel_bl_funcs pch_pwm_funcs = { | |||
1718 | .setup = pch_setup_backlight, | |||
1719 | .enable = pch_enable_backlight, | |||
1720 | .disable = pch_disable_backlight, | |||
1721 | .set = pch_set_backlight, | |||
1722 | .get = pch_get_backlight, | |||
1723 | .hz_to_pwm = pch_hz_to_pwm, | |||
1724 | }; | |||
1725 | ||||
1726 | static const struct intel_panel_bl_funcs ext_pwm_funcs = { | |||
1727 | .setup = ext_pwm_setup_backlight, | |||
1728 | .enable = ext_pwm_enable_backlight, | |||
1729 | .disable = ext_pwm_disable_backlight, | |||
1730 | .set = ext_pwm_set_backlight, | |||
1731 | .get = ext_pwm_get_backlight, | |||
1732 | }; | |||
1733 | ||||
1734 | static const struct intel_panel_bl_funcs vlv_pwm_funcs = { | |||
1735 | .setup = vlv_setup_backlight, | |||
1736 | .enable = vlv_enable_backlight, | |||
1737 | .disable = vlv_disable_backlight, | |||
1738 | .set = vlv_set_backlight, | |||
1739 | .get = vlv_get_backlight, | |||
1740 | .hz_to_pwm = vlv_hz_to_pwm, | |||
1741 | }; | |||
1742 | ||||
1743 | static const struct intel_panel_bl_funcs i965_pwm_funcs = { | |||
1744 | .setup = i965_setup_backlight, | |||
1745 | .enable = i965_enable_backlight, | |||
1746 | .disable = i965_disable_backlight, | |||
1747 | .set = i9xx_set_backlight, | |||
1748 | .get = i9xx_get_backlight, | |||
1749 | .hz_to_pwm = i965_hz_to_pwm, | |||
1750 | }; | |||
1751 | ||||
1752 | static const struct intel_panel_bl_funcs i9xx_pwm_funcs = { | |||
1753 | .setup = i9xx_setup_backlight, | |||
1754 | .enable = i9xx_enable_backlight, | |||
1755 | .disable = i9xx_disable_backlight, | |||
1756 | .set = i9xx_set_backlight, | |||
1757 | .get = i9xx_get_backlight, | |||
1758 | .hz_to_pwm = i9xx_hz_to_pwm, | |||
1759 | }; | |||
1760 | ||||
1761 | static const struct intel_panel_bl_funcs pwm_bl_funcs = { | |||
1762 | .setup = intel_pwm_setup_backlight, | |||
1763 | .enable = intel_pwm_enable_backlight, | |||
1764 | .disable = intel_pwm_disable_backlight, | |||
1765 | .set = intel_pwm_set_backlight, | |||
1766 | .get = intel_pwm_get_backlight, | |||
1767 | }; | |||
1768 | ||||
1769 | /* Set up chip specific backlight functions */ | |||
1770 | void intel_backlight_init_funcs(struct intel_panel *panel) | |||
1771 | { | |||
1772 | struct intel_connector *connector = | |||
1773 | container_of(panel, struct intel_connector, panel)({ const __typeof( ((struct intel_connector *)0)->panel ) * __mptr = (panel); (struct intel_connector *)( (char *)__mptr - __builtin_offsetof(struct intel_connector, panel) );}); | |||
1774 | struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev); | |||
1775 | ||||
1776 | if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI16 && | |||
1777 | intel_dsi_dcs_init_backlight_funcs(connector) == 0) | |||
1778 | return; | |||
1779 | ||||
1780 | if (IS_GEMINILAKE(dev_priv)IS_PLATFORM(dev_priv, INTEL_GEMINILAKE) || IS_BROXTON(dev_priv)IS_PLATFORM(dev_priv, INTEL_BROXTON)) { | |||
1781 | panel->backlight.pwm_funcs = &bxt_pwm_funcs; | |||
1782 | } else if (INTEL_PCH_TYPE(dev_priv)((dev_priv)->pch_type) >= PCH_CNP) { | |||
1783 | panel->backlight.pwm_funcs = &cnp_pwm_funcs; | |||
1784 | } else if (INTEL_PCH_TYPE(dev_priv)((dev_priv)->pch_type) >= PCH_LPT) { | |||
1785 | if (HAS_PCH_LPT(dev_priv)(((dev_priv)->pch_type) == PCH_LPT)) | |||
1786 | panel->backlight.pwm_funcs = &lpt_pwm_funcs; | |||
1787 | else | |||
1788 | panel->backlight.pwm_funcs = &spt_pwm_funcs; | |||
1789 | } else if (HAS_PCH_SPLIT(dev_priv)(((dev_priv)->pch_type) != PCH_NONE)) { | |||
1790 | panel->backlight.pwm_funcs = &pch_pwm_funcs; | |||
1791 | } else if (IS_VALLEYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) || IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) { | |||
1792 | if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI16) { | |||
1793 | panel->backlight.pwm_funcs = &ext_pwm_funcs; | |||
1794 | } else { | |||
1795 | panel->backlight.pwm_funcs = &vlv_pwm_funcs; | |||
1796 | } | |||
1797 | } else if (DISPLAY_VER(dev_priv)((&(dev_priv)->__runtime)->display.ip.ver) == 4) { | |||
1798 | panel->backlight.pwm_funcs = &i965_pwm_funcs; | |||
1799 | } else { | |||
1800 | panel->backlight.pwm_funcs = &i9xx_pwm_funcs; | |||
1801 | } | |||
1802 | ||||
1803 | if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP14) { | |||
1804 | if (intel_dp_aux_init_backlight_funcs(connector) == 0) | |||
1805 | return; | |||
1806 | ||||
1807 | if (!intel_has_quirk(dev_priv, QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK)) | |||
1808 | connector->panel.backlight.power = intel_pps_backlight_power; | |||
1809 | } | |||
1810 | ||||
1811 | /* We're using a standard PWM backlight interface */ | |||
1812 | panel->backlight.funcs = &pwm_bl_funcs; | |||
1813 | } |