nv50_display.c 12.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 * Copyright (C) 2008 Maarten Maathuis.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

27 28 29
#include "nouveau_drm.h"
#include "nouveau_dma.h"

30 31 32 33
#include "nv50_display.h"
#include "nouveau_crtc.h"
#include "nouveau_encoder.h"
#include "nouveau_connector.h"
34
#include "nouveau_fbcon.h"
35
#include <drm/drm_crtc_helper.h>
36
#include "nouveau_fence.h"
37

38
#include <core/gpuobj.h>
39 40
#include <core/class.h>

41
#include <subdev/timer.h>
42

43 44 45
static inline int
nv50_sor_nr(struct drm_device *dev)
{
46
	struct nouveau_device *device = nouveau_dev(dev);
47

48 49 50
	if (device->chipset  < 0x90 ||
	    device->chipset == 0x92 ||
	    device->chipset == 0xa0)
51 52 53 54 55
		return 2;

	return 4;
}

56 57 58
u32
nv50_display_active_crtcs(struct drm_device *dev)
{
59
	struct nouveau_device *device = nouveau_dev(dev);
60 61 62
	u32 mask = 0;
	int i;

63 64 65
	if (device->chipset  < 0x90 ||
	    device->chipset == 0x92 ||
	    device->chipset == 0xa0) {
66
		for (i = 0; i < 2; i++)
67
			mask |= nv_rd32(device, NV50_PDISPLAY_SOR_MODE_CTRL_C(i));
68 69
	} else {
		for (i = 0; i < 4; i++)
70
			mask |= nv_rd32(device, NV90_PDISPLAY_SOR_MODE_CTRL_C(i));
71 72 73
	}

	for (i = 0; i < 3; i++)
74
		mask |= nv_rd32(device, NV50_PDISPLAY_DAC_MODE_CTRL_C(i));
75 76 77 78

	return mask & 3;
}

79 80 81 82 83 84 85 86 87 88 89
int
nv50_display_early_init(struct drm_device *dev)
{
	return 0;
}

void
nv50_display_late_takedown(struct drm_device *dev)
{
}

90 91 92 93 94 95 96 97 98
int
nv50_display_sync(struct drm_device *dev)
{
	struct nv50_display *disp = nv50_display(dev);
	struct nouveau_channel *evo = disp->master;
	int ret;

	ret = RING_SPACE(evo, 6);
	if (ret == 0) {
99
		BEGIN_NV04(evo, 0, 0x0084, 1);
100
		OUT_RING  (evo, 0x80000000);
101
		BEGIN_NV04(evo, 0, 0x0080, 1);
102
		OUT_RING  (evo, 0);
103
		BEGIN_NV04(evo, 0, 0x0084, 1);
104 105
		OUT_RING  (evo, 0x00000000);

106
		nv_wo32(disp->ramin, 0x2000, 0x00000000);
107 108
		FIRE_RING (evo);

109 110
		if (nv_wait_ne(disp->ramin, 0x2000, 0xffffffff, 0x00000000))
			return 0;
111 112
	}

113
	return 0;
114 115
}

