1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright © 2006-2009 Intel Corporation |
4 | * |
5 | * Authors: |
6 | * Eric Anholt <eric@anholt.net> |
7 | * Dave Airlie <airlied@linux.ie> |
8 | * Jesse Barnes <jesse.barnes@intel.com> |
9 | */ |
10 | |
11 | #include <linux/i2c.h> |
12 | #include <linux/pm_runtime.h> |
13 | |
14 | #include <asm/intel-mid.h> |
15 | |
16 | #include <drm/drm_edid.h> |
17 | #include <drm/drm_modeset_helper_vtables.h> |
18 | #include <drm/drm_simple_kms_helper.h> |
19 | |
20 | #include "intel_bios.h" |
21 | #include "power.h" |
22 | #include "psb_drv.h" |
23 | #include "psb_intel_drv.h" |
24 | #include "psb_intel_reg.h" |
25 | |
26 | /* The max/min PWM frequency in BPCR[31:17] - */ |
27 | /* The smallest number is 1 (not 0) that can fit in the |
28 | * 15-bit field of the and then*/ |
29 | /* shifts to the left by one bit to get the actual 16-bit |
30 | * value that the 15-bits correspond to.*/ |
31 | #define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF |
32 | #define BRIGHTNESS_MAX_LEVEL 100 |
33 | |
34 | /* |
35 | * Sets the power state for the panel. |
36 | */ |
37 | static void oaktrail_lvds_set_power(struct drm_device *dev, |
38 | struct gma_encoder *gma_encoder, |
39 | bool on) |
40 | { |
41 | u32 pp_status; |
42 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
43 | |
44 | if (!gma_power_begin(dev, force: true)) |
45 | return; |
46 | |
47 | if (on) { |
48 | REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | |
49 | POWER_TARGET_ON); |
50 | do { |
51 | pp_status = REG_READ(PP_STATUS); |
52 | } while ((pp_status & (PP_ON | PP_READY)) == PP_READY); |
53 | dev_priv->is_lvds_on = true; |
54 | if (dev_priv->ops->lvds_bl_power) |
55 | dev_priv->ops->lvds_bl_power(dev, true); |
56 | } else { |
57 | if (dev_priv->ops->lvds_bl_power) |
58 | dev_priv->ops->lvds_bl_power(dev, false); |
59 | REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & |
60 | ~POWER_TARGET_ON); |
61 | do { |
62 | pp_status = REG_READ(PP_STATUS); |
63 | } while (pp_status & PP_ON); |
64 | dev_priv->is_lvds_on = false; |
65 | } |
66 | gma_power_end(dev); |
67 | } |
68 | |
69 | static void oaktrail_lvds_dpms(struct drm_encoder *encoder, int mode) |
70 | { |
71 | struct drm_device *dev = encoder->dev; |
72 | struct gma_encoder *gma_encoder = to_gma_encoder(encoder); |
73 | |
74 | if (mode == DRM_MODE_DPMS_ON) |
75 | oaktrail_lvds_set_power(dev, gma_encoder, on: true); |
76 | else |
77 | oaktrail_lvds_set_power(dev, gma_encoder, on: false); |
78 | |
79 | /* XXX: We never power down the LVDS pairs. */ |
80 | } |
81 | |
82 | static void oaktrail_lvds_mode_set(struct drm_encoder *encoder, |
83 | struct drm_display_mode *mode, |
84 | struct drm_display_mode *adjusted_mode) |
85 | { |
86 | struct drm_device *dev = encoder->dev; |
87 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
88 | struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; |
89 | struct drm_connector_list_iter conn_iter; |
90 | struct drm_connector *connector = NULL; |
91 | struct drm_crtc *crtc = encoder->crtc; |
92 | u32 lvds_port; |
93 | uint64_t v = DRM_MODE_SCALE_FULLSCREEN; |
94 | |
95 | if (!gma_power_begin(dev, force: true)) |
96 | return; |
97 | |
98 | /* |
99 | * The LVDS pin pair will already have been turned on in the |
100 | * psb_intel_crtc_mode_set since it has a large impact on the DPLL |
101 | * settings. |
102 | */ |
103 | lvds_port = (REG_READ(LVDS) & |
104 | (~LVDS_PIPEB_SELECT)) | |
105 | LVDS_PORT_EN | |
106 | LVDS_BORDER_EN; |
107 | |
108 | /* If the firmware says dither on Moorestown, or the BIOS does |
109 | on Oaktrail then enable dithering */ |
110 | if (mode_dev->panel_wants_dither || dev_priv->lvds_dither) |
111 | lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE; |
112 | |
113 | REG_WRITE(LVDS, lvds_port); |
114 | |
115 | /* Find the connector we're trying to set up */ |
116 | drm_connector_list_iter_begin(dev, iter: &conn_iter); |
117 | drm_for_each_connector_iter(connector, &conn_iter) { |
118 | if (connector->encoder && connector->encoder->crtc == crtc) |
119 | break; |
120 | } |
121 | |
122 | if (!connector) { |
123 | drm_connector_list_iter_end(iter: &conn_iter); |
124 | DRM_ERROR("Couldn't find connector when setting mode" ); |
125 | gma_power_end(dev); |
126 | return; |
127 | } |
128 | |
129 | drm_object_property_get_value( obj: &connector->base, |
130 | property: dev->mode_config.scaling_mode_property, value: &v); |
131 | drm_connector_list_iter_end(iter: &conn_iter); |
132 | |
133 | if (v == DRM_MODE_SCALE_NO_SCALE) |
134 | REG_WRITE(PFIT_CONTROL, 0); |
135 | else if (v == DRM_MODE_SCALE_ASPECT) { |
136 | if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) || |
137 | (mode->hdisplay != adjusted_mode->crtc_hdisplay)) { |
138 | if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) == |
139 | (mode->hdisplay * adjusted_mode->crtc_vdisplay)) |
140 | REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); |
141 | else if ((adjusted_mode->crtc_hdisplay * |
142 | mode->vdisplay) > (mode->hdisplay * |
143 | adjusted_mode->crtc_vdisplay)) |
144 | REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | |
145 | PFIT_SCALING_MODE_PILLARBOX); |
146 | else |
147 | REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | |
148 | PFIT_SCALING_MODE_LETTERBOX); |
149 | } else |
150 | REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); |
151 | } else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/ |
152 | REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); |
153 | |
154 | gma_power_end(dev); |
155 | } |
156 | |
157 | static void oaktrail_lvds_prepare(struct drm_encoder *encoder) |
158 | { |
159 | struct drm_device *dev = encoder->dev; |
160 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
161 | struct gma_encoder *gma_encoder = to_gma_encoder(encoder); |
162 | struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; |
163 | |
164 | if (!gma_power_begin(dev, force: true)) |
165 | return; |
166 | |
167 | mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); |
168 | mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL & |
169 | BACKLIGHT_DUTY_CYCLE_MASK); |
170 | oaktrail_lvds_set_power(dev, gma_encoder, on: false); |
171 | gma_power_end(dev); |
172 | } |
173 | |
174 | static u32 oaktrail_lvds_get_max_backlight(struct drm_device *dev) |
175 | { |
176 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
177 | u32 ret; |
178 | |
179 | if (gma_power_begin(dev, force: false)) { |
180 | ret = ((REG_READ(BLC_PWM_CTL) & |
181 | BACKLIGHT_MODULATION_FREQ_MASK) >> |
182 | BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; |
183 | |
184 | gma_power_end(dev); |
185 | } else |
186 | ret = ((dev_priv->regs.saveBLC_PWM_CTL & |
187 | BACKLIGHT_MODULATION_FREQ_MASK) >> |
188 | BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; |
189 | |
190 | return ret; |
191 | } |
192 | |
193 | static void oaktrail_lvds_commit(struct drm_encoder *encoder) |
194 | { |
195 | struct drm_device *dev = encoder->dev; |
196 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
197 | struct gma_encoder *gma_encoder = to_gma_encoder(encoder); |
198 | struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; |
199 | |
200 | if (mode_dev->backlight_duty_cycle == 0) |
201 | mode_dev->backlight_duty_cycle = |
202 | oaktrail_lvds_get_max_backlight(dev); |
203 | oaktrail_lvds_set_power(dev, gma_encoder, on: true); |
204 | } |
205 | |
206 | static const struct drm_encoder_helper_funcs oaktrail_lvds_helper_funcs = { |
207 | .dpms = oaktrail_lvds_dpms, |
208 | .mode_fixup = psb_intel_lvds_mode_fixup, |
209 | .prepare = oaktrail_lvds_prepare, |
210 | .mode_set = oaktrail_lvds_mode_set, |
211 | .commit = oaktrail_lvds_commit, |
212 | }; |
213 | |
214 | /* Returns the panel fixed mode from configuration. */ |
215 | |
216 | static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev, |
217 | struct psb_intel_mode_device *mode_dev) |
218 | { |
219 | struct drm_display_mode *mode = NULL; |
220 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
221 | struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD; |
222 | |
223 | mode_dev->panel_fixed_mode = NULL; |
224 | |
225 | /* Use the firmware provided data on Moorestown */ |
226 | if (dev_priv->has_gct) { |
227 | mode = kzalloc(size: sizeof(*mode), GFP_KERNEL); |
228 | if (!mode) |
229 | return; |
230 | |
231 | mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; |
232 | mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; |
233 | mode->hsync_start = mode->hdisplay + \ |
234 | ((ti->hsync_offset_hi << 8) | \ |
235 | ti->hsync_offset_lo); |
236 | mode->hsync_end = mode->hsync_start + \ |
237 | ((ti->hsync_pulse_width_hi << 8) | \ |
238 | ti->hsync_pulse_width_lo); |
239 | mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \ |
240 | ti->hblank_lo); |
241 | mode->vsync_start = \ |
242 | mode->vdisplay + ((ti->vsync_offset_hi << 4) | \ |
243 | ti->vsync_offset_lo); |
244 | mode->vsync_end = \ |
245 | mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \ |
246 | ti->vsync_pulse_width_lo); |
247 | mode->vtotal = mode->vdisplay + \ |
248 | ((ti->vblank_hi << 8) | ti->vblank_lo); |
249 | mode->clock = ti->pixel_clock * 10; |
250 | #if 0 |
251 | pr_info("hdisplay is %d\n" , mode->hdisplay); |
252 | pr_info("vdisplay is %d\n" , mode->vdisplay); |
253 | pr_info("HSS is %d\n" , mode->hsync_start); |
254 | pr_info("HSE is %d\n" , mode->hsync_end); |
255 | pr_info("htotal is %d\n" , mode->htotal); |
256 | pr_info("VSS is %d\n" , mode->vsync_start); |
257 | pr_info("VSE is %d\n" , mode->vsync_end); |
258 | pr_info("vtotal is %d\n" , mode->vtotal); |
259 | pr_info("clock is %d\n" , mode->clock); |
260 | #endif |
261 | mode_dev->panel_fixed_mode = mode; |
262 | } |
263 | |
264 | /* Use the BIOS VBT mode if available */ |
265 | if (mode_dev->panel_fixed_mode == NULL && mode_dev->vbt_mode) |
266 | mode_dev->panel_fixed_mode = drm_mode_duplicate(dev, |
267 | mode: mode_dev->vbt_mode); |
268 | |
269 | /* Then try the LVDS VBT mode */ |
270 | if (mode_dev->panel_fixed_mode == NULL) |
271 | if (dev_priv->lfp_lvds_vbt_mode) |
272 | mode_dev->panel_fixed_mode = |
273 | drm_mode_duplicate(dev, |
274 | mode: dev_priv->lfp_lvds_vbt_mode); |
275 | |
276 | /* If we still got no mode then bail */ |
277 | if (mode_dev->panel_fixed_mode == NULL) |
278 | return; |
279 | |
280 | drm_mode_set_name(mode: mode_dev->panel_fixed_mode); |
281 | drm_mode_set_crtcinfo(p: mode_dev->panel_fixed_mode, adjust_flags: 0); |
282 | } |
283 | |
284 | /** |
285 | * oaktrail_lvds_init - setup LVDS connectors on this device |
286 | * @dev: drm device |
287 | * @mode_dev: PSB mode device |
288 | * |
289 | * Create the connector, register the LVDS DDC bus, and try to figure out what |
290 | * modes we can display on the LVDS panel (if present). |
291 | */ |
292 | void oaktrail_lvds_init(struct drm_device *dev, |
293 | struct psb_intel_mode_device *mode_dev) |
294 | { |
295 | struct gma_encoder *gma_encoder; |
296 | struct gma_connector *gma_connector; |
297 | struct gma_i2c_chan *ddc_bus; |
298 | struct drm_connector *connector; |
299 | struct drm_encoder *encoder; |
300 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
301 | struct edid *edid; |
302 | struct i2c_adapter *i2c_adap; |
303 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ |
304 | int ret; |
305 | |
306 | gma_encoder = kzalloc(size: sizeof(struct gma_encoder), GFP_KERNEL); |
307 | if (!gma_encoder) |
308 | return; |
309 | |
310 | gma_connector = kzalloc(size: sizeof(struct gma_connector), GFP_KERNEL); |
311 | if (!gma_connector) |
312 | goto err_free_encoder; |
313 | |
314 | connector = &gma_connector->base; |
315 | encoder = &gma_encoder->base; |
316 | dev_priv->is_lvds_on = true; |
317 | ret = drm_connector_init(dev, connector, |
318 | funcs: &psb_intel_lvds_connector_funcs, |
319 | DRM_MODE_CONNECTOR_LVDS); |
320 | if (ret) |
321 | goto err_free_connector; |
322 | |
323 | ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_LVDS); |
324 | if (ret) |
325 | goto err_connector_cleanup; |
326 | |
327 | gma_connector_attach_encoder(connector: gma_connector, encoder: gma_encoder); |
328 | gma_encoder->type = INTEL_OUTPUT_LVDS; |
329 | |
330 | drm_encoder_helper_add(encoder, funcs: &oaktrail_lvds_helper_funcs); |
331 | drm_connector_helper_add(connector, |
332 | funcs: &psb_intel_lvds_connector_helper_funcs); |
333 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
334 | connector->interlace_allowed = false; |
335 | connector->doublescan_allowed = false; |
336 | |
337 | drm_object_attach_property(obj: &connector->base, |
338 | property: dev->mode_config.scaling_mode_property, |
339 | DRM_MODE_SCALE_FULLSCREEN); |
340 | drm_object_attach_property(obj: &connector->base, |
341 | property: dev_priv->backlight_property, |
342 | BRIGHTNESS_MAX_LEVEL); |
343 | |
344 | mode_dev->panel_wants_dither = false; |
345 | if (dev_priv->has_gct) |
346 | mode_dev->panel_wants_dither = (dev_priv->gct_data. |
347 | Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE); |
348 | if (dev_priv->lvds_dither) |
349 | mode_dev->panel_wants_dither = 1; |
350 | |
351 | /* |
352 | * LVDS discovery: |
353 | * 1) check for EDID on DDC |
354 | * 2) check for VBT data |
355 | * 3) check to see if LVDS is already on |
356 | * if none of the above, no panel |
357 | * 4) make sure lid is open |
358 | * if closed, act like it's not there for now |
359 | */ |
360 | |
361 | edid = NULL; |
362 | mutex_lock(&dev->mode_config.mutex); |
363 | |
364 | i2c_adap = i2c_get_adapter(nr: dev_priv->ops->i2c_bus); |
365 | if (i2c_adap) |
366 | edid = drm_get_edid(connector, adapter: i2c_adap); |
367 | |
368 | if (edid == NULL && dev_priv->lpc_gpio_base) { |
369 | ddc_bus = oaktrail_lvds_i2c_init(dev); |
370 | if (!IS_ERR(ptr: ddc_bus)) { |
371 | i2c_adap = &ddc_bus->base; |
372 | edid = drm_get_edid(connector, adapter: i2c_adap); |
373 | } |
374 | } |
375 | |
376 | /* |
377 | * Due to the logic in probing for i2c buses above we do not know the |
378 | * i2c_adap until now. Hence we cannot use drm_connector_init_with_ddc() |
379 | * but must instead set connector->ddc manually here. |
380 | */ |
381 | connector->ddc = i2c_adap; |
382 | |
383 | /* |
384 | * Attempt to get the fixed panel mode from DDC. Assume that the |
385 | * preferred mode is the right one. |
386 | */ |
387 | if (edid) { |
388 | drm_connector_update_edid_property(connector, edid); |
389 | drm_add_edid_modes(connector, edid); |
390 | kfree(objp: edid); |
391 | |
392 | list_for_each_entry(scan, &connector->probed_modes, head) { |
393 | if (scan->type & DRM_MODE_TYPE_PREFERRED) { |
394 | mode_dev->panel_fixed_mode = |
395 | drm_mode_duplicate(dev, mode: scan); |
396 | goto out; /* FIXME: check for quirks */ |
397 | } |
398 | } |
399 | } else |
400 | dev_err(dev->dev, "No ddc adapter available!\n" ); |
401 | /* |
402 | * If we didn't get EDID, try geting panel timing |
403 | * from configuration data |
404 | */ |
405 | oaktrail_lvds_get_configuration_mode(dev, mode_dev); |
406 | |
407 | if (mode_dev->panel_fixed_mode) { |
408 | mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; |
409 | goto out; /* FIXME: check for quirks */ |
410 | } |
411 | |
412 | /* If we still don't have a mode after all that, give up. */ |
413 | if (!mode_dev->panel_fixed_mode) { |
414 | dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n" ); |
415 | goto err_unlock; |
416 | } |
417 | |
418 | out: |
419 | mutex_unlock(lock: &dev->mode_config.mutex); |
420 | |
421 | return; |
422 | |
423 | err_unlock: |
424 | mutex_unlock(lock: &dev->mode_config.mutex); |
425 | gma_i2c_destroy(to_gma_i2c_chan(connector->ddc)); |
426 | drm_encoder_cleanup(encoder); |
427 | err_connector_cleanup: |
428 | drm_connector_cleanup(connector); |
429 | err_free_connector: |
430 | kfree(objp: gma_connector); |
431 | err_free_encoder: |
432 | kfree(objp: gma_encoder); |
433 | } |
434 | |
435 | |