• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/gpu/drm/nouveau/
1/*
2 * Copyright 2003 NVIDIA, Corporation
3 * Copyright 2006 Dave Airlie
4 * Copyright 2007 Maarten Maathuis
5 * Copyright 2007-2009 Stuart Bennett
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 */
26
27#include "drmP.h"
28#include "drm_crtc_helper.h"
29
30#include "nouveau_drv.h"
31#include "nouveau_encoder.h"
32#include "nouveau_connector.h"
33#include "nouveau_crtc.h"
34#include "nouveau_hw.h"
35#include "nvreg.h"
36
37int nv04_dac_output_offset(struct drm_encoder *encoder)
38{
39	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
40	int offset = 0;
41
42	if (dcb->or & (8 | OUTPUT_C))
43		offset += 0x68;
44	if (dcb->or & (8 | OUTPUT_B))
45		offset += 0x2000;
46
47	return offset;
48}
49
50/*
51 * arbitrary limit to number of sense oscillations tolerated in one sample
52 * period (observed to be at least 13 in "nvidia")
53 */
54#define MAX_HBLANK_OSC 20
55
56/*
57 * arbitrary limit to number of conflicting sample pairs to tolerate at a
58 * voltage step (observed to be at least 5 in "nvidia")
59 */
60#define MAX_SAMPLE_PAIRS 10
61
62static int sample_load_twice(struct drm_device *dev, bool sense[2])
63{
64	int i;
65
66	for (i = 0; i < 2; i++) {
67		bool sense_a, sense_b, sense_b_prime;
68		int j = 0;
69
70		/*
71		 * wait for bit 0 clear -- out of hblank -- (say reg value 0x4),
72		 * then wait for transition 0x4->0x5->0x4: enter hblank, leave
73		 * hblank again
74		 * use a 10ms timeout (guards against crtc being inactive, in
75		 * which case blank state would never change)
76		 */
77		if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
78					0x00000001, 0x00000000))
79			return -EBUSY;
80		if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
81					0x00000001, 0x00000001))
82			return -EBUSY;
83		if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR,
84					0x00000001, 0x00000000))
85			return -EBUSY;
86
87		udelay(100);
88		/* when level triggers, sense is _LO_ */
89		sense_a = nv_rd08(dev, NV_PRMCIO_INP0) & 0x10;
90
91		/* take another reading until it agrees with sense_a... */
92		do {
93			udelay(100);
94			sense_b = nv_rd08(dev, NV_PRMCIO_INP0) & 0x10;
95			if (sense_a != sense_b) {
96				sense_b_prime =
97					nv_rd08(dev, NV_PRMCIO_INP0) & 0x10;
98				if (sense_b == sense_b_prime) {
99					/* ... unless two consecutive subsequent
100					 * samples agree; sense_a is replaced */
101					sense_a = sense_b;
102					/* force mis-match so we loop */
103					sense_b = !sense_a;
104				}
105			}
106		} while ((sense_a != sense_b) && ++j < MAX_HBLANK_OSC);
107
108		if (j == MAX_HBLANK_OSC)
109			/* with so much oscillation, default to sense:LO */
110			sense[i] = false;
111		else
112			sense[i] = sense_a;
113	}
114
115	return 0;
116}
117
118static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder,
119						 struct drm_connector *connector)
120{
121	struct drm_device *dev = encoder->dev;
122	uint8_t saved_seq1, saved_pi, saved_rpc1, saved_cr_mode;
123	uint8_t saved_palette0[3], saved_palette_mask;
124	uint32_t saved_rtest_ctrl, saved_rgen_ctrl;
125	int i;
126	uint8_t blue;
127	bool sense = true;
128
129	/*
130	 * for this detection to work, there needs to be a mode set up on the
131	 * CRTC.  this is presumed to be the case
132	 */
133
134	if (nv_two_heads(dev))
135		/* only implemented for head A for now */
136		NVSetOwner(dev, 0);
137
138	saved_cr_mode = NVReadVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX);
139	NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode | 0x80);
140
141	saved_seq1 = NVReadVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX);
142	NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20);
143
144	saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL);
145	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL,
146		      saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF);
147
148	msleep(10);
149
150	saved_pi = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX);
151	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX,
152		       saved_pi & ~(0x80 | MASK(NV_CIO_CRE_PIXEL_FORMAT)));
153	saved_rpc1 = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX);
154	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1 & ~0xc0);
155
156	nv_wr08(dev, NV_PRMDIO_READ_MODE_ADDRESS, 0x0);
157	for (i = 0; i < 3; i++)
158		saved_palette0[i] = nv_rd08(dev, NV_PRMDIO_PALETTE_DATA);
159	saved_palette_mask = nv_rd08(dev, NV_PRMDIO_PIXEL_MASK);
160	nv_wr08(dev, NV_PRMDIO_PIXEL_MASK, 0);
161
162	saved_rgen_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL);
163	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL,
164		      (saved_rgen_ctrl & ~(NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS |
165					   NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM)) |
166		      NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON);
167
168	blue = 8;	/* start of test range */
169
170	do {
171		bool sense_pair[2];
172
173		nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
174		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, 0);
175		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, 0);
176		/* testing blue won't find monochrome monitors.  I don't care */
177		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, blue);
178
179		i = 0;
180		/* take sample pairs until both samples in the pair agree */
181		do {
182			if (sample_load_twice(dev, sense_pair))
183				goto out;
184		} while ((sense_pair[0] != sense_pair[1]) &&
185							++i < MAX_SAMPLE_PAIRS);
186
187		if (i == MAX_SAMPLE_PAIRS)
188			/* too much oscillation defaults to LO */
189			sense = false;
190		else
191			sense = sense_pair[0];
192
193	/*
194	 * if sense goes LO before blue ramps to 0x18, monitor is not connected.
195	 * ergo, if blue gets to 0x18, monitor must be connected
196	 */
197	} while (++blue < 0x18 && sense);
198
199out:
200	nv_wr08(dev, NV_PRMDIO_PIXEL_MASK, saved_palette_mask);
201	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL, saved_rgen_ctrl);
202	nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
203	for (i = 0; i < 3; i++)
204		nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, saved_palette0[i]);
205	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL, saved_rtest_ctrl);
206	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi);
207	NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1);
208	NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1);
209	NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode);
210
211	if (blue == 0x18) {
212		NV_INFO(dev, "Load detected on head A\n");
213		return connector_status_connected;
214	}
215
216	return connector_status_disconnected;
217}
218
219uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
220{
221	struct drm_device *dev = encoder->dev;
222	struct drm_nouveau_private *dev_priv = dev->dev_private;
223	struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio;
224	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
225	uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder);
226	uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput,
227		saved_rtest_ctrl, saved_gpio0, saved_gpio1, temp, routput;
228	int head;
229
230#define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20)
231	if (dcb->type == OUTPUT_TV) {
232		testval = RGB_TEST_DATA(0xa0, 0xa0, 0xa0);
233
234		if (dev_priv->vbios.tvdactestval)
235			testval = dev_priv->vbios.tvdactestval;
236	} else {
237		testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */
238
239		if (dev_priv->vbios.dactestval)
240			testval = dev_priv->vbios.dactestval;
241	}
242
243	saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
244	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset,
245		      saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF);
246
247	saved_powerctrl_2 = nvReadMC(dev, NV_PBUS_POWERCTRL_2);
248
249	nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2 & 0xd7ffffff);
250	if (regoffset == 0x68) {
251		saved_powerctrl_4 = nvReadMC(dev, NV_PBUS_POWERCTRL_4);
252		nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf);
253	}
254
255	saved_gpio1 = gpio->get(dev, DCB_GPIO_TVDAC1);
256	saved_gpio0 = gpio->get(dev, DCB_GPIO_TVDAC0);
257
258	gpio->set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV);
259	gpio->set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV);
260
261	msleep(4);
262
263	saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
264	head = (saved_routput & 0x100) >> 8;
265
266	/* if there's a spare crtc, using it will minimise flicker */
267	if (!(NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX) & 0xC0))
268		head ^= 1;
269
270	/* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */
271	routput = (saved_routput & 0xfffffece) | head << 8;
272
273	if (dev_priv->card_type >= NV_40) {
274		if (dcb->type == OUTPUT_TV)
275			routput |= 0x1a << 16;
276		else
277			routput &= ~(0x1a << 16);
278	}
279
280	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, routput);
281	msleep(1);
282
283	temp = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
284	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, temp | 1);
285
286	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TESTPOINT_DATA,
287		      NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK | testval);
288	temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL);
289	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL,
290		      temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED);
291	msleep(5);
292
293	sample = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
294
295	temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL);
296	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL,
297		      temp & ~NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED);
298	NVWriteRAMDAC(dev, head, NV_PRAMDAC_TESTPOINT_DATA, 0);
299
300	/* bios does something more complex for restoring, but I think this is good enough */
301	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, saved_routput);
302	NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, saved_rtest_ctrl);
303	if (regoffset == 0x68)
304		nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4);
305	nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2);
306
307	gpio->set(dev, DCB_GPIO_TVDAC1, saved_gpio1);
308	gpio->set(dev, DCB_GPIO_TVDAC0, saved_gpio0);
309
310	return sample;
311}
312
313static enum drm_connector_status
314nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
315{
316	struct drm_device *dev = encoder->dev;
317	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
318
319	if (nv04_dac_in_use(encoder))
320		return connector_status_disconnected;
321
322	if (nv17_dac_sample_load(encoder) &
323	    NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) {
324		NV_INFO(dev, "Load detected on output %c\n",
325			'@' + ffs(dcb->or));
326		return connector_status_connected;
327	} else {
328		return connector_status_disconnected;
329	}
330}
331
332static bool nv04_dac_mode_fixup(struct drm_encoder *encoder,
333				struct drm_display_mode *mode,
334				struct drm_display_mode *adjusted_mode)
335{
336	if (nv04_dac_in_use(encoder))
337		return false;
338
339	return true;
340}
341
342static void nv04_dac_prepare(struct drm_encoder *encoder)
343{
344	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
345	struct drm_device *dev = encoder->dev;
346	struct drm_nouveau_private *dev_priv = dev->dev_private;
347	int head = nouveau_crtc(encoder->crtc)->index;
348	struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg;
349
350	helper->dpms(encoder, DRM_MODE_DPMS_OFF);
351
352	nv04_dfp_disable(dev, head);
353
354	/* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f)
355	 * at LCD__INDEX which we don't alter
356	 */
357	if (!(crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX] & 0x44))
358		crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX] = 0;
359}
360
361
362static void nv04_dac_mode_set(struct drm_encoder *encoder,
363			      struct drm_display_mode *mode,
364			      struct drm_display_mode *adjusted_mode)
365{
366	struct drm_device *dev = encoder->dev;
367	struct drm_nouveau_private *dev_priv = dev->dev_private;
368	int head = nouveau_crtc(encoder->crtc)->index;
369
370	if (nv_gf4_disp_arch(dev)) {
371		struct drm_encoder *rebind;
372		uint32_t dac_offset = nv04_dac_output_offset(encoder);
373		uint32_t otherdac;
374
375		/* bit 16-19 are bits that are set on some G70 cards,
376		 * but don't seem to have much effect */
377		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset,
378			      head << 8 | NV_PRAMDAC_DACCLK_SEL_DACCLK);
379		/* force any other vga encoders to bind to the other crtc */
380		list_for_each_entry(rebind, &dev->mode_config.encoder_list, head) {
381			if (rebind == encoder
382			    || nouveau_encoder(rebind)->dcb->type != OUTPUT_ANALOG)
383				continue;
384
385			dac_offset = nv04_dac_output_offset(rebind);
386			otherdac = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset);
387			NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset,
388				      (otherdac & ~0x0100) | (head ^ 1) << 8);
389		}
390	}
391
392	/* This could use refinement for flatpanels, but it should work this way */
393	if (dev_priv->chipset < 0x44)
394		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0xf0000000);
395	else
396		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000);
397}
398
399static void nv04_dac_commit(struct drm_encoder *encoder)
400{
401	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
402	struct drm_device *dev = encoder->dev;
403	struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
404	struct drm_encoder_helper_funcs *helper = encoder->helper_private;
405
406	helper->dpms(encoder, DRM_MODE_DPMS_ON);
407
408	NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
409		drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
410		nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
411}
412
413void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable)
414{
415	struct drm_device *dev = encoder->dev;
416	struct drm_nouveau_private *dev_priv = dev->dev_private;
417	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
418
419	if (nv_gf4_disp_arch(dev)) {
420		uint32_t *dac_users = &dev_priv->dac_users[ffs(dcb->or) - 1];
421		int dacclk_off = NV_PRAMDAC_DACCLK + nv04_dac_output_offset(encoder);
422		uint32_t dacclk = NVReadRAMDAC(dev, 0, dacclk_off);
423
424		if (enable) {
425			*dac_users |= 1 << dcb->index;
426			NVWriteRAMDAC(dev, 0, dacclk_off, dacclk | NV_PRAMDAC_DACCLK_SEL_DACCLK);
427
428		} else {
429			*dac_users &= ~(1 << dcb->index);
430			if (!*dac_users)
431				NVWriteRAMDAC(dev, 0, dacclk_off,
432					dacclk & ~NV_PRAMDAC_DACCLK_SEL_DACCLK);
433		}
434	}
435}
436
437/* Check if the DAC corresponding to 'encoder' is being used by
438 * someone else. */
439bool nv04_dac_in_use(struct drm_encoder *encoder)
440{
441	struct drm_nouveau_private *dev_priv = encoder->dev->dev_private;
442	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
443
444	return nv_gf4_disp_arch(encoder->dev) &&
445		(dev_priv->dac_users[ffs(dcb->or) - 1] & ~(1 << dcb->index));
446}
447
448static void nv04_dac_dpms(struct drm_encoder *encoder, int mode)
449{
450	struct drm_device *dev = encoder->dev;
451	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
452
453	if (nv_encoder->last_dpms == mode)
454		return;
455	nv_encoder->last_dpms = mode;
456
457	NV_INFO(dev, "Setting dpms mode %d on vga encoder (output %d)\n",
458		     mode, nv_encoder->dcb->index);
459
460	nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON);
461}
462
463static void nv04_dac_save(struct drm_encoder *encoder)
464{
465	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
466	struct drm_device *dev = encoder->dev;
467
468	if (nv_gf4_disp_arch(dev))
469		nv_encoder->restore.output = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK +
470							  nv04_dac_output_offset(encoder));
471}
472
473static void nv04_dac_restore(struct drm_encoder *encoder)
474{
475	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
476	struct drm_device *dev = encoder->dev;
477
478	if (nv_gf4_disp_arch(dev))
479		NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + nv04_dac_output_offset(encoder),
480			      nv_encoder->restore.output);
481
482	nv_encoder->last_dpms = NV_DPMS_CLEARED;
483}
484
485static void nv04_dac_destroy(struct drm_encoder *encoder)
486{
487	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
488
489	NV_DEBUG_KMS(encoder->dev, "\n");
490
491	drm_encoder_cleanup(encoder);
492	kfree(nv_encoder);
493}
494
495static const struct drm_encoder_helper_funcs nv04_dac_helper_funcs = {
496	.dpms = nv04_dac_dpms,
497	.save = nv04_dac_save,
498	.restore = nv04_dac_restore,
499	.mode_fixup = nv04_dac_mode_fixup,
500	.prepare = nv04_dac_prepare,
501	.commit = nv04_dac_commit,
502	.mode_set = nv04_dac_mode_set,
503	.detect = nv04_dac_detect
504};
505
506static const struct drm_encoder_helper_funcs nv17_dac_helper_funcs = {
507	.dpms = nv04_dac_dpms,
508	.save = nv04_dac_save,
509	.restore = nv04_dac_restore,
510	.mode_fixup = nv04_dac_mode_fixup,
511	.prepare = nv04_dac_prepare,
512	.commit = nv04_dac_commit,
513	.mode_set = nv04_dac_mode_set,
514	.detect = nv17_dac_detect
515};
516
517static const struct drm_encoder_funcs nv04_dac_funcs = {
518	.destroy = nv04_dac_destroy,
519};
520
521int
522nv04_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
523{
524	const struct drm_encoder_helper_funcs *helper;
525	struct nouveau_encoder *nv_encoder = NULL;
526	struct drm_device *dev = connector->dev;
527	struct drm_encoder *encoder;
528
529	nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
530	if (!nv_encoder)
531		return -ENOMEM;
532
533	encoder = to_drm_encoder(nv_encoder);
534
535	nv_encoder->dcb = entry;
536	nv_encoder->or = ffs(entry->or) - 1;
537
538	if (nv_gf4_disp_arch(dev))
539		helper = &nv17_dac_helper_funcs;
540	else
541		helper = &nv04_dac_helper_funcs;
542
543	drm_encoder_init(dev, encoder, &nv04_dac_funcs, DRM_MODE_ENCODER_DAC);
544	drm_encoder_helper_add(encoder, helper);
545
546	encoder->possible_crtcs = entry->heads;
547	encoder->possible_clones = 0;
548
549	drm_mode_connector_attach_encoder(connector, encoder);
550	return 0;
551}
552