116 117 118
int
nv50_display_init(struct drm_device *dev)
{
119 120
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nouveau_device *device = nouveau_dev(dev);
121
	struct nouveau_channel *evo;
122 123 124
	int ret, i;

	for (i = 0; i < 3; i++) {
125
		nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(i), 0x00550000 |
126
			NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
127
		nv_wr32(device, NV50_PDISPLAY_DAC_CLK_CTRL1(i), 0x00000001);
128 129
	}

130
	for (i = 0; i < 2; i++) {
131 132
		nv_wr32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000);
		if (!nv_wait(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
133
			     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) {
134 135 136
			NV_ERROR(drm, "timeout: CURSOR_CTRL2_STATUS == 0\n");
			NV_ERROR(drm, "CURSOR_CTRL2 = 0x%08x\n",
				 nv_rd32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
137 138 139
			return -EBUSY;
		}

140
		nv_wr32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
141
			NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON);
142
		if (!nv_wait(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
143 144
			     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS,
			     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) {
145
			NV_ERROR(drm, "timeout: "
146
				      "CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", i);
147 148
			NV_ERROR(drm, "CURSOR_CTRL2(%d) = 0x%08x\n", i,
				 nv_rd32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
149 150 151 152
			return -EBUSY;
		}
	}

153
	ret = nv50_evo_init(dev);
154 155
	if (ret)
		return ret;
156
	evo = nv50_display(dev)->master;
157

158
	ret = RING_SPACE(evo, 3);
159 160
	if (ret)
		return ret;
161
	BEGIN_NV04(evo, 0, NV50_EVO_UNK84, 2);
162 163
	OUT_RING  (evo, NV50_EVO_UNK84_NOTIFY_DISABLED);
	OUT_RING  (evo, NvEvoSync);
164

165
	return nv50_display_sync(dev);
166 167
}

168 169
void
nv50_display_fini(struct drm_device *dev)
170
{
171 172
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nouveau_device *device = nouveau_dev(dev);
173
	struct nv50_display *disp = nv50_display(dev);
174
	struct nouveau_channel *evo = disp->master;
175 176 177 178 179 180 181 182 183
	struct drm_crtc *drm_crtc;
	int ret, i;

	list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) {
		struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc);

		nv50_crtc_blank(crtc, true);
	}

184
	ret = RING_SPACE(evo, 2);
185
	if (ret == 0) {
186
		BEGIN_NV04(evo, 0, NV50_EVO_UPDATE, 1);
187
		OUT_RING(evo, 0);
188
	}
189
	FIRE_RING(evo);
190 191 192 193 194 195 196 197 198 199 200

	/* Almost like ack'ing a vblank interrupt, maybe in the spirit of
	 * cleaning up?
	 */
	list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) {
		struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc);
		uint32_t mask = NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(crtc->index);

		if (!crtc->base.enabled)
			continue;

201 202 203
		nv_wr32(device, NV50_PDISPLAY_INTR_1, mask);
		if (!nv_wait(device, NV50_PDISPLAY_INTR_1, mask, mask)) {
			NV_ERROR(drm, "timeout: (0x610024 & 0x%08x) == "
204
				      "0x%08x\n", mask, mask);
205 206
			NV_ERROR(drm, "0x610024 = 0x%08x\n",
				 nv_rd32(device, NV50_PDISPLAY_INTR_1));
207 208 209
		}
	}

