aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/Makefile1
-rw-r--r--drivers/gpu/drm/i915/dvo.h1
-rw-r--r--drivers/gpu/drm/i915/dvo_ns2501.c582
-rw-r--r--drivers/gpu/drm/i915/intel_display.c4
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c10
5 files changed, 596 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index b0bacdba6d7e..0f2c5493242b 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -40,6 +40,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
40 dvo_ivch.o \ 40 dvo_ivch.o \
41 dvo_tfp410.o \ 41 dvo_tfp410.o \
42 dvo_sil164.o \ 42 dvo_sil164.o \
43 dvo_ns2501.o \
43 i915_gem_dmabuf.o 44 i915_gem_dmabuf.o
44 45
45i915-$(CONFIG_COMPAT) += i915_ioc32.o 46i915-$(CONFIG_COMPAT) += i915_ioc32.o
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h
index 58914691a77b..0c8ac4d92deb 100644
--- a/drivers/gpu/drm/i915/dvo.h
+++ b/drivers/gpu/drm/i915/dvo.h
@@ -140,5 +140,6 @@ extern struct intel_dvo_dev_ops ch7xxx_ops;
140extern struct intel_dvo_dev_ops ivch_ops; 140extern struct intel_dvo_dev_ops ivch_ops;
141extern struct intel_dvo_dev_ops tfp410_ops; 141extern struct intel_dvo_dev_ops tfp410_ops;
142extern struct intel_dvo_dev_ops ch7017_ops; 142extern struct intel_dvo_dev_ops ch7017_ops;
143extern struct intel_dvo_dev_ops ns2501_ops;
143 144
144#endif /* _INTEL_DVO_H */ 145#endif /* _INTEL_DVO_H */
diff --git a/drivers/gpu/drm/i915/dvo_ns2501.c b/drivers/gpu/drm/i915/dvo_ns2501.c
new file mode 100644
index 000000000000..1a0bad9a5fab
--- /dev/null
+++ b/drivers/gpu/drm/i915/dvo_ns2501.c
@@ -0,0 +1,582 @@
1/*
2 *
3 * Copyright (c) 2012 Gilles Dartiguelongue, Thomas Richter
4 *
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 */
28
29#include "dvo.h"
30#include "i915_reg.h"
31#include "i915_drv.h"
32
33#define NS2501_VID 0x1305
34#define NS2501_DID 0x6726
35
36#define NS2501_VID_LO 0x00
37#define NS2501_VID_HI 0x01
38#define NS2501_DID_LO 0x02
39#define NS2501_DID_HI 0x03
40#define NS2501_REV 0x04
41#define NS2501_RSVD 0x05
42#define NS2501_FREQ_LO 0x06
43#define NS2501_FREQ_HI 0x07
44
45#define NS2501_REG8 0x08
46#define NS2501_8_VEN (1<<5)
47#define NS2501_8_HEN (1<<4)
48#define NS2501_8_DSEL (1<<3)
49#define NS2501_8_BPAS (1<<2)
50#define NS2501_8_RSVD (1<<1)
51#define NS2501_8_PD (1<<0)
52
53#define NS2501_REG9 0x09
54#define NS2501_9_VLOW (1<<7)
55#define NS2501_9_MSEL_MASK (0x7<<4)
56#define NS2501_9_TSEL (1<<3)
57#define NS2501_9_RSEN (1<<2)
58#define NS2501_9_RSVD (1<<1)
59#define NS2501_9_MDI (1<<0)
60
61#define NS2501_REGC 0x0c
62
63struct ns2501_priv {
64 //I2CDevRec d;
65 bool quiet;
66 int reg_8_shadow;
67 int reg_8_set;
68 // Shadow registers for i915
69 int dvoc;
70 int pll_a;
71 int srcdim;
72 int fw_blc;
73};
74
75#define NSPTR(d) ((NS2501Ptr)(d->DriverPrivate.ptr))
76
77/*
78 * Include the PLL launcher prototype
79 */
80extern void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe);
81
82/*
83 * For reasons unclear to me, the ns2501 at least on the Fujitsu/Siemens
84 * laptops does not react on the i2c bus unless
85 * both the PLL is running and the display is configured in its native
86 * resolution.
87 * This function forces the DVO on, and stores the registers it touches.
88 * Afterwards, registers are restored to regular values.
89 *
90 * This is pretty much a hack, though it works.
91 * Without that, ns2501_readb and ns2501_writeb fail
92 * when switching the resolution.
93 */
94
95static void enable_dvo(struct intel_dvo_device *dvo)
96{
97 struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
98 struct i2c_adapter *adapter = dvo->i2c_bus;
99 struct intel_gmbus *bus = container_of(adapter,
100 struct intel_gmbus,
101 adapter);
102 struct drm_i915_private *dev_priv = bus->dev_priv;
103
104 DRM_DEBUG_KMS("%s: Trying to re-enable the DVO\n", __FUNCTION__);
105
106 ns->dvoc = I915_READ(DVO_C);
107 ns->pll_a = I915_READ(_DPLL_A);
108 ns->srcdim = I915_READ(DVOC_SRCDIM);
109 ns->fw_blc = I915_READ(FW_BLC);
110
111 I915_WRITE(DVOC, 0x10004084);
112 I915_WRITE(_DPLL_A, 0xd0820000);
113 I915_WRITE(DVOC_SRCDIM, 0x400300); // 1024x768
114 I915_WRITE(FW_BLC, 0x1080304);
115
116 intel_enable_pll(dev_priv, 0);
117
118 I915_WRITE(DVOC, 0x90004084);
119}
120
121/*
122 * Restore the I915 registers modified by the above
123 * trigger function.
124 */
125static void restore_dvo(struct intel_dvo_device *dvo)
126{
127 struct i2c_adapter *adapter = dvo->i2c_bus;
128 struct intel_gmbus *bus = container_of(adapter,
129 struct intel_gmbus,
130 adapter);
131 struct drm_i915_private *dev_priv = bus->dev_priv;
132 struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
133
134 I915_WRITE(DVOC, ns->dvoc);
135 I915_WRITE(_DPLL_A, ns->pll_a);
136 I915_WRITE(DVOC_SRCDIM, ns->srcdim);
137 I915_WRITE(FW_BLC, ns->fw_blc);
138}
139
140/*
141** Read a register from the ns2501.
142** Returns true if successful, false otherwise.
143** If it returns false, it might be wise to enable the
144** DVO with the above function.
145*/
146static bool ns2501_readb(struct intel_dvo_device *dvo, int addr, uint8_t * ch)
147{
148 struct ns2501_priv *ns = dvo->dev_priv;
149 struct i2c_adapter *adapter = dvo->i2c_bus;
150 u8 out_buf[2];
151 u8 in_buf[2];
152
153 struct i2c_msg msgs[] = {
154 {
155 .addr = dvo->slave_addr,
156 .flags = 0,
157 .len = 1,
158 .buf = out_buf,
159 },
160 {
161 .addr = dvo->slave_addr,
162 .flags = I2C_M_RD,
163 .len = 1,
164 .buf = in_buf,
165 }
166 };
167
168 out_buf[0] = addr;
169 out_buf[1] = 0;
170
171 if (i2c_transfer(adapter, msgs, 2) == 2) {
172 *ch = in_buf[0];
173 return true;
174 };
175
176 if (!ns->quiet) {
177 DRM_DEBUG_KMS
178 ("Unable to read register 0x%02x from %s:0x%02x.\n", addr,
179 adapter->name, dvo->slave_addr);
180 }
181
182 return false;
183}
184
185/*
186** Write a register to the ns2501.
187** Returns true if successful, false otherwise.
188** If it returns false, it might be wise to enable the
189** DVO with the above function.
190*/
191static bool ns2501_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
192{
193 struct ns2501_priv *ns = dvo->dev_priv;
194 struct i2c_adapter *adapter = dvo->i2c_bus;
195 uint8_t out_buf[2];
196
197 struct i2c_msg msg = {
198 .addr = dvo->slave_addr,
199 .flags = 0,
200 .len = 2,
201 .buf = out_buf,
202 };
203
204 out_buf[0] = addr;
205 out_buf[1] = ch;
206
207 if (i2c_transfer(adapter, &msg, 1) == 1) {
208 return true;
209 }
210
211 if (!ns->quiet) {
212 DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d\n",
213 addr, adapter->name, dvo->slave_addr);
214 }
215
216 return false;
217}
218
219/* National Semiconductor 2501 driver for chip on i2c bus
220 * scan for the chip on the bus.
221 * Hope the VBIOS initialized the PLL correctly so we can
222 * talk to it. If not, it will not be seen and not detected.
223 * Bummer!
224 */
225static bool ns2501_init(struct intel_dvo_device *dvo,
226 struct i2c_adapter *adapter)
227{
228 /* this will detect the NS2501 chip on the specified i2c bus */
229 struct ns2501_priv *ns;
230 unsigned char ch;
231
232 ns = kzalloc(sizeof(struct ns2501_priv), GFP_KERNEL);
233 if (ns == NULL)
234 return false;
235
236 dvo->i2c_bus = adapter;
237 dvo->dev_priv = ns;
238 ns->quiet = true;
239
240 if (!ns2501_readb(dvo, NS2501_VID_LO, &ch))
241 goto out;
242
243 if (ch != (NS2501_VID & 0xff)) {
244 DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
245 ch, adapter->name, dvo->slave_addr);
246 goto out;
247 }
248
249 if (!ns2501_readb(dvo, NS2501_DID_LO, &ch))
250 goto out;
251
252 if (ch != (NS2501_DID & 0xff)) {
253 DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
254 ch, adapter->name, dvo->slave_addr);
255 goto out;
256 }
257 ns->quiet = false;
258 ns->reg_8_set = 0;
259 ns->reg_8_shadow =
260 NS2501_8_PD | NS2501_8_BPAS | NS2501_8_VEN | NS2501_8_HEN;
261
262 DRM_DEBUG_KMS("init ns2501 dvo controller successfully!\n");
263 return true;
264
265out:
266 kfree(ns);
267 return false;
268}
269
270static enum drm_connector_status ns2501_detect(struct intel_dvo_device *dvo)
271{
272 /*
273 * This is a Laptop display, it doesn't have hotplugging.
274 * Even if not, the detection bit of the 2501 is unreliable as
275 * it only works for some display types.
276 * It is even more unreliable as the PLL must be active for
277 * allowing reading from the chiop.
278 */
279 return connector_status_connected;
280}
281
282static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo,
283 struct drm_display_mode *mode)
284{
285 DRM_DEBUG_KMS
286 ("%s: is mode valid (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d)\n",
287 __FUNCTION__, mode->hdisplay, mode->htotal, mode->vdisplay,
288 mode->vtotal);
289
290 /*
291 * Currently, these are all the modes I have data from.
292 * More might exist. Unclear how to find the native resolution
293 * of the panel in here so we could always accept it
294 * by disabling the scaler.
295 */
296 if ((mode->hdisplay == 800 && mode->vdisplay == 600) ||
297 (mode->hdisplay == 640 && mode->vdisplay == 480) ||
298 (mode->hdisplay == 1024 && mode->vdisplay == 768)) {
299 return MODE_OK;
300 } else {
301 return MODE_ONE_SIZE; /* Is this a reasonable error? */
302 }
303}
304
305static void ns2501_mode_set(struct intel_dvo_device *dvo,
306 struct drm_display_mode *mode,
307 struct drm_display_mode *adjusted_mode)
308{
309 bool ok;
310 bool restore = false;
311 struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
312
313 DRM_DEBUG_KMS
314 ("%s: set mode (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d).\n",
315 __FUNCTION__, mode->hdisplay, mode->htotal, mode->vdisplay,
316 mode->vtotal);
317
318 /*
319 * Where do I find the native resolution for which scaling is not required???
320 *
321 * First trigger the DVO on as otherwise the chip does not appear on the i2c
322 * bus.
323 */
324 do {
325 ok = true;
326
327 if (mode->hdisplay == 800 && mode->vdisplay == 600) {
328 /* mode 277 */
329 ns->reg_8_shadow &= ~NS2501_8_BPAS;
330 DRM_DEBUG_KMS("%s: switching to 800x600\n",
331 __FUNCTION__);
332
333 /*
334 * No, I do not know where this data comes from.
335 * It is just what the video bios left in the DVO, so
336 * I'm just copying it here over.
337 * This also means that I cannot support any other modes
338 * except the ones supported by the bios.
339 */
340 ok &= ns2501_writeb(dvo, 0x11, 0xc8); // 0xc7 also works.
341 ok &= ns2501_writeb(dvo, 0x1b, 0x19);
342 ok &= ns2501_writeb(dvo, 0x1c, 0x62); // VBIOS left 0x64 here, but 0x62 works nicer
343 ok &= ns2501_writeb(dvo, 0x1d, 0x02);
344
345 ok &= ns2501_writeb(dvo, 0x34, 0x03);
346 ok &= ns2501_writeb(dvo, 0x35, 0xff);
347
348 ok &= ns2501_writeb(dvo, 0x80, 0x27);
349 ok &= ns2501_writeb(dvo, 0x81, 0x03);
350 ok &= ns2501_writeb(dvo, 0x82, 0x41);
351 ok &= ns2501_writeb(dvo, 0x83, 0x05);
352
353 ok &= ns2501_writeb(dvo, 0x8d, 0x02);
354 ok &= ns2501_writeb(dvo, 0x8e, 0x04);
355 ok &= ns2501_writeb(dvo, 0x8f, 0x00);
356
357 ok &= ns2501_writeb(dvo, 0x90, 0xfe); /* vertical. VBIOS left 0xff here, but 0xfe works better */
358 ok &= ns2501_writeb(dvo, 0x91, 0x07);
359 ok &= ns2501_writeb(dvo, 0x94, 0x00);
360 ok &= ns2501_writeb(dvo, 0x95, 0x00);
361
362 ok &= ns2501_writeb(dvo, 0x96, 0x00);
363
364 ok &= ns2501_writeb(dvo, 0x99, 0x00);
365 ok &= ns2501_writeb(dvo, 0x9a, 0x88);
366
367 ok &= ns2501_writeb(dvo, 0x9c, 0x23); /* Looks like first and last line of the image. */
368 ok &= ns2501_writeb(dvo, 0x9d, 0x00);
369 ok &= ns2501_writeb(dvo, 0x9e, 0x25);
370 ok &= ns2501_writeb(dvo, 0x9f, 0x03);
371
372 ok &= ns2501_writeb(dvo, 0xa4, 0x80);
373
374 ok &= ns2501_writeb(dvo, 0xb6, 0x00);
375
376 ok &= ns2501_writeb(dvo, 0xb9, 0xc8); /* horizontal? */
377 ok &= ns2501_writeb(dvo, 0xba, 0x00); /* horizontal? */
378
379 ok &= ns2501_writeb(dvo, 0xc0, 0x05); /* horizontal? */
380 ok &= ns2501_writeb(dvo, 0xc1, 0xd7);
381
382 ok &= ns2501_writeb(dvo, 0xc2, 0x00);
383 ok &= ns2501_writeb(dvo, 0xc3, 0xf8);
384
385 ok &= ns2501_writeb(dvo, 0xc4, 0x03);
386 ok &= ns2501_writeb(dvo, 0xc5, 0x1a);
387
388 ok &= ns2501_writeb(dvo, 0xc6, 0x00);
389 ok &= ns2501_writeb(dvo, 0xc7, 0x73);
390 ok &= ns2501_writeb(dvo, 0xc8, 0x02);
391
392 } else if (mode->hdisplay == 640 && mode->vdisplay == 480) {
393 /* mode 274 */
394 DRM_DEBUG_KMS("%s: switching to 640x480\n",
395 __FUNCTION__);
396 /*
397 * No, I do not know where this data comes from.
398 * It is just what the video bios left in the DVO, so
399 * I'm just copying it here over.
400 * This also means that I cannot support any other modes
401 * except the ones supported by the bios.
402 */
403 ns->reg_8_shadow &= ~NS2501_8_BPAS;
404
405 ok &= ns2501_writeb(dvo, 0x11, 0xa0);
406 ok &= ns2501_writeb(dvo, 0x1b, 0x11);
407 ok &= ns2501_writeb(dvo, 0x1c, 0x54);
408 ok &= ns2501_writeb(dvo, 0x1d, 0x03);
409
410 ok &= ns2501_writeb(dvo, 0x34, 0x03);
411 ok &= ns2501_writeb(dvo, 0x35, 0xff);
412
413 ok &= ns2501_writeb(dvo, 0x80, 0xff);
414 ok &= ns2501_writeb(dvo, 0x81, 0x07);
415 ok &= ns2501_writeb(dvo, 0x82, 0x3d);
416 ok &= ns2501_writeb(dvo, 0x83, 0x05);
417
418 ok &= ns2501_writeb(dvo, 0x8d, 0x02);
419 ok &= ns2501_writeb(dvo, 0x8e, 0x10);
420 ok &= ns2501_writeb(dvo, 0x8f, 0x00);
421
422 ok &= ns2501_writeb(dvo, 0x90, 0xff); /* vertical */
423 ok &= ns2501_writeb(dvo, 0x91, 0x07);
424 ok &= ns2501_writeb(dvo, 0x94, 0x00);
425 ok &= ns2501_writeb(dvo, 0x95, 0x00);
426
427 ok &= ns2501_writeb(dvo, 0x96, 0x05);
428
429 ok &= ns2501_writeb(dvo, 0x99, 0x00);
430 ok &= ns2501_writeb(dvo, 0x9a, 0x88);
431
432 ok &= ns2501_writeb(dvo, 0x9c, 0x24);
433 ok &= ns2501_writeb(dvo, 0x9d, 0x00);
434 ok &= ns2501_writeb(dvo, 0x9e, 0x25);
435 ok &= ns2501_writeb(dvo, 0x9f, 0x03);
436
437 ok &= ns2501_writeb(dvo, 0xa4, 0x84);
438
439 ok &= ns2501_writeb(dvo, 0xb6, 0x09);
440
441 ok &= ns2501_writeb(dvo, 0xb9, 0xa0); /* horizontal? */
442 ok &= ns2501_writeb(dvo, 0xba, 0x00); /* horizontal? */
443
444 ok &= ns2501_writeb(dvo, 0xc0, 0x05); /* horizontal? */
445 ok &= ns2501_writeb(dvo, 0xc1, 0x90);
446
447 ok &= ns2501_writeb(dvo, 0xc2, 0x00);
448 ok &= ns2501_writeb(dvo, 0xc3, 0x0f);
449
450 ok &= ns2501_writeb(dvo, 0xc4, 0x03);
451 ok &= ns2501_writeb(dvo, 0xc5, 0x16);
452
453 ok &= ns2501_writeb(dvo, 0xc6, 0x00);
454 ok &= ns2501_writeb(dvo, 0xc7, 0x02);
455 ok &= ns2501_writeb(dvo, 0xc8, 0x02);
456
457 } else if (mode->hdisplay == 1024 && mode->vdisplay == 768) {
458 /* mode 280 */
459 DRM_DEBUG_KMS("%s: switching to 1024x768\n",
460 __FUNCTION__);
461 /*
462 * This might or might not work, actually. I'm silently
463 * assuming here that the native panel resolution is
464 * 1024x768. If not, then this leaves the scaler disabled
465 * generating a picture that is likely not the expected.
466 *
467 * Problem is that I do not know where to take the panel
468 * dimensions from.
469 *
470 * Enable the bypass, scaling not required.
471 *
472 * The scaler registers are irrelevant here....
473 *
474 */
475 ns->reg_8_shadow |= NS2501_8_BPAS;
476 ok &= ns2501_writeb(dvo, 0x37, 0x44);
477 } else {
478 /*
479 * Data not known. Bummer!
480 * Hopefully, the code should not go here
481 * as mode_OK delivered no other modes.
482 */
483 ns->reg_8_shadow |= NS2501_8_BPAS;
484 }
485 ok &= ns2501_writeb(dvo, NS2501_REG8, ns->reg_8_shadow);
486
487 if (!ok) {
488 if (restore)
489 restore_dvo(dvo);
490 enable_dvo(dvo);
491 restore = true;
492 }
493 } while (!ok);
494 /*
495 * Restore the old i915 registers before
496 * forcing the ns2501 on.
497 */
498 if (restore)
499 restore_dvo(dvo);
500}
501
502/* set the NS2501 power state */
503static void ns2501_dpms(struct intel_dvo_device *dvo, int mode)
504{
505 bool ok;
506 bool restore = false;
507 struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
508 unsigned char ch;
509
510 DRM_DEBUG_KMS("%s: Trying set the dpms of the DVO to %d\n",
511 __FUNCTION__, mode);
512
513 ch = ns->reg_8_shadow;
514
515 if (mode == DRM_MODE_DPMS_ON)
516 ch |= NS2501_8_PD;
517 else
518 ch &= ~NS2501_8_PD;
519
520 if (ns->reg_8_set == 0 || ns->reg_8_shadow != ch) {
521 ns->reg_8_set = 1;
522 ns->reg_8_shadow = ch;
523
524 do {
525 ok = true;
526 ok &= ns2501_writeb(dvo, NS2501_REG8, ch);
527 ok &=
528 ns2501_writeb(dvo, 0x34,
529 (mode ==
530 DRM_MODE_DPMS_ON) ? (0x03) : (0x00));
531 ok &=
532 ns2501_writeb(dvo, 0x35,
533 (mode ==
534 DRM_MODE_DPMS_ON) ? (0xff) : (0x00));
535 if (!ok) {
536 if (restore)
537 restore_dvo(dvo);
538 enable_dvo(dvo);
539 restore = true;
540 }
541 } while (!ok);
542
543 if (restore)
544 restore_dvo(dvo);
545 }
546}
547
548static void ns2501_dump_regs(struct intel_dvo_device *dvo)
549{
550 uint8_t val;
551
552 ns2501_readb(dvo, NS2501_FREQ_LO, &val);
553 DRM_LOG_KMS("NS2501_FREQ_LO: 0x%02x\n", val);
554 ns2501_readb(dvo, NS2501_FREQ_HI, &val);
555 DRM_LOG_KMS("NS2501_FREQ_HI: 0x%02x\n", val);
556 ns2501_readb(dvo, NS2501_REG8, &val);
557 DRM_LOG_KMS("NS2501_REG8: 0x%02x\n", val);
558 ns2501_readb(dvo, NS2501_REG9, &val);
559 DRM_LOG_KMS("NS2501_REG9: 0x%02x\n", val);
560 ns2501_readb(dvo, NS2501_REGC, &val);
561 DRM_LOG_KMS("NS2501_REGC: 0x%02x\n", val);
562}
563
564static void ns2501_destroy(struct intel_dvo_device *dvo)
565{
566 struct ns2501_priv *ns = dvo->dev_priv;
567
568 if (ns) {
569 kfree(ns);
570 dvo->dev_priv = NULL;
571 }
572}
573
574struct intel_dvo_dev_ops ns2501_ops = {
575 .init = ns2501_init,
576 .detect = ns2501_detect,
577 .mode_valid = ns2501_mode_valid,
578 .mode_set = ns2501_mode_set,
579 .dpms = ns2501_dpms,
580 .dump_regs = ns2501_dump_regs,
581 .destroy = ns2501_destroy,
582};
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f8c2aa1ec27a..93d9934ba328 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1428,8 +1428,10 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
1428 * protect mechanism may be enabled. 1428 * protect mechanism may be enabled.
1429 * 1429 *
1430 * Note! This is for pre-ILK only. 1430 * Note! This is for pre-ILK only.
1431 *
1432 * Unfortunately needed by dvo_ns2501 since the dvo depends on it running.
1431 */ 1433 */
1432static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) 1434void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
1433{ 1435{
1434 int reg; 1436 int reg;
1435 u32 val; 1437 u32 val;
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index 556cf6bf2a55..03dfdff8e003 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -37,6 +37,7 @@
37#define SIL164_ADDR 0x38 37#define SIL164_ADDR 0x38
38#define CH7xxx_ADDR 0x76 38#define CH7xxx_ADDR 0x76
39#define TFP410_ADDR 0x38 39#define TFP410_ADDR 0x38
40#define NS2501_ADDR 0x38
40 41
41static const struct intel_dvo_device intel_dvo_devices[] = { 42static const struct intel_dvo_device intel_dvo_devices[] = {
42 { 43 {
@@ -74,7 +75,14 @@ static const struct intel_dvo_device intel_dvo_devices[] = {
74 .slave_addr = 0x75, 75 .slave_addr = 0x75,
75 .gpio = GMBUS_PORT_DPB, 76 .gpio = GMBUS_PORT_DPB,
76 .dev_ops = &ch7017_ops, 77 .dev_ops = &ch7017_ops,
77 } 78 },
79 {
80 .type = INTEL_DVO_CHIP_TMDS,
81 .name = "ns2501",
82 .dvo_reg = DVOC,
83 .slave_addr = NS2501_ADDR,
84 .dev_ops = &ns2501_ops,
85 }
78}; 86};
79 87
80struct intel_dvo { 88struct intel_dvo {