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 <sys/cdefs.h>
30__FBSDID("$FreeBSD$");
31
32#include "dvo.h"
33#include "i915_reg.h"
34#include "i915_drv.h"
35
36#define NS2501_VID 0x1305
37#define NS2501_DID 0x6726
38
39#define NS2501_VID_LO 0x00
40#define NS2501_VID_HI 0x01
41#define NS2501_DID_LO 0x02
42#define NS2501_DID_HI 0x03
43#define NS2501_REV 0x04
44#define NS2501_RSVD 0x05
45#define NS2501_FREQ_LO 0x06
46#define NS2501_FREQ_HI 0x07
47
48#define NS2501_REG8 0x08
49#define NS2501_8_VEN (1<<5)
50#define NS2501_8_HEN (1<<4)
51#define NS2501_8_DSEL (1<<3)
52#define NS2501_8_BPAS (1<<2)
53#define NS2501_8_RSVD (1<<1)
54#define NS2501_8_PD (1<<0)
55
56#define NS2501_REG9 0x09
57#define NS2501_9_VLOW (1<<7)
58#define NS2501_9_MSEL_MASK (0x7<<4)
59#define NS2501_9_TSEL (1<<3)
60#define NS2501_9_RSEN (1<<2)
61#define NS2501_9_RSVD (1<<1)
62#define NS2501_9_MDI (1<<0)
63
64#define NS2501_REGC 0x0c
65
66struct ns2501_priv {
67	//I2CDevRec d;
68	bool quiet;
69	int reg_8_shadow;
70	int reg_8_set;
71	// Shadow registers for i915
72	int dvoc;
73	int pll_a;
74	int srcdim;
75	int fw_blc;
76};
77
78#define NSPTR(d) ((NS2501Ptr)(d->DriverPrivate.ptr))
79
80/*
81 * For reasons unclear to me, the ns2501 at least on the Fujitsu/Siemens
82 * laptops does not react on the i2c bus unless
83 * both the PLL is running and the display is configured in its native
84 * resolution.
85 * This function forces the DVO on, and stores the registers it touches.
86 * Afterwards, registers are restored to regular values.
87 *
88 * This is pretty much a hack, though it works.
89 * Without that, ns2501_readb and ns2501_writeb fail
90 * when switching the resolution.
91 */
92
93static void enable_dvo(struct intel_dvo_device *dvo)
94{
95	struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
96	device_t adapter = dvo->i2c_bus;
97	/*
98	 * FIXME Linux<->FreeBSD: device_get_softc() returns a struct
99	 * intel_iic_softc in reality, where struct intel_gmbus is
100	 * the first member. struct intel_iic_softc is defined in
101	 * intel_iic.c.
102	 */
103	struct intel_gmbus *bus =
104	    (struct intel_gmbus *)device_get_softc(adapter);
105	struct drm_i915_private *dev_priv = bus->dev_priv;
106
107	DRM_DEBUG_KMS("%s: Trying to re-enable the DVO\n", __FUNCTION__);
108
109	ns->dvoc = I915_READ(DVO_C);
110	ns->pll_a = I915_READ(_DPLL_A);
111	ns->srcdim = I915_READ(DVOC_SRCDIM);
112	ns->fw_blc = I915_READ(FW_BLC);
113
114	I915_WRITE(DVOC, 0x10004084);
115	I915_WRITE(_DPLL_A, 0xd0820000);
116	I915_WRITE(DVOC_SRCDIM, 0x400300);	// 1024x768
117	I915_WRITE(FW_BLC, 0x1080304);
118
119	I915_WRITE(DVOC, 0x90004084);
120}
121
122/*
123 * Restore the I915 registers modified by the above
124 * trigger function.
125 */
126static void restore_dvo(struct intel_dvo_device *dvo)
127{
128	device_t adapter = dvo->i2c_bus;
129	/*
130	 * FIXME Linux<->FreeBSD: device_get_softc() returns a struct
131	 * intel_iic_softc in reality, where struct intel_gmbus is
132	 * the first member. struct intel_iic_softc is defined in
133	 * intel_iic.c.
134	 */
135	struct intel_gmbus *bus =
136	    (struct intel_gmbus *)device_get_softc(adapter);
137	struct drm_i915_private *dev_priv = bus->dev_priv;
138	struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
139
140	I915_WRITE(DVOC, ns->dvoc);
141	I915_WRITE(_DPLL_A, ns->pll_a);
142	I915_WRITE(DVOC_SRCDIM, ns->srcdim);
143	I915_WRITE(FW_BLC, ns->fw_blc);
144}
145
146/*
147** Read a register from the ns2501.
148** Returns true if successful, false otherwise.
149** If it returns false, it might be wise to enable the
150** DVO with the above function.
151*/
152static bool ns2501_readb(struct intel_dvo_device *dvo, int addr, uint8_t * ch)
153{
154	struct ns2501_priv *ns = dvo->dev_priv;
155	device_t adapter = dvo->i2c_bus;
156	u8 out_buf[2];
157	u8 in_buf[2];
158
159	struct iic_msg msgs[] = {
160		{
161		 .slave = dvo->slave_addr << 1,
162		 .flags = 0,
163		 .len = 1,
164		 .buf = out_buf,
165		 },
166		{
167		 .slave = dvo->slave_addr << 1,
168		 .flags = I2C_M_RD,
169		 .len = 1,
170		 .buf = in_buf,
171		 }
172	};
173
174	out_buf[0] = addr;
175	out_buf[1] = 0;
176
177	if (-iicbus_transfer(adapter, msgs, 2) == 0) {
178		*ch = in_buf[0];
179		return true;
180	}
181
182	if (!ns->quiet) {
183		DRM_DEBUG_KMS
184		    ("Unable to read register 0x%02x from %s:0x%02x.\n", addr,
185		     device_get_nameunit(adapter), dvo->slave_addr);
186	}
187
188	return false;
189}
190
191/*
192** Write a register to the ns2501.
193** Returns true if successful, false otherwise.
194** If it returns false, it might be wise to enable the
195** DVO with the above function.
196*/
197static bool ns2501_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
198{
199	struct ns2501_priv *ns = dvo->dev_priv;
200	device_t adapter = dvo->i2c_bus;
201	uint8_t out_buf[2];
202
203	struct iic_msg msg = {
204		.slave = dvo->slave_addr << 1,
205		.flags = 0,
206		.len = 2,
207		.buf = out_buf,
208	};
209
210	out_buf[0] = addr;
211	out_buf[1] = ch;
212
213	if (-iicbus_transfer(adapter, &msg, 1) == 0) {
214		return true;
215	}
216
217	if (!ns->quiet) {
218		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d\n",
219			      addr, device_get_nameunit(adapter), dvo->slave_addr);
220	}
221
222	return false;
223}
224
225/* National Semiconductor 2501 driver for chip on i2c bus
226 * scan for the chip on the bus.
227 * Hope the VBIOS initialized the PLL correctly so we can
228 * talk to it. If not, it will not be seen and not detected.
229 * Bummer!
230 */
231static bool ns2501_init(struct intel_dvo_device *dvo,
232			device_t adapter)
233{
234	/* this will detect the NS2501 chip on the specified i2c bus */
235	struct ns2501_priv *ns;
236	unsigned char ch;
237
238	ns = malloc(sizeof(struct ns2501_priv), DRM_MEM_KMS, M_NOWAIT | M_ZERO);
239	if (ns == NULL)
240		return false;
241
242	dvo->i2c_bus = adapter;
243	dvo->dev_priv = ns;
244	ns->quiet = true;
245
246	if (!ns2501_readb(dvo, NS2501_VID_LO, &ch))
247		goto out;
248
249	if (ch != (NS2501_VID & 0xff)) {
250		DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
251			      ch, device_get_nameunit(adapter), dvo->slave_addr);
252		goto out;
253	}
254
255	if (!ns2501_readb(dvo, NS2501_DID_LO, &ch))
256		goto out;
257
258	if (ch != (NS2501_DID & 0xff)) {
259		DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
260			      ch, device_get_nameunit(adapter), dvo->slave_addr);
261		goto out;
262	}
263	ns->quiet = false;
264	ns->reg_8_set = 0;
265	ns->reg_8_shadow =
266	    NS2501_8_PD | NS2501_8_BPAS | NS2501_8_VEN | NS2501_8_HEN;
267
268	DRM_DEBUG_KMS("init ns2501 dvo controller successfully!\n");
269	return true;
270
271out:
272	free(ns, DRM_MEM_KMS);
273	return false;
274}
275
276static enum drm_connector_status ns2501_detect(struct intel_dvo_device *dvo)
277{
278	/*
279	 * This is a Laptop display, it doesn't have hotplugging.
280	 * Even if not, the detection bit of the 2501 is unreliable as
281	 * it only works for some display types.
282	 * It is even more unreliable as the PLL must be active for
283	 * allowing reading from the chiop.
284	 */
285	return connector_status_connected;
286}
287
288static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo,
289					      struct drm_display_mode *mode)
290{
291	DRM_DEBUG_KMS
292	    ("%s: is mode valid (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d)\n",
293	     __FUNCTION__, mode->hdisplay, mode->htotal, mode->vdisplay,
294	     mode->vtotal);
295
296	/*
297	 * Currently, these are all the modes I have data from.
298	 * More might exist. Unclear how to find the native resolution
299	 * of the panel in here so we could always accept it
300	 * by disabling the scaler.
301	 */
302	if ((mode->hdisplay == 800 && mode->vdisplay == 600) ||
303	    (mode->hdisplay == 640 && mode->vdisplay == 480) ||
304	    (mode->hdisplay == 1024 && mode->vdisplay == 768)) {
305		return MODE_OK;
306	} else {
307		return MODE_ONE_SIZE;	/* Is this a reasonable error? */
308	}
309}
310
311static void ns2501_mode_set(struct intel_dvo_device *dvo,
312			    struct drm_display_mode *mode,
313			    struct drm_display_mode *adjusted_mode)
314{
315	bool ok;
316	bool restore = false;
317	struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
318
319	DRM_DEBUG_KMS
320	    ("%s: set mode (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d).\n",
321	     __FUNCTION__, mode->hdisplay, mode->htotal, mode->vdisplay,
322	     mode->vtotal);
323
324	/*
325	 * Where do I find the native resolution for which scaling is not required???
326	 *
327	 * First trigger the DVO on as otherwise the chip does not appear on the i2c
328	 * bus.
329	 */
330	do {
331		ok = true;
332
333		if (mode->hdisplay == 800 && mode->vdisplay == 600) {
334			/* mode 277 */
335			ns->reg_8_shadow &= ~NS2501_8_BPAS;
336			DRM_DEBUG_KMS("%s: switching to 800x600\n",
337				      __FUNCTION__);
338
339			/*
340			 * No, I do not know where this data comes from.
341			 * It is just what the video bios left in the DVO, so
342			 * I'm just copying it here over.
343			 * This also means that I cannot support any other modes
344			 * except the ones supported by the bios.
345			 */
346			ok &= ns2501_writeb(dvo, 0x11, 0xc8);	// 0xc7 also works.
347			ok &= ns2501_writeb(dvo, 0x1b, 0x19);
348			ok &= ns2501_writeb(dvo, 0x1c, 0x62);	// VBIOS left 0x64 here, but 0x62 works nicer
349			ok &= ns2501_writeb(dvo, 0x1d, 0x02);
350
351			ok &= ns2501_writeb(dvo, 0x34, 0x03);
352			ok &= ns2501_writeb(dvo, 0x35, 0xff);
353
354			ok &= ns2501_writeb(dvo, 0x80, 0x27);
355			ok &= ns2501_writeb(dvo, 0x81, 0x03);
356			ok &= ns2501_writeb(dvo, 0x82, 0x41);
357			ok &= ns2501_writeb(dvo, 0x83, 0x05);
358
359			ok &= ns2501_writeb(dvo, 0x8d, 0x02);
360			ok &= ns2501_writeb(dvo, 0x8e, 0x04);
361			ok &= ns2501_writeb(dvo, 0x8f, 0x00);
362
363			ok &= ns2501_writeb(dvo, 0x90, 0xfe);	/* vertical. VBIOS left 0xff here, but 0xfe works better */
364			ok &= ns2501_writeb(dvo, 0x91, 0x07);
365			ok &= ns2501_writeb(dvo, 0x94, 0x00);
366			ok &= ns2501_writeb(dvo, 0x95, 0x00);
367
368			ok &= ns2501_writeb(dvo, 0x96, 0x00);
369
370			ok &= ns2501_writeb(dvo, 0x99, 0x00);
371			ok &= ns2501_writeb(dvo, 0x9a, 0x88);
372
373			ok &= ns2501_writeb(dvo, 0x9c, 0x23);	/* Looks like first and last line of the image. */
374			ok &= ns2501_writeb(dvo, 0x9d, 0x00);
375			ok &= ns2501_writeb(dvo, 0x9e, 0x25);
376			ok &= ns2501_writeb(dvo, 0x9f, 0x03);
377
378			ok &= ns2501_writeb(dvo, 0xa4, 0x80);
379
380			ok &= ns2501_writeb(dvo, 0xb6, 0x00);
381
382			ok &= ns2501_writeb(dvo, 0xb9, 0xc8);	/* horizontal? */
383			ok &= ns2501_writeb(dvo, 0xba, 0x00);	/* horizontal? */
384
385			ok &= ns2501_writeb(dvo, 0xc0, 0x05);	/* horizontal? */
386			ok &= ns2501_writeb(dvo, 0xc1, 0xd7);
387
388			ok &= ns2501_writeb(dvo, 0xc2, 0x00);
389			ok &= ns2501_writeb(dvo, 0xc3, 0xf8);
390
391			ok &= ns2501_writeb(dvo, 0xc4, 0x03);
392			ok &= ns2501_writeb(dvo, 0xc5, 0x1a);
393
394			ok &= ns2501_writeb(dvo, 0xc6, 0x00);
395			ok &= ns2501_writeb(dvo, 0xc7, 0x73);
396			ok &= ns2501_writeb(dvo, 0xc8, 0x02);
397
398		} else if (mode->hdisplay == 640 && mode->vdisplay == 480) {
399			/* mode 274 */
400			DRM_DEBUG_KMS("%s: switching to 640x480\n",
401				      __FUNCTION__);
402			/*
403			 * No, I do not know where this data comes from.
404			 * It is just what the video bios left in the DVO, so
405			 * I'm just copying it here over.
406			 * This also means that I cannot support any other modes
407			 * except the ones supported by the bios.
408			 */
409			ns->reg_8_shadow &= ~NS2501_8_BPAS;
410
411			ok &= ns2501_writeb(dvo, 0x11, 0xa0);
412			ok &= ns2501_writeb(dvo, 0x1b, 0x11);
413			ok &= ns2501_writeb(dvo, 0x1c, 0x54);
414			ok &= ns2501_writeb(dvo, 0x1d, 0x03);
415
416			ok &= ns2501_writeb(dvo, 0x34, 0x03);
417			ok &= ns2501_writeb(dvo, 0x35, 0xff);
418
419			ok &= ns2501_writeb(dvo, 0x80, 0xff);
420			ok &= ns2501_writeb(dvo, 0x81, 0x07);
421			ok &= ns2501_writeb(dvo, 0x82, 0x3d);
422			ok &= ns2501_writeb(dvo, 0x83, 0x05);
423
424			ok &= ns2501_writeb(dvo, 0x8d, 0x02);
425			ok &= ns2501_writeb(dvo, 0x8e, 0x10);
426			ok &= ns2501_writeb(dvo, 0x8f, 0x00);
427
428			ok &= ns2501_writeb(dvo, 0x90, 0xff);	/* vertical */
429			ok &= ns2501_writeb(dvo, 0x91, 0x07);
430			ok &= ns2501_writeb(dvo, 0x94, 0x00);
431			ok &= ns2501_writeb(dvo, 0x95, 0x00);
432
433			ok &= ns2501_writeb(dvo, 0x96, 0x05);
434
435			ok &= ns2501_writeb(dvo, 0x99, 0x00);
436			ok &= ns2501_writeb(dvo, 0x9a, 0x88);
437
438			ok &= ns2501_writeb(dvo, 0x9c, 0x24);
439			ok &= ns2501_writeb(dvo, 0x9d, 0x00);
440			ok &= ns2501_writeb(dvo, 0x9e, 0x25);
441			ok &= ns2501_writeb(dvo, 0x9f, 0x03);
442
443			ok &= ns2501_writeb(dvo, 0xa4, 0x84);
444
445			ok &= ns2501_writeb(dvo, 0xb6, 0x09);
446
447			ok &= ns2501_writeb(dvo, 0xb9, 0xa0);	/* horizontal? */
448			ok &= ns2501_writeb(dvo, 0xba, 0x00);	/* horizontal? */
449
450			ok &= ns2501_writeb(dvo, 0xc0, 0x05);	/* horizontal? */
451			ok &= ns2501_writeb(dvo, 0xc1, 0x90);
452
453			ok &= ns2501_writeb(dvo, 0xc2, 0x00);
454			ok &= ns2501_writeb(dvo, 0xc3, 0x0f);
455
456			ok &= ns2501_writeb(dvo, 0xc4, 0x03);
457			ok &= ns2501_writeb(dvo, 0xc5, 0x16);
458
459			ok &= ns2501_writeb(dvo, 0xc6, 0x00);
460			ok &= ns2501_writeb(dvo, 0xc7, 0x02);
461			ok &= ns2501_writeb(dvo, 0xc8, 0x02);
462
463		} else if (mode->hdisplay == 1024 && mode->vdisplay == 768) {
464			/* mode 280 */
465			DRM_DEBUG_KMS("%s: switching to 1024x768\n",
466				      __FUNCTION__);
467			/*
468			 * This might or might not work, actually. I'm silently
469			 * assuming here that the native panel resolution is
470			 * 1024x768. If not, then this leaves the scaler disabled
471			 * generating a picture that is likely not the expected.
472			 *
473			 * Problem is that I do not know where to take the panel
474			 * dimensions from.
475			 *
476			 * Enable the bypass, scaling not required.
477			 *
478			 * The scaler registers are irrelevant here....
479			 *
480			 */
481			ns->reg_8_shadow |= NS2501_8_BPAS;
482			ok &= ns2501_writeb(dvo, 0x37, 0x44);
483		} else {
484			/*
485			 * Data not known. Bummer!
486			 * Hopefully, the code should not go here
487			 * as mode_OK delivered no other modes.
488			 */
489			ns->reg_8_shadow |= NS2501_8_BPAS;
490		}
491		ok &= ns2501_writeb(dvo, NS2501_REG8, ns->reg_8_shadow);
492
493		if (!ok) {
494			if (restore)
495				restore_dvo(dvo);
496			enable_dvo(dvo);
497			restore = true;
498		}
499	} while (!ok);
500	/*
501	 * Restore the old i915 registers before
502	 * forcing the ns2501 on.
503	 */
504	if (restore)
505		restore_dvo(dvo);
506}
507
508/* set the NS2501 power state */
509static bool ns2501_get_hw_state(struct intel_dvo_device *dvo)
510{
511	unsigned char ch;
512
513	if (!ns2501_readb(dvo, NS2501_REG8, &ch))
514		return false;
515
516	if (ch & NS2501_8_PD)
517		return true;
518	else
519		return false;
520}
521
522/* set the NS2501 power state */
523static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable)
524{
525	bool ok;
526	bool restore = false;
527	struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
528	unsigned char ch;
529
530	DRM_DEBUG_KMS("%s: Trying set the dpms of the DVO to %i\n",
531		      __FUNCTION__, enable);
532
533	ch = ns->reg_8_shadow;
534
535	if (enable)
536		ch |= NS2501_8_PD;
537	else
538		ch &= ~NS2501_8_PD;
539
540	if (ns->reg_8_set == 0 || ns->reg_8_shadow != ch) {
541		ns->reg_8_set = 1;
542		ns->reg_8_shadow = ch;
543
544		do {
545			ok = true;
546			ok &= ns2501_writeb(dvo, NS2501_REG8, ch);
547			ok &=
548			    ns2501_writeb(dvo, 0x34,
549					  enable ? 0x03 : 0x00);
550			ok &=
551			    ns2501_writeb(dvo, 0x35,
552					  enable ? 0xff : 0x00);
553			if (!ok) {
554				if (restore)
555					restore_dvo(dvo);
556				enable_dvo(dvo);
557				restore = true;
558			}
559		} while (!ok);
560
561		if (restore)
562			restore_dvo(dvo);
563	}
564}
565
566static void ns2501_dump_regs(struct intel_dvo_device *dvo)
567{
568	uint8_t val;
569
570	ns2501_readb(dvo, NS2501_FREQ_LO, &val);
571	DRM_LOG_KMS("NS2501_FREQ_LO: 0x%02x\n", val);
572	ns2501_readb(dvo, NS2501_FREQ_HI, &val);
573	DRM_LOG_KMS("NS2501_FREQ_HI: 0x%02x\n", val);
574	ns2501_readb(dvo, NS2501_REG8, &val);
575	DRM_LOG_KMS("NS2501_REG8: 0x%02x\n", val);
576	ns2501_readb(dvo, NS2501_REG9, &val);
577	DRM_LOG_KMS("NS2501_REG9: 0x%02x\n", val);
578	ns2501_readb(dvo, NS2501_REGC, &val);
579	DRM_LOG_KMS("NS2501_REGC: 0x%02x\n", val);
580}
581
582static void ns2501_destroy(struct intel_dvo_device *dvo)
583{
584	struct ns2501_priv *ns = dvo->dev_priv;
585
586	if (ns) {
587		free(ns, DRM_MEM_KMS);
588		dvo->dev_priv = NULL;
589	}
590}
591
592struct intel_dvo_dev_ops ns2501_ops = {
593	.init = ns2501_init,
594	.detect = ns2501_detect,
595	.mode_valid = ns2501_mode_valid,
596	.mode_set = ns2501_mode_set,
597	.dpms = ns2501_dpms,
598	.get_hw_state = ns2501_get_hw_state,
599	.dump_regs = ns2501_dump_regs,
600	.destroy = ns2501_destroy,
601};
602