210
	for (i = 0; i < 2; i++) {
211 212
		nv_wr32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0);
		if (!nv_wait(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
213
			     NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) {
214 215 216
			NV_ERROR(drm, "timeout: CURSOR_CTRL2_STATUS == 0\n");
			NV_ERROR(drm, "CURSOR_CTRL2 = 0x%08x\n",
				 nv_rd32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
217 218 219
		}
	}

220
	nv50_evo_fini(dev);
221 222

	for (i = 0; i < 3; i++) {
223
		if (!nv_wait(device, NV50_PDISPLAY_SOR_DPMS_STATE(i),
224
			     NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) {
225 226 227
			NV_ERROR(drm, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", i);
			NV_ERROR(drm, "SOR_DPMS_STATE(%d) = 0x%08x\n", i,
				  nv_rd32(device, NV50_PDISPLAY_SOR_DPMS_STATE(i)));
228 229 230 231
		}
	}
}

232 233
int
nv50_display_create(struct drm_device *dev)
234
{
235 236 237 238 239 240 241
	static const u16 oclass[] = {
		NVA3_DISP_CLASS,
		NV94_DISP_CLASS,
		NVA0_DISP_CLASS,
		NV84_DISP_CLASS,
		NV50_DISP_CLASS,
	};
242 243
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct dcb_table *dcb = &drm->vbios.dcb;
244
	struct drm_connector *connector, *ct;
245
	struct nv50_display *priv;
246
	int ret, i;
247

248 249 250
	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
251 252 253 254 255

	nouveau_display(dev)->priv = priv;
	nouveau_display(dev)->dtor = nv50_display_destroy;
	nouveau_display(dev)->init = nv50_display_init;
	nouveau_display(dev)->fini = nv50_display_fini;
256

257 258 259 260 261 262 263 264 265 266 267
	/* attempt to allocate a supported evo display class */
	ret = -ENODEV;
	for (i = 0; ret && i < ARRAY_SIZE(oclass); i++) {
		ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE,
					 0xd1500000, oclass[i], NULL, 0,
					 &priv->core);
	}

	if (ret)
		return ret;

268
	/* Create CRTC objects */
269 270 271 272 273
	for (i = 0; i < 2; i++) {
		ret = nv50_crtc_create(dev, i);
		if (ret)
			return ret;
	}
274 275 276

	/* We setup the encoders from the BIOS table */
	for (i = 0 ; i < dcb->entries; i++) {
277
		struct dcb_output *entry = &dcb->entry[i];
278 279

		if (entry->location != DCB_LOC_ON_CHIP) {
280
			NV_WARN(drm, "Off-chip encoder %d/%d unsupported\n",
281 282 283 284
				entry->type, ffs(entry->or) - 1);
			continue;
		}

285 286 287 288
		connector = nouveau_connector_create(dev, entry->connector);
		if (IS_ERR(connector))
			continue;

289
		switch (entry->type) {
290 291 292
		case DCB_OUTPUT_TMDS:
		case DCB_OUTPUT_LVDS:
		case DCB_OUTPUT_DP:
293
			nv50_sor_create(connector, entry);
294
			break;
295
		case DCB_OUTPUT_ANALOG:
296
			nv50_dac_create(connector, entry);
297 298
			break;
		default:
299
			NV_WARN(drm, "DCB encoder %d unknown\n", entry->type);
300 301 302 303
			continue;
		}
	}

304 305 306
	list_for_each_entry_safe(connector, ct,
				 &dev->mode_config.connector_list, head) {
		if (!connector->encoder_ids[0]) {
307
			NV_WARN(drm, "%s has no encoders, removing\n",
308 309 310
				drm_get_connector_name(connector));
			connector->funcs->destroy(connector);
		}
311 312
	}

313 314 315 316 317 318
	ret = nv50_evo_create(dev);
	if (ret) {
		nv50_display_destroy(dev);
		return ret;
	}

319 320 321
	return 0;
}

322 323
void
nv50_display_destroy(struct drm_device *dev)
324
{
325
	struct nv50_display *disp = nv50_display(dev);
326

327
	nv50_evo_destroy(dev);
328
	kfree(disp);
329 330
}

331 332 333 334 335 336
struct nouveau_bo *
nv50_display_crtc_sema(struct drm_device *dev, int crtc)
{
	return nv50_display(dev)->crtc[crtc].sem.bo;
}

337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
void
nv50_display_flip_stop(struct drm_crtc *crtc)
{
	struct nv50_display *disp = nv50_display(crtc->dev);
	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
	struct nv50_display_crtc *dispc = &disp->crtc[nv_crtc->index];
	struct nouveau_channel *evo = dispc->sync;
	int ret;

	ret = RING_SPACE(evo, 8);
	if (ret) {
		WARN_ON(1);
		return;
	}

352
	BEGIN_NV04(evo, 0, 0x0084, 1);
353
	OUT_RING  (evo, 0x00000000);
354
	BEGIN_NV04(evo, 0, 0x0094, 1);
355
	OUT_RING  (evo, 0x00000000);
356
	BEGIN_NV04(evo, 0, 0x00c0, 1);
357
	OUT_RING  (evo, 0x00000000);
358
	BEGIN_NV04(evo, 0, 0x0080, 1);
359 360 361 362 363 364 365 366
	OUT_RING  (evo, 0x00000000);
	FIRE_RING (evo);
}

int
nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
		       struct nouveau_channel *chan)
{
367
	struct nouveau_drm *drm = nouveau_drm(crtc->dev);
368 369 370 371 372 373 374
	struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb);
	struct nv50_display *disp = nv50_display(crtc->dev);
	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
	struct nv50_display_crtc *dispc = &disp->crtc[nv_crtc->index];
	struct nouveau_channel *evo = dispc->sync;
	int ret;

375
	ret = RING_SPACE(evo, chan ? 25 : 27);
376 377 378 379 380 381 382 383 384 385 386
	if (unlikely(ret))
		return ret;

	/* synchronise with the rendering channel, if necessary */
	if (likely(chan)) {
		ret = RING_SPACE(chan, 10);
		if (ret) {
			WIND_RING(evo);
			return ret;
		}

387
		if (nv_device(drm->device)->chipset < 0xc0) {
388
			BEGIN_NV04(chan, 0, 0x0060, 2);
389 390
			OUT_RING  (chan, NvEvoSema0 + nv_crtc->index);
			OUT_RING  (chan, dispc->sem.offset);
391
			BEGIN_NV04(chan, 0, 0x006c, 1);
392
			OUT_RING  (chan, 0xf00d0000 | dispc->sem.value);
393
			BEGIN_NV04(chan, 0, 0x0064, 2);
394 395
			OUT_RING  (chan, dispc->sem.offset ^ 0x10);
			OUT_RING  (chan, 0x74b1e000);
396
			BEGIN_NV04(chan, 0, 0x0060, 1);
397
			if (nv_device(drm->device)->chipset < 0x84)
398 399
				OUT_RING  (chan, NvSema);
			else
400
				OUT_RING  (chan, chan->vram);
401
		} else {
402
			u64 offset = nvc0_fence_crtc(chan, nv_crtc->index);
403
			offset += dispc->sem.offset;
404
			BEGIN_NVC0(chan, 0, 0x0010, 4);
405 406 407 408
			OUT_RING  (chan, upper_32_bits(offset));
			OUT_RING  (chan, lower_32_bits(offset));
			OUT_RING  (chan, 0xf00d0000 | dispc->sem.value);
			OUT_RING  (chan, 0x1002);
409
			BEGIN_NVC0(chan, 0, 0x0010, 4);
410 411 412 413 414 415 416 417 418 419 420 421
			OUT_RING  (chan, upper_32_bits(offset));
			OUT_RING  (chan, lower_32_bits(offset ^ 0x10));
			OUT_RING  (chan, 0x74b1e000);
			OUT_RING  (chan, 0x1001);
		}
		FIRE_RING (chan);
	} else {
		nouveau_bo_wr32(dispc->sem.bo, dispc->sem.offset / 4,
				0xf00d0000 | dispc->sem.value);
	}

	/* queue the flip on the crtc's "display sync" channel */
422
	BEGIN_NV04(evo, 0, 0x0100, 1);
423
	OUT_RING  (evo, 0xfffe0000);
424
	if (chan) {
425
		BEGIN_NV04(evo, 0, 0x0084, 1);
426 427
		OUT_RING  (evo, 0x00000100);
	} else {
428
		BEGIN_NV04(evo, 0, 0x0084, 1);
429 430 431 432
		OUT_RING  (evo, 0x00000010);
		/* allows gamma somehow, PDISP will bitch at you if
		 * you don't wait for vblank before changing this..
		 */
433
		BEGIN_NV04(evo, 0, 0x00e0, 1);
434 435
		OUT_RING  (evo, 0x40000000);
	}
436
	BEGIN_NV04(evo, 0, 0x0088, 4);
437 438 439 440
	OUT_RING  (evo, dispc->sem.offset);
	OUT_RING  (evo, 0xf00d0000 | dispc->sem.value);
	OUT_RING  (evo, 0x74b1e000);
	OUT_RING  (evo, NvEvoSync);
441
	BEGIN_NV04(evo, 0, 0x00a0, 2);
442 443
	OUT_RING  (evo, 0x00000000);
	OUT_RING  (evo, 0x00000000);
444
	BEGIN_NV04(evo, 0, 0x00c0, 1);
445
	OUT_RING  (evo, nv_fb->r_dma);
446
	BEGIN_NV04(evo, 0, 0x0110, 2);
447 448
	OUT_RING  (evo, 0x00000000);
	OUT_RING  (evo, 0x00000000);
449
	BEGIN_NV04(evo, 0, 0x0800, 5);
450
	OUT_RING  (evo, nv_fb->nvbo->bo.offset >> 8);
451 452 453 454
	OUT_RING  (evo, 0);
	OUT_RING  (evo, (fb->height << 16) | fb->width);
	OUT_RING  (evo, nv_fb->r_pitch);
	OUT_RING  (evo, nv_fb->r_format);
455
	BEGIN_NV04(evo, 0, 0x0080, 1);
456 457 458 459 460 461 462
	OUT_RING  (evo, 0x00000000);
	FIRE_RING (evo);

	dispc->sem.offset ^= 0x10;
	dispc->sem.value++;
	return 0;
}