Linux Audio

Check our new training course

Loading...
v5.4
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright 2010 Matt Turner.
   4 * Copyright 2012 Red Hat
   5 *
   6 * Authors: Matthew Garrett
   7 *	    Matt Turner
   8 *	    Dave Airlie
   9 */
  10
  11#include <linux/delay.h>
 
  12
  13#include <drm/drm_crtc_helper.h>
 
 
 
 
  14#include <drm/drm_fourcc.h>
  15#include <drm/drm_pci.h>
  16#include <drm/drm_plane_helper.h>
  17#include <drm/drm_probe_helper.h>
 
 
  18
 
  19#include "mgag200_drv.h"
  20
  21#define MGAG200_LUT_SIZE 256
  22
  23/*
  24 * This file contains setup code for the CRTC.
  25 */
  26
  27static void mga_crtc_load_lut(struct drm_crtc *crtc)
 
  28{
  29	struct drm_device *dev = crtc->dev;
  30	struct mga_device *mdev = dev->dev_private;
  31	struct drm_framebuffer *fb = crtc->primary->fb;
  32	u16 *r_ptr, *g_ptr, *b_ptr;
  33	int i;
  34
  35	if (!crtc->enabled)
  36		return;
  37
  38	r_ptr = crtc->gamma_store;
  39	g_ptr = r_ptr + crtc->gamma_size;
  40	b_ptr = g_ptr + crtc->gamma_size;
  41
  42	WREG8(DAC_INDEX + MGA1064_INDEX, 0);
  43
  44	if (fb && fb->format->cpp[0] * 8 == 16) {
  45		int inc = (fb->format->depth == 15) ? 8 : 4;
  46		u8 r, b;
  47		for (i = 0; i < MGAG200_LUT_SIZE; i += inc) {
  48			if (fb->format->depth == 16) {
  49				if (i > (MGAG200_LUT_SIZE >> 1)) {
  50					r = b = 0;
  51				} else {
  52					r = *r_ptr++ >> 8;
  53					b = *b_ptr++ >> 8;
  54					r_ptr++;
  55					b_ptr++;
  56				}
  57			} else {
  58				r = *r_ptr++ >> 8;
  59				b = *b_ptr++ >> 8;
  60			}
  61			/* VGA registers */
  62			WREG8(DAC_INDEX + MGA1064_COL_PAL, r);
  63			WREG8(DAC_INDEX + MGA1064_COL_PAL, *g_ptr++ >> 8);
  64			WREG8(DAC_INDEX + MGA1064_COL_PAL, b);
  65		}
  66		return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  67	}
  68	for (i = 0; i < MGAG200_LUT_SIZE; i++) {
  69		/* VGA registers */
  70		WREG8(DAC_INDEX + MGA1064_COL_PAL, *r_ptr++ >> 8);
  71		WREG8(DAC_INDEX + MGA1064_COL_PAL, *g_ptr++ >> 8);
  72		WREG8(DAC_INDEX + MGA1064_COL_PAL, *b_ptr++ >> 8);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  73	}
  74}
  75
  76static inline void mga_wait_vsync(struct mga_device *mdev)
  77{
  78	unsigned long timeout = jiffies + HZ/10;
  79	unsigned int status = 0;
  80
  81	do {
  82		status = RREG32(MGAREG_Status);
  83	} while ((status & 0x08) && time_before(jiffies, timeout));
  84	timeout = jiffies + HZ/10;
  85	status = 0;
  86	do {
  87		status = RREG32(MGAREG_Status);
  88	} while (!(status & 0x08) && time_before(jiffies, timeout));
  89}
  90
  91static inline void mga_wait_busy(struct mga_device *mdev)
  92{
  93	unsigned long timeout = jiffies + HZ;
  94	unsigned int status = 0;
  95	do {
  96		status = RREG8(MGAREG_Status + 2);
  97	} while ((status & 0x01) && time_before(jiffies, timeout));
  98}
  99
 100#define P_ARRAY_SIZE 9
 101
 102static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 103{
 104	unsigned int vcomax, vcomin, pllreffreq;
 105	unsigned int delta, tmpdelta, permitteddelta;
 106	unsigned int testp, testm, testn;
 107	unsigned int p, m, n;
 108	unsigned int computed;
 109	unsigned int pvalues_e4[P_ARRAY_SIZE] = {16, 14, 12, 10, 8, 6, 4, 2, 1};
 110	unsigned int fvv;
 111	unsigned int i;
 112
 113	if (mdev->unique_rev_id <= 0x03) {
 114
 115		m = n = p = 0;
 116		vcomax = 320000;
 117		vcomin = 160000;
 118		pllreffreq = 25000;
 119
 120		delta = 0xffffffff;
 121		permitteddelta = clock * 5 / 1000;
 122
 123		for (testp = 8; testp > 0; testp /= 2) {
 124			if (clock * testp > vcomax)
 125				continue;
 126			if (clock * testp < vcomin)
 127				continue;
 128
 129			for (testn = 17; testn < 256; testn++) {
 130				for (testm = 1; testm < 32; testm++) {
 131					computed = (pllreffreq * testn) /
 132						(testm * testp);
 133					if (computed > clock)
 134						tmpdelta = computed - clock;
 135					else
 136						tmpdelta = clock - computed;
 137					if (tmpdelta < delta) {
 138						delta = tmpdelta;
 139						m = testm - 1;
 140						n = testn - 1;
 141						p = testp - 1;
 142					}
 143				}
 144			}
 145		}
 146	} else {
 147
 148
 149		m = n = p = 0;
 150		vcomax        = 1600000;
 151		vcomin        = 800000;
 152		pllreffreq    = 25000;
 153
 154		if (clock < 25000)
 155			clock = 25000;
 156
 157		clock = clock * 2;
 158
 159		delta = 0xFFFFFFFF;
 160		/* Permited delta is 0.5% as VESA Specification */
 161		permitteddelta = clock * 5 / 1000;
 162
 163		for (i = 0 ; i < P_ARRAY_SIZE ; i++) {
 164			testp = pvalues_e4[i];
 165
 166			if ((clock * testp) > vcomax)
 167				continue;
 168			if ((clock * testp) < vcomin)
 169				continue;
 170
 171			for (testn = 50; testn <= 256; testn++) {
 172				for (testm = 1; testm <= 32; testm++) {
 173					computed = (pllreffreq * testn) /
 174						(testm * testp);
 175					if (computed > clock)
 176						tmpdelta = computed - clock;
 177					else
 178						tmpdelta = clock - computed;
 179
 180					if (tmpdelta < delta) {
 181						delta = tmpdelta;
 182						m = testm - 1;
 183						n = testn - 1;
 184						p = testp - 1;
 185					}
 186				}
 187			}
 188		}
 189
 190		fvv = pllreffreq * (n + 1) / (m + 1);
 191		fvv = (fvv - 800000) / 50000;
 192
 193		if (fvv > 15)
 194			fvv = 15;
 195
 196		p |= (fvv << 4);
 197		m |= 0x80;
 198
 199		clock = clock / 2;
 200	}
 201
 202	if (delta > permitteddelta) {
 203		pr_warn("PLL delta too large\n");
 204		return 1;
 205	}
 206
 207	WREG_DAC(MGA1064_PIX_PLLC_M, m);
 208	WREG_DAC(MGA1064_PIX_PLLC_N, n);
 209	WREG_DAC(MGA1064_PIX_PLLC_P, p);
 210
 211	if (mdev->unique_rev_id >= 0x04) {
 212		WREG_DAC(0x1a, 0x09);
 213		msleep(20);
 214		WREG_DAC(0x1a, 0x01);
 215
 216	}
 217
 218	return 0;
 219}
 220
 221static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
 222{
 223	unsigned int vcomax, vcomin, pllreffreq;
 224	unsigned int delta, tmpdelta;
 225	unsigned int testp, testm, testn, testp2;
 226	unsigned int p, m, n;
 227	unsigned int computed;
 228	int i, j, tmpcount, vcount;
 229	bool pll_locked = false;
 230	u8 tmp;
 231
 232	m = n = p = 0;
 233
 234	delta = 0xffffffff;
 235
 236	if (mdev->type == G200_EW3) {
 237
 238		vcomax = 800000;
 239		vcomin = 400000;
 240		pllreffreq = 25000;
 241
 242		for (testp = 1; testp < 8; testp++) {
 243			for (testp2 = 1; testp2 < 8; testp2++) {
 244				if (testp < testp2)
 245					continue;
 246				if ((clock * testp * testp2) > vcomax)
 247					continue;
 248				if ((clock * testp * testp2) < vcomin)
 249					continue;
 250				for (testm = 1; testm < 26; testm++) {
 251					for (testn = 32; testn < 2048 ; testn++) {
 252						computed = (pllreffreq * testn) /
 253							(testm * testp * testp2);
 254						if (computed > clock)
 255							tmpdelta = computed - clock;
 256						else
 257							tmpdelta = clock - computed;
 258						if (tmpdelta < delta) {
 259							delta = tmpdelta;
 260							m = ((testn & 0x100) >> 1) |
 261								(testm);
 262							n = (testn & 0xFF);
 263							p = ((testn & 0x600) >> 3) |
 264								(testp2 << 3) |
 265								(testp);
 266						}
 267					}
 268				}
 269			}
 270		}
 271	} else {
 272
 273		vcomax = 550000;
 274		vcomin = 150000;
 275		pllreffreq = 48000;
 276
 277		for (testp = 1; testp < 9; testp++) {
 278			if (clock * testp > vcomax)
 279				continue;
 280			if (clock * testp < vcomin)
 281				continue;
 282
 283			for (testm = 1; testm < 17; testm++) {
 284				for (testn = 1; testn < 151; testn++) {
 285					computed = (pllreffreq * testn) /
 286						(testm * testp);
 287					if (computed > clock)
 288						tmpdelta = computed - clock;
 289					else
 290						tmpdelta = clock - computed;
 291					if (tmpdelta < delta) {
 292						delta = tmpdelta;
 293						n = testn - 1;
 294						m = (testm - 1) |
 295							((n >> 1) & 0x80);
 296						p = testp - 1;
 297					}
 298				}
 299			}
 300		}
 301	}
 302
 303	for (i = 0; i <= 32 && pll_locked == false; i++) {
 304		if (i > 0) {
 305			WREG8(MGAREG_CRTC_INDEX, 0x1e);
 306			tmp = RREG8(MGAREG_CRTC_DATA);
 307			if (tmp < 0xff)
 308				WREG8(MGAREG_CRTC_DATA, tmp+1);
 309		}
 310
 311		/* set pixclkdis to 1 */
 312		WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 313		tmp = RREG8(DAC_DATA);
 314		tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
 315		WREG8(DAC_DATA, tmp);
 316
 317		WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
 318		tmp = RREG8(DAC_DATA);
 319		tmp |= MGA1064_REMHEADCTL_CLKDIS;
 320		WREG8(DAC_DATA, tmp);
 321
 322		/* select PLL Set C */
 323		tmp = RREG8(MGAREG_MEM_MISC_READ);
 324		tmp |= 0x3 << 2;
 325		WREG8(MGAREG_MEM_MISC_WRITE, tmp);
 326
 327		WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 328		tmp = RREG8(DAC_DATA);
 329		tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN | 0x80;
 330		WREG8(DAC_DATA, tmp);
 331
 332		udelay(500);
 333
 334		/* reset the PLL */
 335		WREG8(DAC_INDEX, MGA1064_VREF_CTL);
 336		tmp = RREG8(DAC_DATA);
 337		tmp &= ~0x04;
 338		WREG8(DAC_DATA, tmp);
 339
 340		udelay(50);
 341
 342		/* program pixel pll register */
 343		WREG_DAC(MGA1064_WB_PIX_PLLC_N, n);
 344		WREG_DAC(MGA1064_WB_PIX_PLLC_M, m);
 345		WREG_DAC(MGA1064_WB_PIX_PLLC_P, p);
 346
 347		udelay(50);
 348
 349		/* turn pll on */
 350		WREG8(DAC_INDEX, MGA1064_VREF_CTL);
 351		tmp = RREG8(DAC_DATA);
 352		tmp |= 0x04;
 353		WREG_DAC(MGA1064_VREF_CTL, tmp);
 354
 355		udelay(500);
 356
 357		/* select the pixel pll */
 358		WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 359		tmp = RREG8(DAC_DATA);
 360		tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
 361		tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
 362		WREG8(DAC_DATA, tmp);
 363
 364		WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
 365		tmp = RREG8(DAC_DATA);
 366		tmp &= ~MGA1064_REMHEADCTL_CLKSL_MSK;
 367		tmp |= MGA1064_REMHEADCTL_CLKSL_PLL;
 368		WREG8(DAC_DATA, tmp);
 369
 370		/* reset dotclock rate bit */
 371		WREG8(MGAREG_SEQ_INDEX, 1);
 372		tmp = RREG8(MGAREG_SEQ_DATA);
 373		tmp &= ~0x8;
 374		WREG8(MGAREG_SEQ_DATA, tmp);
 375
 376		WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 377		tmp = RREG8(DAC_DATA);
 378		tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
 379		WREG8(DAC_DATA, tmp);
 380
 381		vcount = RREG8(MGAREG_VCOUNT);
 382
 383		for (j = 0; j < 30 && pll_locked == false; j++) {
 384			tmpcount = RREG8(MGAREG_VCOUNT);
 385			if (tmpcount < vcount)
 386				vcount = 0;
 387			if ((tmpcount - vcount) > 2)
 388				pll_locked = true;
 389			else
 390				udelay(5);
 391		}
 392	}
 393	WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
 394	tmp = RREG8(DAC_DATA);
 395	tmp &= ~MGA1064_REMHEADCTL_CLKDIS;
 396	WREG_DAC(MGA1064_REMHEADCTL, tmp);
 397	return 0;
 398}
 399
 400static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
 401{
 402	unsigned int vcomax, vcomin, pllreffreq;
 403	unsigned int delta, tmpdelta;
 404	unsigned int testp, testm, testn;
 405	unsigned int p, m, n;
 406	unsigned int computed;
 407	u8 tmp;
 408
 409	m = n = p = 0;
 410	vcomax = 550000;
 411	vcomin = 150000;
 412	pllreffreq = 50000;
 413
 414	delta = 0xffffffff;
 415
 416	for (testp = 16; testp > 0; testp--) {
 417		if (clock * testp > vcomax)
 418			continue;
 419		if (clock * testp < vcomin)
 420			continue;
 421
 422		for (testn = 1; testn < 257; testn++) {
 423			for (testm = 1; testm < 17; testm++) {
 424				computed = (pllreffreq * testn) /
 425					(testm * testp);
 426				if (computed > clock)
 427					tmpdelta = computed - clock;
 428				else
 429					tmpdelta = clock - computed;
 430				if (tmpdelta < delta) {
 431					delta = tmpdelta;
 432					n = testn - 1;
 433					m = testm - 1;
 434					p = testp - 1;
 435				}
 436			}
 437		}
 438	}
 439
 440	WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 441	tmp = RREG8(DAC_DATA);
 442	tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
 443	WREG8(DAC_DATA, tmp);
 444
 445	tmp = RREG8(MGAREG_MEM_MISC_READ);
 446	tmp |= 0x3 << 2;
 447	WREG8(MGAREG_MEM_MISC_WRITE, tmp);
 448
 449	WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
 450	tmp = RREG8(DAC_DATA);
 451	WREG8(DAC_DATA, tmp & ~0x40);
 452
 453	WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 454	tmp = RREG8(DAC_DATA);
 455	tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
 456	WREG8(DAC_DATA, tmp);
 457
 458	WREG_DAC(MGA1064_EV_PIX_PLLC_M, m);
 459	WREG_DAC(MGA1064_EV_PIX_PLLC_N, n);
 460	WREG_DAC(MGA1064_EV_PIX_PLLC_P, p);
 461
 462	udelay(50);
 463
 464	WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 465	tmp = RREG8(DAC_DATA);
 466	tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
 467	WREG8(DAC_DATA, tmp);
 468
 469	udelay(500);
 470
 471	WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 472	tmp = RREG8(DAC_DATA);
 473	tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
 474	tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
 475	WREG8(DAC_DATA, tmp);
 476
 477	WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
 478	tmp = RREG8(DAC_DATA);
 479	WREG8(DAC_DATA, tmp | 0x40);
 480
 481	tmp = RREG8(MGAREG_MEM_MISC_READ);
 482	tmp |= (0x3 << 2);
 483	WREG8(MGAREG_MEM_MISC_WRITE, tmp);
 484
 485	WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 486	tmp = RREG8(DAC_DATA);
 487	tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
 488	WREG8(DAC_DATA, tmp);
 489
 490	return 0;
 491}
 
 
 
 
 492
 493static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
 494{
 495	unsigned int vcomax, vcomin, pllreffreq;
 496	unsigned int delta, tmpdelta;
 497	unsigned int testp, testm, testn;
 498	unsigned int p, m, n;
 499	unsigned int computed;
 500	int i, j, tmpcount, vcount;
 501	u8 tmp;
 502	bool pll_locked = false;
 503
 504	m = n = p = 0;
 505
 506	if (mdev->type == G200_EH3) {
 507		vcomax = 3000000;
 508		vcomin = 1500000;
 509		pllreffreq = 25000;
 510
 511		delta = 0xffffffff;
 512
 513		testp = 0;
 514
 515		for (testm = 150; testm >= 6; testm--) {
 516			if (clock * testm > vcomax)
 517				continue;
 518			if (clock * testm < vcomin)
 519				continue;
 520			for (testn = 120; testn >= 60; testn--) {
 521				computed = (pllreffreq * testn) / testm;
 522				if (computed > clock)
 523					tmpdelta = computed - clock;
 524				else
 525					tmpdelta = clock - computed;
 526				if (tmpdelta < delta) {
 527					delta = tmpdelta;
 528					n = testn;
 529					m = testm;
 530					p = testp;
 531				}
 532				if (delta == 0)
 533					break;
 534			}
 535			if (delta == 0)
 536				break;
 537		}
 538	} else {
 539
 540		vcomax = 800000;
 541		vcomin = 400000;
 542		pllreffreq = 33333;
 543
 544		delta = 0xffffffff;
 545
 546		for (testp = 16; testp > 0; testp >>= 1) {
 547			if (clock * testp > vcomax)
 548				continue;
 549			if (clock * testp < vcomin)
 550				continue;
 551
 552			for (testm = 1; testm < 33; testm++) {
 553				for (testn = 17; testn < 257; testn++) {
 554					computed = (pllreffreq * testn) /
 555						(testm * testp);
 556					if (computed > clock)
 557						tmpdelta = computed - clock;
 558					else
 559						tmpdelta = clock - computed;
 560					if (tmpdelta < delta) {
 561						delta = tmpdelta;
 562						n = testn - 1;
 563						m = (testm - 1);
 564						p = testp - 1;
 565					}
 566					if ((clock * testp) >= 600000)
 567						p |= 0x80;
 568				}
 569			}
 570		}
 571	}
 572	for (i = 0; i <= 32 && pll_locked == false; i++) {
 573		WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 574		tmp = RREG8(DAC_DATA);
 575		tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
 576		WREG8(DAC_DATA, tmp);
 577
 578		tmp = RREG8(MGAREG_MEM_MISC_READ);
 579		tmp |= 0x3 << 2;
 580		WREG8(MGAREG_MEM_MISC_WRITE, tmp);
 581
 582		WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 583		tmp = RREG8(DAC_DATA);
 584		tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
 585		WREG8(DAC_DATA, tmp);
 586
 587		udelay(500);
 588
 589		WREG_DAC(MGA1064_EH_PIX_PLLC_M, m);
 590		WREG_DAC(MGA1064_EH_PIX_PLLC_N, n);
 591		WREG_DAC(MGA1064_EH_PIX_PLLC_P, p);
 592
 593		udelay(500);
 594
 595		WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 596		tmp = RREG8(DAC_DATA);
 597		tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
 598		tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
 599		WREG8(DAC_DATA, tmp);
 600
 601		WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 602		tmp = RREG8(DAC_DATA);
 603		tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
 604		tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
 605		WREG8(DAC_DATA, tmp);
 606
 607		vcount = RREG8(MGAREG_VCOUNT);
 608
 609		for (j = 0; j < 30 && pll_locked == false; j++) {
 610			tmpcount = RREG8(MGAREG_VCOUNT);
 611			if (tmpcount < vcount)
 612				vcount = 0;
 613			if ((tmpcount - vcount) > 2)
 614				pll_locked = true;
 615			else
 616				udelay(5);
 617		}
 618	}
 619
 620	return 0;
 621}
 622
 623static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
 
 624{
 625	unsigned int vcomax, vcomin, pllreffreq;
 626	unsigned int delta, tmpdelta;
 627	int testr, testn, testm, testo;
 628	unsigned int p, m, n;
 629	unsigned int computed, vco;
 630	int tmp;
 631	const unsigned int m_div_val[] = { 1, 2, 4, 8 };
 632
 633	m = n = p = 0;
 634	vcomax = 1488000;
 635	vcomin = 1056000;
 636	pllreffreq = 48000;
 637
 638	delta = 0xffffffff;
 639
 640	for (testr = 0; testr < 4; testr++) {
 641		if (delta == 0)
 642			break;
 643		for (testn = 5; testn < 129; testn++) {
 644			if (delta == 0)
 645				break;
 646			for (testm = 3; testm >= 0; testm--) {
 647				if (delta == 0)
 648					break;
 649				for (testo = 5; testo < 33; testo++) {
 650					vco = pllreffreq * (testn + 1) /
 651						(testr + 1);
 652					if (vco < vcomin)
 653						continue;
 654					if (vco > vcomax)
 655						continue;
 656					computed = vco / (m_div_val[testm] * (testo + 1));
 657					if (computed > clock)
 658						tmpdelta = computed - clock;
 659					else
 660						tmpdelta = clock - computed;
 661					if (tmpdelta < delta) {
 662						delta = tmpdelta;
 663						m = testm | (testo << 3);
 664						n = testn;
 665						p = testr | (testr << 3);
 666					}
 667				}
 668			}
 669		}
 670	}
 671
 672	WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 673	tmp = RREG8(DAC_DATA);
 674	tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
 675	WREG8(DAC_DATA, tmp);
 676
 677	WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
 678	tmp = RREG8(DAC_DATA);
 679	tmp |= MGA1064_REMHEADCTL_CLKDIS;
 680	WREG8(DAC_DATA, tmp);
 681
 682	tmp = RREG8(MGAREG_MEM_MISC_READ);
 683	tmp |= (0x3<<2) | 0xc0;
 684	WREG8(MGAREG_MEM_MISC_WRITE, tmp);
 685
 686	WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 687	tmp = RREG8(DAC_DATA);
 688	tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
 689	tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
 690	WREG8(DAC_DATA, tmp);
 691
 692	udelay(500);
 693
 694	WREG_DAC(MGA1064_ER_PIX_PLLC_N, n);
 695	WREG_DAC(MGA1064_ER_PIX_PLLC_M, m);
 696	WREG_DAC(MGA1064_ER_PIX_PLLC_P, p);
 697
 698	udelay(50);
 699
 700	return 0;
 701}
 702
 703static int mga_crtc_set_plls(struct mga_device *mdev, long clock)
 704{
 705	switch(mdev->type) {
 706	case G200_SE_A:
 707	case G200_SE_B:
 708		return mga_g200se_set_plls(mdev, clock);
 709		break;
 710	case G200_WB:
 711	case G200_EW3:
 712		return mga_g200wb_set_plls(mdev, clock);
 713		break;
 714	case G200_EV:
 715		return mga_g200ev_set_plls(mdev, clock);
 716		break;
 717	case G200_EH:
 718	case G200_EH3:
 719		return mga_g200eh_set_plls(mdev, clock);
 720		break;
 721	case G200_ER:
 722		return mga_g200er_set_plls(mdev, clock);
 723		break;
 724	}
 725	return 0;
 726}
 727
 728static void mga_g200wb_prepare(struct drm_crtc *crtc)
 729{
 730	struct mga_device *mdev = crtc->dev->dev_private;
 731	u8 tmp;
 732	int iter_max;
 733
 734	/* 1- The first step is to warn the BMC of an upcoming mode change.
 735	 * We are putting the misc<0> to output.*/
 736
 737	WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL);
 738	tmp = RREG8(DAC_DATA);
 739	tmp |= 0x10;
 740	WREG_DAC(MGA1064_GEN_IO_CTL, tmp);
 741
 742	/* we are putting a 1 on the misc<0> line */
 743	WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
 744	tmp = RREG8(DAC_DATA);
 745	tmp |= 0x10;
 746	WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
 747
 748	/* 2- Second step to mask and further scan request
 749	 * This will be done by asserting the remfreqmsk bit (XSPAREREG<7>)
 750	 */
 751	WREG8(DAC_INDEX, MGA1064_SPAREREG);
 752	tmp = RREG8(DAC_DATA);
 753	tmp |= 0x80;
 754	WREG_DAC(MGA1064_SPAREREG, tmp);
 755
 756	/* 3a- the third step is to verifu if there is an active scan
 757	 * We are searching for a 0 on remhsyncsts <XSPAREREG<0>)
 758	 */
 759	iter_max = 300;
 760	while (!(tmp & 0x1) && iter_max) {
 761		WREG8(DAC_INDEX, MGA1064_SPAREREG);
 762		tmp = RREG8(DAC_DATA);
 763		udelay(1000);
 764		iter_max--;
 765	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 766
 767	/* 3b- this step occurs only if the remove is actually scanning
 768	 * we are waiting for the end of the frame which is a 1 on
 769	 * remvsyncsts (XSPAREREG<1>)
 770	 */
 771	if (iter_max) {
 772		iter_max = 300;
 773		while ((tmp & 0x2) && iter_max) {
 774			WREG8(DAC_INDEX, MGA1064_SPAREREG);
 775			tmp = RREG8(DAC_DATA);
 776			udelay(1000);
 777			iter_max--;
 778		}
 779	}
 780}
 781
 782static void mga_g200wb_commit(struct drm_crtc *crtc)
 783{
 784	u8 tmp;
 785	struct mga_device *mdev = crtc->dev->dev_private;
 786
 787	/* 1- The first step is to ensure that the vrsten and hrsten are set */
 788	WREG8(MGAREG_CRTCEXT_INDEX, 1);
 789	tmp = RREG8(MGAREG_CRTCEXT_DATA);
 790	WREG8(MGAREG_CRTCEXT_DATA, tmp | 0x88);
 791
 792	/* 2- second step is to assert the rstlvl2 */
 793	WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
 794	tmp = RREG8(DAC_DATA);
 795	tmp |= 0x8;
 796	WREG8(DAC_DATA, tmp);
 797
 798	/* wait 10 us */
 799	udelay(10);
 800
 801	/* 3- deassert rstlvl2 */
 802	tmp &= ~0x08;
 803	WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
 804	WREG8(DAC_DATA, tmp);
 805
 806	/* 4- remove mask of scan request */
 807	WREG8(DAC_INDEX, MGA1064_SPAREREG);
 808	tmp = RREG8(DAC_DATA);
 809	tmp &= ~0x80;
 810	WREG8(DAC_DATA, tmp);
 811
 812	/* 5- put back a 0 on the misc<0> line */
 813	WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
 814	tmp = RREG8(DAC_DATA);
 815	tmp &= ~0x10;
 816	WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
 817}
 818
 819/*
 820   This is how the framebuffer base address is stored in g200 cards:
 821   * Assume @offset is the gpu_addr variable of the framebuffer object
 822   * Then addr is the number of _pixels_ (not bytes) from the start of
 823     VRAM to the first pixel we want to display. (divided by 2 for 32bit
 824     framebuffers)
 825   * addr is stored in the CRTCEXT0, CRTCC and CRTCD registers
 826   addr<20> -> CRTCEXT0<6>
 827   addr<19-16> -> CRTCEXT0<3-0>
 828   addr<15-8> -> CRTCC<7-0>
 829   addr<7-0> -> CRTCD<7-0>
 830   CRTCEXT0 has to be programmed last to trigger an update and make the
 831   new addr variable take effect.
 832 */
 833static void mga_set_start_address(struct drm_crtc *crtc, unsigned offset)
 834{
 835	struct mga_device *mdev = crtc->dev->dev_private;
 836	u32 addr;
 837	int count;
 838	u8 crtcext0;
 839
 840	while (RREG8(0x1fda) & 0x08);
 841	while (!(RREG8(0x1fda) & 0x08));
 842
 843	count = RREG8(MGAREG_VCOUNT) + 2;
 844	while (RREG8(MGAREG_VCOUNT) < count);
 845
 846	WREG8(MGAREG_CRTCEXT_INDEX, 0);
 847	crtcext0 = RREG8(MGAREG_CRTCEXT_DATA);
 848	crtcext0 &= 0xB0;
 849	addr = offset / 8;
 850	/* Can't store addresses any higher than that...
 851	   but we also don't have more than 16MB of memory, so it should be fine. */
 852	WARN_ON(addr > 0x1fffff);
 853	crtcext0 |= (!!(addr & (1<<20)))<<6;
 854	WREG_CRT(0x0d, (u8)(addr & 0xff));
 855	WREG_CRT(0x0c, (u8)(addr >> 8) & 0xff);
 856	WREG_ECRT(0x0, ((u8)(addr >> 16) & 0xf) | crtcext0);
 857}
 858
 859static int mga_crtc_do_set_base(struct drm_crtc *crtc,
 860				struct drm_framebuffer *fb,
 861				int x, int y, int atomic)
 862{
 863	struct drm_gem_vram_object *gbo;
 864	int ret;
 865	s64 gpu_addr;
 866
 867	if (!atomic && fb) {
 868		gbo = drm_gem_vram_of_gem(fb->obj[0]);
 869		drm_gem_vram_unpin(gbo);
 870	}
 871
 872	gbo = drm_gem_vram_of_gem(crtc->primary->fb->obj[0]);
 
 873
 874	ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
 875	if (ret)
 876		return ret;
 877	gpu_addr = drm_gem_vram_offset(gbo);
 878	if (gpu_addr < 0) {
 879		ret = (int)gpu_addr;
 880		goto err_drm_gem_vram_unpin;
 881	}
 882
 883	mga_set_start_address(crtc, (u32)gpu_addr);
 884
 885	return 0;
 886
 887err_drm_gem_vram_unpin:
 888	drm_gem_vram_unpin(gbo);
 889	return ret;
 890}
 891
 892static int mga_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 893				  struct drm_framebuffer *old_fb)
 894{
 895	return mga_crtc_do_set_base(crtc, old_fb, x, y, 0);
 896}
 897
 898static int mga_crtc_mode_set(struct drm_crtc *crtc,
 899				struct drm_display_mode *mode,
 900				struct drm_display_mode *adjusted_mode,
 901				int x, int y, struct drm_framebuffer *old_fb)
 902{
 903	struct drm_device *dev = crtc->dev;
 904	struct mga_device *mdev = dev->dev_private;
 905	const struct drm_framebuffer *fb = crtc->primary->fb;
 906	int hdisplay, hsyncstart, hsyncend, htotal;
 907	int vdisplay, vsyncstart, vsyncend, vtotal;
 908	int pitch;
 909	int option = 0, option2 = 0;
 910	int i;
 911	unsigned char misc = 0;
 912	unsigned char ext_vga[6];
 913	u8 bppshift;
 914
 915	static unsigned char dacvalue[] = {
 916		/* 0x00: */        0,    0,    0,    0,    0,    0, 0x00,    0,
 917		/* 0x08: */        0,    0,    0,    0,    0,    0,    0,    0,
 918		/* 0x10: */        0,    0,    0,    0,    0,    0,    0,    0,
 919		/* 0x18: */     0x00,    0, 0xC9, 0xFF, 0xBF, 0x20, 0x1F, 0x20,
 920		/* 0x20: */     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 921		/* 0x28: */     0x00, 0x00, 0x00, 0x00,    0,    0,    0, 0x40,
 922		/* 0x30: */     0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83,
 923		/* 0x38: */     0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3A,
 924		/* 0x40: */        0,    0,    0,    0,    0,    0,    0,    0,
 925		/* 0x48: */        0,    0,    0,    0,    0,    0,    0,    0
 926	};
 927
 928	bppshift = mdev->bpp_shifts[fb->format->cpp[0] - 1];
 929
 930	switch (mdev->type) {
 931	case G200_SE_A:
 932	case G200_SE_B:
 933		dacvalue[MGA1064_VREF_CTL] = 0x03;
 934		dacvalue[MGA1064_PIX_CLK_CTL] = MGA1064_PIX_CLK_CTL_SEL_PLL;
 935		dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_DAC_EN |
 936					     MGA1064_MISC_CTL_VGA8 |
 937					     MGA1064_MISC_CTL_DAC_RAM_CS;
 938		if (mdev->has_sdram)
 939			option = 0x40049120;
 940		else
 941			option = 0x4004d120;
 942		option2 = 0x00008000;
 943		break;
 944	case G200_WB:
 945	case G200_EW3:
 946		dacvalue[MGA1064_VREF_CTL] = 0x07;
 947		option = 0x41049120;
 948		option2 = 0x0000b000;
 949		break;
 950	case G200_EV:
 951		dacvalue[MGA1064_PIX_CLK_CTL] = MGA1064_PIX_CLK_CTL_SEL_PLL;
 952		dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 |
 953					     MGA1064_MISC_CTL_DAC_RAM_CS;
 954		option = 0x00000120;
 955		option2 = 0x0000b000;
 956		break;
 957	case G200_EH:
 958	case G200_EH3:
 959		dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 |
 960					     MGA1064_MISC_CTL_DAC_RAM_CS;
 961		option = 0x00000120;
 962		option2 = 0x0000b000;
 963		break;
 964	case G200_ER:
 
 965		break;
 966	}
 967
 968	switch (fb->format->cpp[0] * 8) {
 
 
 969	case 8:
 970		dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_8bits;
 971		break;
 972	case 16:
 973		if (fb->format->depth == 15)
 974			dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_15bits;
 975		else
 976			dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_16bits;
 977		break;
 978	case 24:
 979		dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_24bits;
 980		break;
 981	case 32:
 982		dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_32_24bits;
 983		break;
 
 
 
 
 984	}
 985
 986	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
 987		misc |= 0x40;
 988	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 989		misc |= 0x80;
 990
 
 991
 992	for (i = 0; i < sizeof(dacvalue); i++) {
 993		if ((i <= 0x17) ||
 994		    (i == 0x1b) ||
 995		    (i == 0x1c) ||
 996		    ((i >= 0x1f) && (i <= 0x29)) ||
 997		    ((i >= 0x30) && (i <= 0x37)))
 998			continue;
 999		if (IS_G200_SE(mdev) &&
1000		    ((i == 0x2c) || (i == 0x2d) || (i == 0x2e)))
1001			continue;
1002		if ((mdev->type == G200_EV ||
1003		    mdev->type == G200_WB ||
1004		    mdev->type == G200_EH ||
1005		    mdev->type == G200_EW3 ||
1006		    mdev->type == G200_EH3) &&
1007		    (i >= 0x44) && (i <= 0x4e))
1008			continue;
1009
1010		WREG_DAC(i, dacvalue[i]);
1011	}
1012
1013	if (mdev->type == G200_ER)
1014		WREG_DAC(0x90, 0);
 
1015
1016	if (option)
1017		pci_write_config_dword(dev->pdev, PCI_MGA_OPTION, option);
1018	if (option2)
1019		pci_write_config_dword(dev->pdev, PCI_MGA_OPTION2, option2);
1020
1021	WREG_SEQ(2, 0xf);
1022	WREG_SEQ(3, 0);
1023	WREG_SEQ(4, 0xe);
1024
1025	pitch = fb->pitches[0] / fb->format->cpp[0];
1026	if (fb->format->cpp[0] * 8 == 24)
1027		pitch = (pitch * 3) >> (4 - bppshift);
1028	else
1029		pitch = pitch >> (4 - bppshift);
 
1030
1031	hdisplay = mode->hdisplay / 8 - 1;
1032	hsyncstart = mode->hsync_start / 8 - 1;
1033	hsyncend = mode->hsync_end / 8 - 1;
1034	htotal = mode->htotal / 8 - 1;
 
1035
1036	/* Work around hardware quirk */
1037	if ((htotal & 0x07) == 0x06 || (htotal & 0x07) == 0x04)
1038		htotal++;
1039
1040	vdisplay = mode->vdisplay - 1;
1041	vsyncstart = mode->vsync_start - 1;
1042	vsyncend = mode->vsync_end - 1;
1043	vtotal = mode->vtotal - 2;
1044
1045	WREG_GFX(0, 0);
1046	WREG_GFX(1, 0);
1047	WREG_GFX(2, 0);
1048	WREG_GFX(3, 0);
1049	WREG_GFX(4, 0);
1050	WREG_GFX(5, 0x40);
1051	WREG_GFX(6, 0x5);
1052	WREG_GFX(7, 0xf);
1053	WREG_GFX(8, 0xf);
1054
1055	WREG_CRT(0, htotal - 4);
1056	WREG_CRT(1, hdisplay);
1057	WREG_CRT(2, hdisplay);
1058	WREG_CRT(3, (htotal & 0x1F) | 0x80);
1059	WREG_CRT(4, hsyncstart);
1060	WREG_CRT(5, ((htotal & 0x20) << 2) | (hsyncend & 0x1F));
1061	WREG_CRT(6, vtotal & 0xFF);
1062	WREG_CRT(7, ((vtotal & 0x100) >> 8) |
1063		 ((vdisplay & 0x100) >> 7) |
1064		 ((vsyncstart & 0x100) >> 6) |
1065		 ((vdisplay & 0x100) >> 5) |
1066		 ((vdisplay & 0x100) >> 4) | /* linecomp */
1067		 ((vtotal & 0x200) >> 4)|
1068		 ((vdisplay & 0x200) >> 3) |
1069		 ((vsyncstart & 0x200) >> 2));
1070	WREG_CRT(9, ((vdisplay & 0x200) >> 4) |
1071		 ((vdisplay & 0x200) >> 3));
1072	WREG_CRT(10, 0);
1073	WREG_CRT(11, 0);
1074	WREG_CRT(12, 0);
1075	WREG_CRT(13, 0);
1076	WREG_CRT(14, 0);
1077	WREG_CRT(15, 0);
1078	WREG_CRT(16, vsyncstart & 0xFF);
1079	WREG_CRT(17, (vsyncend & 0x0F) | 0x20);
1080	WREG_CRT(18, vdisplay & 0xFF);
1081	WREG_CRT(19, pitch & 0xFF);
1082	WREG_CRT(20, 0);
1083	WREG_CRT(21, vdisplay & 0xFF);
1084	WREG_CRT(22, (vtotal + 1) & 0xFF);
1085	WREG_CRT(23, 0xc3);
1086	WREG_CRT(24, vdisplay & 0xFF);
1087
1088	ext_vga[0] = 0;
1089	ext_vga[5] = 0;
1090
1091	/* TODO interlace */
1092
1093	ext_vga[0] |= (pitch & 0x300) >> 4;
1094	ext_vga[1] = (((htotal - 4) & 0x100) >> 8) |
1095		((hdisplay & 0x100) >> 7) |
1096		((hsyncstart & 0x100) >> 6) |
1097		(htotal & 0x40);
1098	ext_vga[2] = ((vtotal & 0xc00) >> 10) |
1099		((vdisplay & 0x400) >> 8) |
1100		((vdisplay & 0xc00) >> 7) |
1101		((vsyncstart & 0xc00) >> 5) |
1102		((vdisplay & 0x400) >> 3);
1103	if (fb->format->cpp[0] * 8 == 24)
1104		ext_vga[3] = (((1 << bppshift) * 3) - 1) | 0x80;
1105	else
1106		ext_vga[3] = ((1 << bppshift) - 1) | 0x80;
1107	ext_vga[4] = 0;
1108	if (mdev->type == G200_WB || mdev->type == G200_EW3)
1109		ext_vga[1] |= 0x88;
1110
1111	/* Set pixel clocks */
1112	misc = 0x2d;
1113	WREG8(MGA_MISC_OUT, misc);
 
 
 
1114
1115	mga_crtc_set_plls(mdev, mode->clock);
 
 
 
 
1116
1117	for (i = 0; i < 6; i++) {
1118		WREG_ECRT(i, ext_vga[i]);
1119	}
 
1120
1121	if (mdev->type == G200_ER)
1122		WREG_ECRT(0x24, 0x5);
 
1123
1124	if (mdev->type == G200_EW3)
1125		WREG_ECRT(0x34, 0x5);
 
1126
1127	if (mdev->type == G200_EV) {
1128		WREG_ECRT(6, 0);
1129	}
 
 
1130
1131	WREG_ECRT(0, ext_vga[0]);
1132	/* Enable mga pixel clock */
1133	misc = 0x2d;
1134
1135	WREG8(MGA_MISC_OUT, misc);
 
 
 
1136
1137	if (adjusted_mode)
1138		memcpy(&mdev->mode, mode, sizeof(struct drm_display_mode));
 
 
 
 
 
 
 
 
1139
1140	mga_crtc_do_set_base(crtc, old_fb, x, y, 0);
 
1141
1142	/* reset tagfifo */
1143	if (mdev->type == G200_ER) {
1144		u32 mem_ctl = RREG32(MGAREG_MEMCTL);
1145		u8 seq1;
1146
1147		/* screen off */
1148		WREG8(MGAREG_SEQ_INDEX, 0x01);
1149		seq1 = RREG8(MGAREG_SEQ_DATA) | 0x20;
1150		WREG8(MGAREG_SEQ_DATA, seq1);
1151
1152		WREG32(MGAREG_MEMCTL, mem_ctl | 0x00200000);
1153		udelay(1000);
1154		WREG32(MGAREG_MEMCTL, mem_ctl & ~0x00200000);
1155
1156		WREG8(MGAREG_SEQ_DATA, seq1 & ~0x20);
1157	}
1158
 
 
 
 
 
1159
1160	if (IS_G200_SE(mdev)) {
1161		if  (mdev->unique_rev_id >= 0x04) {
1162			WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
1163			WREG8(MGAREG_CRTCEXT_DATA, 0);
1164		} else if (mdev->unique_rev_id >= 0x02) {
1165			u8 hi_pri_lvl;
1166			u32 bpp;
1167			u32 mb;
1168
1169			if (fb->format->cpp[0] * 8 > 16)
1170				bpp = 32;
1171			else if (fb->format->cpp[0] * 8 > 8)
1172				bpp = 16;
1173			else
1174				bpp = 8;
1175
1176			mb = (mode->clock * bpp) / 1000;
1177			if (mb > 3100)
1178				hi_pri_lvl = 0;
1179			else if (mb > 2600)
1180				hi_pri_lvl = 1;
1181			else if (mb > 1900)
1182				hi_pri_lvl = 2;
1183			else if (mb > 1160)
1184				hi_pri_lvl = 3;
1185			else if (mb > 440)
1186				hi_pri_lvl = 4;
1187			else
1188				hi_pri_lvl = 5;
1189
1190			WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
1191			WREG8(MGAREG_CRTCEXT_DATA, hi_pri_lvl);
1192		} else {
1193			WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
1194			if (mdev->unique_rev_id >= 0x01)
1195				WREG8(MGAREG_CRTCEXT_DATA, 0x03);
1196			else
1197				WREG8(MGAREG_CRTCEXT_DATA, 0x04);
1198		}
1199	}
1200	return 0;
1201}
1202
1203#if 0 /* code from mjg to attempt D3 on crtc dpms off - revisit later */
1204static int mga_suspend(struct drm_crtc *crtc)
1205{
1206	struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1207	struct drm_device *dev = crtc->dev;
1208	struct mga_device *mdev = dev->dev_private;
1209	struct pci_dev *pdev = dev->pdev;
1210	int option;
1211
1212	if (mdev->suspended)
1213		return 0;
1214
1215	WREG_SEQ(1, 0x20);
1216	WREG_ECRT(1, 0x30);
1217	/* Disable the pixel clock */
1218	WREG_DAC(0x1a, 0x05);
1219	/* Power down the DAC */
1220	WREG_DAC(0x1e, 0x18);
1221	/* Power down the pixel PLL */
1222	WREG_DAC(0x1a, 0x0d);
1223
1224	/* Disable PLLs and clocks */
1225	pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
1226	option &= ~(0x1F8024);
1227	pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
1228	pci_set_power_state(pdev, PCI_D3hot);
1229	pci_disable_device(pdev);
1230
1231	mdev->suspended = true;
1232
1233	return 0;
 
 
1234}
1235
1236static int mga_resume(struct drm_crtc *crtc)
 
1237{
1238	struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1239	struct drm_device *dev = crtc->dev;
1240	struct mga_device *mdev = dev->dev_private;
1241	struct pci_dev *pdev = dev->pdev;
1242	int option;
1243
1244	if (!mdev->suspended)
1245		return 0;
1246
1247	pci_set_power_state(pdev, PCI_D0);
1248	pci_enable_device(pdev);
1249
1250	/* Disable sysclk */
1251	pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
1252	option &= ~(0x4);
1253	pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
1254
1255	mdev->suspended = false;
1256
1257	return 0;
1258}
1259
1260#endif
1261
1262static void mga_crtc_dpms(struct drm_crtc *crtc, int mode)
1263{
1264	struct drm_device *dev = crtc->dev;
1265	struct mga_device *mdev = dev->dev_private;
1266	u8 seq1 = 0, crtcext1 = 0;
 
 
 
 
 
 
1267
1268	switch (mode) {
1269	case DRM_MODE_DPMS_ON:
1270		seq1 = 0;
1271		crtcext1 = 0;
1272		mga_crtc_load_lut(crtc);
1273		break;
1274	case DRM_MODE_DPMS_STANDBY:
1275		seq1 = 0x20;
1276		crtcext1 = 0x10;
1277		break;
1278	case DRM_MODE_DPMS_SUSPEND:
1279		seq1 = 0x20;
1280		crtcext1 = 0x20;
1281		break;
1282	case DRM_MODE_DPMS_OFF:
1283		seq1 = 0x20;
1284		crtcext1 = 0x30;
1285		break;
1286	}
1287
1288#if 0
1289	if (mode == DRM_MODE_DPMS_OFF) {
1290		mga_suspend(crtc);
1291	}
1292#endif
1293	WREG8(MGAREG_SEQ_INDEX, 0x01);
1294	seq1 |= RREG8(MGAREG_SEQ_DATA) & ~0x20;
1295	mga_wait_vsync(mdev);
1296	mga_wait_busy(mdev);
1297	WREG8(MGAREG_SEQ_DATA, seq1);
1298	msleep(20);
1299	WREG8(MGAREG_CRTCEXT_INDEX, 0x01);
1300	crtcext1 |= RREG8(MGAREG_CRTCEXT_DATA) & ~0x30;
1301	WREG8(MGAREG_CRTCEXT_DATA, crtcext1);
1302
1303#if 0
1304	if (mode == DRM_MODE_DPMS_ON && mdev->suspended == true) {
1305		mga_resume(crtc);
1306		drm_helper_resume_force_mode(dev);
1307	}
1308#endif
1309}
1310
1311/*
1312 * This is called before a mode is programmed. A typical use might be to
1313 * enable DPMS during the programming to avoid seeing intermediate stages,
1314 * but that's not relevant to us
1315 */
1316static void mga_crtc_prepare(struct drm_crtc *crtc)
 
 
1317{
1318	struct drm_device *dev = crtc->dev;
1319	struct mga_device *mdev = dev->dev_private;
1320	u8 tmp;
1321
1322	/*	mga_resume(crtc);*/
 
 
 
 
 
 
 
1323
1324	WREG8(MGAREG_CRTC_INDEX, 0x11);
1325	tmp = RREG8(MGAREG_CRTC_DATA);
1326	WREG_CRT(0x11, tmp | 0x80);
1327
1328	if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) {
1329		WREG_SEQ(0, 1);
1330		msleep(50);
1331		WREG_SEQ(1, 0x20);
1332		msleep(20);
1333	} else {
1334		WREG8(MGAREG_SEQ_INDEX, 0x1);
1335		tmp = RREG8(MGAREG_SEQ_DATA);
1336
1337		/* start sync reset */
1338		WREG_SEQ(0, 1);
1339		WREG_SEQ(1, tmp | 0x20);
1340	}
1341
1342	if (mdev->type == G200_WB || mdev->type == G200_EW3)
1343		mga_g200wb_prepare(crtc);
 
 
 
 
1344
1345	WREG_CRT(17, 0);
1346}
1347
1348/*
1349 * This is called after a mode is programmed. It should reverse anything done
1350 * by the prepare function
1351 */
1352static void mga_crtc_commit(struct drm_crtc *crtc)
1353{
1354	struct drm_device *dev = crtc->dev;
1355	struct mga_device *mdev = dev->dev_private;
1356	const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1357	u8 tmp;
1358
1359	if (mdev->type == G200_WB || mdev->type == G200_EW3)
1360		mga_g200wb_commit(crtc);
1361
1362	if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) {
1363		msleep(50);
1364		WREG_SEQ(1, 0x0);
1365		msleep(20);
1366		WREG_SEQ(0, 0x3);
1367	} else {
1368		WREG8(MGAREG_SEQ_INDEX, 0x1);
1369		tmp = RREG8(MGAREG_SEQ_DATA);
1370
1371		tmp &= ~0x20;
1372		WREG_SEQ(0x1, tmp);
1373		WREG_SEQ(0, 3);
1374	}
1375	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1376}
1377
1378/*
1379 * The core can pass us a set of gamma values to program. We actually only
1380 * use this for 8-bit mode so can't perform smooth fades on deeper modes,
1381 * but it's a requirement that we provide the function
1382 */
1383static int mga_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
1384			      u16 *blue, uint32_t size,
1385			      struct drm_modeset_acquire_ctx *ctx)
1386{
1387	mga_crtc_load_lut(crtc);
1388
1389	return 0;
1390}
1391
1392/* Simple cleanup function */
1393static void mga_crtc_destroy(struct drm_crtc *crtc)
1394{
1395	struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
 
 
 
1396
1397	drm_crtc_cleanup(crtc);
1398	kfree(mga_crtc);
1399}
1400
1401static void mga_crtc_disable(struct drm_crtc *crtc)
1402{
1403	DRM_DEBUG_KMS("\n");
1404	mga_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
1405	if (crtc->primary->fb) {
1406		struct drm_framebuffer *fb = crtc->primary->fb;
1407		struct drm_gem_vram_object *gbo =
1408			drm_gem_vram_of_gem(fb->obj[0]);
1409		drm_gem_vram_unpin(gbo);
1410	}
1411	crtc->primary->fb = NULL;
1412}
1413
1414/* These provide the minimum set of functions required to handle a CRTC */
1415static const struct drm_crtc_funcs mga_crtc_funcs = {
1416	.cursor_set = mga_crtc_cursor_set,
1417	.cursor_move = mga_crtc_cursor_move,
1418	.gamma_set = mga_crtc_gamma_set,
1419	.set_config = drm_crtc_helper_set_config,
1420	.destroy = mga_crtc_destroy,
1421};
1422
1423static const struct drm_crtc_helper_funcs mga_helper_funcs = {
1424	.disable = mga_crtc_disable,
1425	.dpms = mga_crtc_dpms,
1426	.mode_set = mga_crtc_mode_set,
1427	.mode_set_base = mga_crtc_mode_set_base,
1428	.prepare = mga_crtc_prepare,
1429	.commit = mga_crtc_commit,
1430};
1431
1432/* CRTC setup */
1433static void mga_crtc_init(struct mga_device *mdev)
1434{
1435	struct mga_crtc *mga_crtc;
1436
1437	mga_crtc = kzalloc(sizeof(struct mga_crtc) +
1438			      (MGAG200FB_CONN_LIMIT * sizeof(struct drm_connector *)),
1439			      GFP_KERNEL);
 
 
1440
1441	if (mga_crtc == NULL)
1442		return;
1443
1444	drm_crtc_init(mdev->dev, &mga_crtc->base, &mga_crtc_funcs);
 
1445
1446	drm_mode_crtc_set_gamma_size(&mga_crtc->base, MGAG200_LUT_SIZE);
1447	mdev->mode_info.crtc = mga_crtc;
 
 
1448
1449	drm_crtc_helper_add(&mga_crtc->base, &mga_helper_funcs);
1450}
1451
1452/*
1453 * The encoder comes after the CRTC in the output pipeline, but before
1454 * the connector. It's responsible for ensuring that the digital
1455 * stream is appropriately converted into the output format. Setup is
1456 * very simple in this case - all we have to do is inform qemu of the
1457 * colour depth in order to ensure that it displays appropriately
1458 */
1459
1460/*
1461 * These functions are analagous to those in the CRTC code, but are intended
1462 * to handle any encoder-specific limitations
1463 */
1464static void mga_encoder_mode_set(struct drm_encoder *encoder,
1465				struct drm_display_mode *mode,
1466				struct drm_display_mode *adjusted_mode)
1467{
 
1468
 
1469}
1470
1471static void mga_encoder_dpms(struct drm_encoder *encoder, int state)
1472{
1473	return;
1474}
1475
1476static void mga_encoder_prepare(struct drm_encoder *encoder)
1477{
1478}
1479
1480static void mga_encoder_commit(struct drm_encoder *encoder)
1481{
 
 
 
1482}
1483
1484static void mga_encoder_destroy(struct drm_encoder *encoder)
1485{
1486	struct mga_encoder *mga_encoder = to_mga_encoder(encoder);
1487	drm_encoder_cleanup(encoder);
1488	kfree(mga_encoder);
1489}
1490
1491static const struct drm_encoder_helper_funcs mga_encoder_helper_funcs = {
1492	.dpms = mga_encoder_dpms,
1493	.mode_set = mga_encoder_mode_set,
1494	.prepare = mga_encoder_prepare,
1495	.commit = mga_encoder_commit,
1496};
1497
1498static const struct drm_encoder_funcs mga_encoder_encoder_funcs = {
1499	.destroy = mga_encoder_destroy,
1500};
1501
1502static struct drm_encoder *mga_encoder_init(struct drm_device *dev)
1503{
1504	struct drm_encoder *encoder;
1505	struct mga_encoder *mga_encoder;
1506
1507	mga_encoder = kzalloc(sizeof(struct mga_encoder), GFP_KERNEL);
1508	if (!mga_encoder)
1509		return NULL;
 
1510
1511	encoder = &mga_encoder->base;
1512	encoder->possible_crtcs = 0x1;
 
 
1513
1514	drm_encoder_init(dev, encoder, &mga_encoder_encoder_funcs,
1515			 DRM_MODE_ENCODER_DAC, NULL);
1516	drm_encoder_helper_add(encoder, &mga_encoder_helper_funcs);
1517
1518	return encoder;
 
 
 
 
 
1519}
1520
 
 
 
1521
1522static int mga_vga_get_modes(struct drm_connector *connector)
1523{
1524	struct mga_connector *mga_connector = to_mga_connector(connector);
1525	struct edid *edid;
1526	int ret = 0;
1527
1528	edid = drm_get_edid(connector, &mga_connector->i2c->adapter);
1529	if (edid) {
1530		drm_connector_update_edid_property(connector, edid);
1531		ret = drm_add_edid_modes(connector, edid);
1532		kfree(edid);
1533	}
1534	return ret;
 
 
1535}
1536
1537static uint32_t mga_vga_calculate_mode_bandwidth(struct drm_display_mode *mode,
1538							int bits_per_pixel)
 
 
 
 
 
1539{
1540	uint32_t total_area, divisor;
1541	uint64_t active_area, pixels_per_second, bandwidth;
1542	uint64_t bytes_per_pixel = (bits_per_pixel + 7) / 8;
1543
1544	divisor = 1024;
1545
1546	if (!mode->htotal || !mode->vtotal || !mode->clock)
1547		return 0;
1548
1549	active_area = mode->hdisplay * mode->vdisplay;
1550	total_area = mode->htotal * mode->vtotal;
1551
1552	pixels_per_second = active_area * mode->clock * 1000;
1553	do_div(pixels_per_second, total_area);
1554
1555	bandwidth = pixels_per_second * bytes_per_pixel * 100;
1556	do_div(bandwidth, divisor);
1557
1558	return (uint32_t)(bandwidth);
1559}
1560
1561#define MODE_BANDWIDTH	MODE_BAD
1562
1563static enum drm_mode_status mga_vga_mode_valid(struct drm_connector *connector,
1564				 struct drm_display_mode *mode)
1565{
1566	struct drm_device *dev = connector->dev;
1567	struct mga_device *mdev = (struct mga_device*)dev->dev_private;
1568	int bpp = 32;
1569
1570	if (IS_G200_SE(mdev)) {
1571		if (mdev->unique_rev_id == 0x01) {
1572			if (mode->hdisplay > 1600)
1573				return MODE_VIRTUAL_X;
1574			if (mode->vdisplay > 1200)
1575				return MODE_VIRTUAL_Y;
1576			if (mga_vga_calculate_mode_bandwidth(mode, bpp)
1577				> (24400 * 1024))
1578				return MODE_BANDWIDTH;
1579		} else if (mdev->unique_rev_id == 0x02) {
1580			if (mode->hdisplay > 1920)
1581				return MODE_VIRTUAL_X;
1582			if (mode->vdisplay > 1200)
1583				return MODE_VIRTUAL_Y;
1584			if (mga_vga_calculate_mode_bandwidth(mode, bpp)
1585				> (30100 * 1024))
1586				return MODE_BANDWIDTH;
1587		} else {
1588			if (mga_vga_calculate_mode_bandwidth(mode, bpp)
1589				> (55000 * 1024))
1590				return MODE_BANDWIDTH;
1591		}
1592	} else if (mdev->type == G200_WB) {
1593		if (mode->hdisplay > 1280)
1594			return MODE_VIRTUAL_X;
1595		if (mode->vdisplay > 1024)
1596			return MODE_VIRTUAL_Y;
1597		if (mga_vga_calculate_mode_bandwidth(mode, bpp) >
1598		    (31877 * 1024))
1599			return MODE_BANDWIDTH;
1600	} else if (mdev->type == G200_EV &&
1601		(mga_vga_calculate_mode_bandwidth(mode, bpp)
1602			> (32700 * 1024))) {
1603		return MODE_BANDWIDTH;
1604	} else if (mdev->type == G200_EH &&
1605		(mga_vga_calculate_mode_bandwidth(mode, bpp)
1606			> (37500 * 1024))) {
1607		return MODE_BANDWIDTH;
1608	} else if (mdev->type == G200_ER &&
1609		(mga_vga_calculate_mode_bandwidth(mode,
1610			bpp) > (55000 * 1024))) {
1611		return MODE_BANDWIDTH;
1612	}
1613
1614	if ((mode->hdisplay % 8) != 0 || (mode->hsync_start % 8) != 0 ||
1615	    (mode->hsync_end % 8) != 0 || (mode->htotal % 8) != 0) {
1616		return MODE_H_ILLEGAL;
1617	}
1618
1619	if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 ||
1620	    mode->crtc_hsync_end > 4096 || mode->crtc_htotal > 4096 ||
1621	    mode->crtc_vdisplay > 2048 || mode->crtc_vsync_start > 4096 ||
1622	    mode->crtc_vsync_end > 4096 || mode->crtc_vtotal > 4096) {
1623		return MODE_BAD;
1624	}
1625
1626	/* Validate the mode input by the user */
1627	if (connector->cmdline_mode.specified) {
1628		if (connector->cmdline_mode.bpp_specified)
1629			bpp = connector->cmdline_mode.bpp;
1630	}
1631
1632	if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->mc.vram_size) {
1633		if (connector->cmdline_mode.specified)
1634			connector->cmdline_mode.specified = false;
1635		return MODE_BAD;
 
 
 
 
 
1636	}
1637
1638	return MODE_OK;
1639}
1640
1641static struct drm_encoder *mga_connector_best_encoder(struct drm_connector
1642						  *connector)
1643{
1644	int enc_id = connector->encoder_ids[0];
1645	/* pick the encoder ids */
1646	if (enc_id)
1647		return drm_encoder_find(connector->dev, NULL, enc_id);
1648	return NULL;
1649}
1650
1651static void mga_connector_destroy(struct drm_connector *connector)
1652{
1653	struct mga_connector *mga_connector = to_mga_connector(connector);
1654	mgag200_i2c_destroy(mga_connector->i2c);
1655	drm_connector_cleanup(connector);
1656	kfree(connector);
1657}
1658
1659static const struct drm_connector_helper_funcs mga_vga_connector_helper_funcs = {
1660	.get_modes = mga_vga_get_modes,
1661	.mode_valid = mga_vga_mode_valid,
1662	.best_encoder = mga_connector_best_encoder,
1663};
1664
1665static const struct drm_connector_funcs mga_vga_connector_funcs = {
1666	.dpms = drm_helper_connector_dpms,
1667	.fill_modes = drm_helper_probe_single_connector_modes,
1668	.destroy = mga_connector_destroy,
1669};
1670
1671static struct drm_connector *mga_vga_init(struct drm_device *dev)
1672{
1673	struct drm_connector *connector;
1674	struct mga_connector *mga_connector;
1675
1676	mga_connector = kzalloc(sizeof(struct mga_connector), GFP_KERNEL);
1677	if (!mga_connector)
1678		return NULL;
1679
1680	connector = &mga_connector->base;
1681	mga_connector->i2c = mgag200_i2c_create(dev);
1682	if (!mga_connector->i2c)
1683		DRM_ERROR("failed to add ddc bus\n");
1684
1685	drm_connector_init_with_ddc(dev, connector,
1686				    &mga_vga_connector_funcs,
1687				    DRM_MODE_CONNECTOR_VGA,
1688				    &mga_connector->i2c->adapter);
1689
1690	drm_connector_helper_add(connector, &mga_vga_connector_helper_funcs);
1691
1692	drm_connector_register(connector);
1693
1694	return connector;
1695}
1696
1697
1698int mgag200_modeset_init(struct mga_device *mdev)
1699{
1700	struct drm_encoder *encoder;
1701	struct drm_connector *connector;
1702
1703	mdev->mode_info.mode_config_initialized = true;
1704
1705	mdev->dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH;
1706	mdev->dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT;
1707
1708	mdev->dev->mode_config.fb_base = mdev->mc.vram_base;
1709
1710	mga_crtc_init(mdev);
1711
1712	encoder = mga_encoder_init(mdev->dev);
1713	if (!encoder) {
1714		DRM_ERROR("mga_encoder_init failed\n");
1715		return -1;
1716	}
1717
1718	connector = mga_vga_init(mdev->dev);
1719	if (!connector) {
1720		DRM_ERROR("mga_vga_init failed\n");
1721		return -1;
1722	}
1723
1724	drm_connector_attach_encoder(connector, encoder);
 
 
 
 
1725
1726	return 0;
1727}
1728
1729void mgag200_modeset_fini(struct mga_device *mdev)
1730{
1731
1732}
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright 2010 Matt Turner.
  4 * Copyright 2012 Red Hat
  5 *
  6 * Authors: Matthew Garrett
  7 *	    Matt Turner
  8 *	    Dave Airlie
  9 */
 10
 11#include <linux/delay.h>
 12#include <linux/iosys-map.h>
 13
 14#include <drm/drm_atomic.h>
 15#include <drm/drm_atomic_helper.h>
 16#include <drm/drm_damage_helper.h>
 17#include <drm/drm_edid.h>
 18#include <drm/drm_format_helper.h>
 19#include <drm/drm_fourcc.h>
 20#include <drm/drm_framebuffer.h>
 21#include <drm/drm_gem_atomic_helper.h>
 22#include <drm/drm_gem_framebuffer_helper.h>
 23#include <drm/drm_panic.h>
 24#include <drm/drm_print.h>
 25
 26#include "mgag200_ddc.h"
 27#include "mgag200_drv.h"
 28
 
 
 29/*
 30 * This file contains setup code for the CRTC.
 31 */
 32
 33void mgag200_crtc_set_gamma_linear(struct mga_device *mdev,
 34				   const struct drm_format_info *format)
 35{
 
 
 
 
 36	int i;
 37
 
 
 
 
 
 
 
 38	WREG8(DAC_INDEX + MGA1064_INDEX, 0);
 39
 40	switch (format->format) {
 41	case DRM_FORMAT_RGB565:
 42		/* Use better interpolation, to take 32 values from 0 to 255 */
 43		for (i = 0; i < MGAG200_LUT_SIZE / 8; i++) {
 44			WREG8(DAC_INDEX + MGA1064_COL_PAL, i * 8 + i / 4);
 45			WREG8(DAC_INDEX + MGA1064_COL_PAL, i * 4 + i / 16);
 46			WREG8(DAC_INDEX + MGA1064_COL_PAL, i * 8 + i / 4);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 47		}
 48		/* Green has one more bit, so add padding with 0 for red and blue. */
 49		for (i = MGAG200_LUT_SIZE / 8; i < MGAG200_LUT_SIZE / 4; i++) {
 50			WREG8(DAC_INDEX + MGA1064_COL_PAL, 0);
 51			WREG8(DAC_INDEX + MGA1064_COL_PAL, i * 4 + i / 16);
 52			WREG8(DAC_INDEX + MGA1064_COL_PAL, 0);
 53		}
 54		break;
 55	case DRM_FORMAT_RGB888:
 56	case DRM_FORMAT_XRGB8888:
 57		for (i = 0; i < MGAG200_LUT_SIZE; i++) {
 58			WREG8(DAC_INDEX + MGA1064_COL_PAL, i);
 59			WREG8(DAC_INDEX + MGA1064_COL_PAL, i);
 60			WREG8(DAC_INDEX + MGA1064_COL_PAL, i);
 61		}
 62		break;
 63	default:
 64		drm_warn_once(&mdev->base, "Unsupported format %p4cc for gamma correction\n",
 65			      &format->format);
 66		break;
 67	}
 68}
 69
 70void mgag200_crtc_set_gamma(struct mga_device *mdev,
 71			    const struct drm_format_info *format,
 72			    struct drm_color_lut *lut)
 73{
 74	int i;
 75
 76	WREG8(DAC_INDEX + MGA1064_INDEX, 0);
 77
 78	switch (format->format) {
 79	case DRM_FORMAT_RGB565:
 80		/* Use better interpolation, to take 32 values from lut[0] to lut[255] */
 81		for (i = 0; i < MGAG200_LUT_SIZE / 8; i++) {
 82			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i * 8 + i / 4].red >> 8);
 83			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i * 4 + i / 16].green >> 8);
 84			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i * 8 + i / 4].blue >> 8);
 85		}
 86		/* Green has one more bit, so add padding with 0 for red and blue. */
 87		for (i = MGAG200_LUT_SIZE / 8; i < MGAG200_LUT_SIZE / 4; i++) {
 88			WREG8(DAC_INDEX + MGA1064_COL_PAL, 0);
 89			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i * 4 + i / 16].green >> 8);
 90			WREG8(DAC_INDEX + MGA1064_COL_PAL, 0);
 91		}
 92		break;
 93	case DRM_FORMAT_RGB888:
 94	case DRM_FORMAT_XRGB8888:
 95		for (i = 0; i < MGAG200_LUT_SIZE; i++) {
 96			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i].red >> 8);
 97			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i].green >> 8);
 98			WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i].blue >> 8);
 99		}
100		break;
101	default:
102		drm_warn_once(&mdev->base, "Unsupported format %p4cc for gamma correction\n",
103			      &format->format);
104		break;
105	}
106}
107
108static inline void mga_wait_vsync(struct mga_device *mdev)
109{
110	unsigned long timeout = jiffies + HZ/10;
111	unsigned int status = 0;
112
113	do {
114		status = RREG32(MGAREG_STATUS);
115	} while ((status & 0x08) && time_before(jiffies, timeout));
116	timeout = jiffies + HZ/10;
117	status = 0;
118	do {
119		status = RREG32(MGAREG_STATUS);
120	} while (!(status & 0x08) && time_before(jiffies, timeout));
121}
122
123static inline void mga_wait_busy(struct mga_device *mdev)
124{
125	unsigned long timeout = jiffies + HZ;
126	unsigned int status = 0;
127	do {
128		status = RREG8(MGAREG_STATUS + 2);
129	} while ((status & 0x01) && time_before(jiffies, timeout));
130}
131
132/*
133 * This is how the framebuffer base address is stored in g200 cards:
134 *   * Assume @offset is the gpu_addr variable of the framebuffer object
135 *   * Then addr is the number of _pixels_ (not bytes) from the start of
136 *     VRAM to the first pixel we want to display. (divided by 2 for 32bit
137 *     framebuffers)
138 *   * addr is stored in the CRTCEXT0, CRTCC and CRTCD registers
139 *      addr<20> -> CRTCEXT0<6>
140 *      addr<19-16> -> CRTCEXT0<3-0>
141 *      addr<15-8> -> CRTCC<7-0>
142 *      addr<7-0> -> CRTCD<7-0>
143 *
144 *  CRTCEXT0 has to be programmed last to trigger an update and make the
145 *  new addr variable take effect.
146 */
147static void mgag200_set_startadd(struct mga_device *mdev,
148				 unsigned long offset)
149{
150	struct drm_device *dev = &mdev->base;
151	u32 startadd;
152	u8 crtcc, crtcd, crtcext0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
154	startadd = offset / 8;
 
155
156	if (startadd > 0)
157		drm_WARN_ON_ONCE(dev, mdev->info->bug_no_startadd);
158
159	/*
160	 * Can't store addresses any higher than that, but we also
161	 * don't have more than 16 MiB of memory, so it should be fine.
162	 */
163	drm_WARN_ON(dev, startadd > 0x1fffff);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
165	RREG_ECRT(0x00, crtcext0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
167	crtcc = (startadd >> 8) & 0xff;
168	crtcd = startadd & 0xff;
169	crtcext0 &= 0xb0;
170	crtcext0 |= ((startadd >> 14) & BIT(6)) |
171		    ((startadd >> 16) & 0x0f);
 
 
172
173	WREG_CRT(0x0c, crtcc);
174	WREG_CRT(0x0d, crtcd);
175	WREG_ECRT(0x00, crtcext0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176}
177
178void mgag200_init_registers(struct mga_device *mdev)
179{
180	u8 crtc11, misc;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
182	WREG_SEQ(2, 0x0f);
183	WREG_SEQ(3, 0x00);
184	WREG_SEQ(4, 0x0e);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
186	WREG_CRT(10, 0);
187	WREG_CRT(11, 0);
188	WREG_CRT(12, 0);
189	WREG_CRT(13, 0);
190	WREG_CRT(14, 0);
191	WREG_CRT(15, 0);
192
193	RREG_CRT(0x11, crtc11);
194	crtc11 &= ~(MGAREG_CRTC11_CRTCPROTECT |
195		    MGAREG_CRTC11_VINTEN |
196		    MGAREG_CRTC11_VINTCLR);
197	WREG_CRT(0x11, crtc11);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
199	misc = RREG8(MGA_MISC_IN);
200	misc |= MGAREG_MISC_IOADSEL;
201	WREG8(MGA_MISC_OUT, misc);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202}
203
204void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mode *mode,
205			   bool set_vidrst)
206{
207	unsigned int hdispend, hsyncstr, hsyncend, htotal, hblkstr, hblkend;
208	unsigned int vdispend, vsyncstr, vsyncend, vtotal, vblkstr, vblkend;
209	unsigned int linecomp;
210	u8 misc, crtcext1, crtcext2, crtcext5;
211
212	hdispend = mode->crtc_hdisplay / 8 - 1;
213	hsyncstr = mode->crtc_hsync_start / 8 - 1;
214	hsyncend = mode->crtc_hsync_end / 8 - 1;
215	htotal = mode->crtc_htotal / 8 - 1;
216	/* Work around hardware quirk */
217	if ((htotal & 0x07) == 0x06 || (htotal & 0x07) == 0x04)
218		htotal++;
219	hblkstr = mode->crtc_hblank_start / 8 - 1;
220	hblkend = htotal;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
222	vdispend = mode->crtc_vdisplay - 1;
223	vsyncstr = mode->crtc_vsync_start - 1;
224	vsyncend = mode->crtc_vsync_end - 1;
225	vtotal = mode->crtc_vtotal - 2;
226	vblkstr = mode->crtc_vblank_start;
227	vblkend = vtotal + 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
229	linecomp = vdispend;
230
231	misc = RREG8(MGA_MISC_IN);
 
232
233	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
234		misc |= MGAREG_MISC_HSYNCPOL;
235	else
236		misc &= ~MGAREG_MISC_HSYNCPOL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
238	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
239		misc |= MGAREG_MISC_VSYNCPOL;
240	else
241		misc &= ~MGAREG_MISC_VSYNCPOL;
 
 
 
242
243	crtcext1 = (((htotal - 4) & 0x100) >> 8) |
244		   ((hblkstr & 0x100) >> 7) |
245		   ((hsyncstr & 0x100) >> 6) |
246		    (hblkend & 0x40);
247	if (set_vidrst)
248		crtcext1 |= MGAREG_CRTCEXT1_VRSTEN |
249			    MGAREG_CRTCEXT1_HRSTEN;
250
251	crtcext2 = ((vtotal & 0xc00) >> 10) |
252		   ((vdispend & 0x400) >> 8) |
253		   ((vblkstr & 0xc00) >> 7) |
254		   ((vsyncstr & 0xc00) >> 5) |
255		   ((linecomp & 0x400) >> 3);
256	crtcext5 = 0x00;
257
258	WREG_CRT(0x00, htotal - 4);
259	WREG_CRT(0x01, hdispend);
260	WREG_CRT(0x02, hblkstr);
261	WREG_CRT(0x03, (hblkend & 0x1f) | 0x80);
262	WREG_CRT(0x04, hsyncstr);
263	WREG_CRT(0x05, ((hblkend & 0x20) << 2) | (hsyncend & 0x1f));
264	WREG_CRT(0x06, vtotal & 0xff);
265	WREG_CRT(0x07, ((vtotal & 0x100) >> 8) |
266		       ((vdispend & 0x100) >> 7) |
267		       ((vsyncstr & 0x100) >> 6) |
268		       ((vblkstr & 0x100) >> 5) |
269		       ((linecomp & 0x100) >> 4) |
270		       ((vtotal & 0x200) >> 4) |
271		       ((vdispend & 0x200) >> 3) |
272		       ((vsyncstr & 0x200) >> 2));
273	WREG_CRT(0x09, ((vblkstr & 0x200) >> 4) |
274		       ((linecomp & 0x200) >> 3));
275	WREG_CRT(0x10, vsyncstr & 0xff);
276	WREG_CRT(0x11, (vsyncend & 0x0f) | 0x20);
277	WREG_CRT(0x12, vdispend & 0xff);
278	WREG_CRT(0x14, 0);
279	WREG_CRT(0x15, vblkstr & 0xff);
280	WREG_CRT(0x16, vblkend & 0xff);
281	WREG_CRT(0x17, 0xc3);
282	WREG_CRT(0x18, linecomp & 0xff);
283
284	WREG_ECRT(0x01, crtcext1);
285	WREG_ECRT(0x02, crtcext2);
286	WREG_ECRT(0x05, crtcext5);
287
288	WREG8(MGA_MISC_OUT, misc);
 
 
 
 
 
 
 
 
 
 
 
 
289}
290
291static u8 mgag200_get_bpp_shift(const struct drm_format_info *format)
292{
293	static const u8 bpp_shift[] = {0, 1, 0, 2};
 
294
295	return bpp_shift[format->cpp[0] - 1];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296}
297
298/*
299 * Calculates the HW offset value from the framebuffer's pitch. The
300 * offset is a multiple of the pixel size and depends on the display
301 * format.
 
 
 
 
 
 
 
 
 
302 */
303static u32 mgag200_calculate_offset(struct mga_device *mdev,
304				    const struct drm_framebuffer *fb)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305{
306	u32 offset = fb->pitches[0] / fb->format->cpp[0];
307	u8 bppshift = mgag200_get_bpp_shift(fb->format);
 
308
309	if (fb->format->cpp[0] * 8 == 24)
310		offset = (offset * 3) >> (4 - bppshift);
311	else
312		offset = offset >> (4 - bppshift);
313
314	return offset;
315}
316
317static void mgag200_set_offset(struct mga_device *mdev,
318			       const struct drm_framebuffer *fb)
319{
320	u8 crtc13, crtcext0;
321	u32 offset = mgag200_calculate_offset(mdev, fb);
 
 
 
322
323	RREG_ECRT(0, crtcext0);
324
325	crtc13 = offset & 0xff;
326
327	crtcext0 &= ~MGAREG_CRTCEXT0_OFFSET_MASK;
328	crtcext0 |= (offset >> 4) & MGAREG_CRTCEXT0_OFFSET_MASK;
 
 
329
330	WREG_CRT(0x13, crtc13);
331	WREG_ECRT(0x00, crtcext0);
 
 
332}
333
334void mgag200_set_format_regs(struct mga_device *mdev, const struct drm_format_info *format)
 
 
 
335{
336	struct drm_device *dev = &mdev->base;
337	unsigned int bpp, bppshift, scale;
338	u8 crtcext3, xmulctrl;
339
340	bpp = format->cpp[0] * 8;
341
342	bppshift = mgag200_get_bpp_shift(format);
343	switch (bpp) {
344	case 24:
345		scale = ((1 << bppshift) * 3) - 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346		break;
347	default:
348		scale = (1 << bppshift) - 1;
349		break;
350	}
351
352	RREG_ECRT(3, crtcext3);
353
354	switch (bpp) {
355	case 8:
356		xmulctrl = MGA1064_MUL_CTL_8bits;
357		break;
358	case 16:
359		if (format->depth == 15)
360			xmulctrl = MGA1064_MUL_CTL_15bits;
361		else
362			xmulctrl = MGA1064_MUL_CTL_16bits;
363		break;
364	case 24:
365		xmulctrl = MGA1064_MUL_CTL_24bits;
366		break;
367	case 32:
368		xmulctrl = MGA1064_MUL_CTL_32_24bits;
369		break;
370	default:
371		/* BUG: We should have caught this problem already. */
372		drm_WARN_ON(dev, "invalid format depth\n");
373		return;
374	}
375
376	crtcext3 &= ~GENMASK(2, 0);
377	crtcext3 |= scale;
 
 
378
379	WREG_DAC(MGA1064_MUL_CTL, xmulctrl);
380
381	WREG_GFX(0, 0x00);
382	WREG_GFX(1, 0x00);
383	WREG_GFX(2, 0x00);
384	WREG_GFX(3, 0x00);
385	WREG_GFX(4, 0x00);
386	WREG_GFX(5, 0x40);
387	/* GCTL6 should be 0x05, but we configure memmapsl to 0xb8000 (text mode),
388	 * so that it doesn't hang when running kexec/kdump on G200_SE rev42.
389	 */
390	WREG_GFX(6, 0x0d);
391	WREG_GFX(7, 0x0f);
392	WREG_GFX(8, 0x0f);
 
 
 
 
 
393
394	WREG_ECRT(3, crtcext3);
395}
396
397void mgag200_enable_display(struct mga_device *mdev)
398{
399	u8 seq0, crtcext1;
400
401	RREG_SEQ(0x00, seq0);
402	seq0 |= MGAREG_SEQ0_SYNCRST |
403		MGAREG_SEQ0_ASYNCRST;
404	WREG_SEQ(0x00, seq0);
 
 
 
 
405
406	/*
407	 * TODO: replace busy waiting with vblank IRQ; put
408	 *       msleep(50) before changing SCROFF
409	 */
410	mga_wait_vsync(mdev);
411	mga_wait_busy(mdev);
412
413	RREG_ECRT(0x01, crtcext1);
414	crtcext1 &= ~MGAREG_CRTCEXT1_VSYNCOFF;
415	crtcext1 &= ~MGAREG_CRTCEXT1_HSYNCOFF;
416	WREG_ECRT(0x01, crtcext1);
417}
418
419static void mgag200_disable_display(struct mga_device *mdev)
420{
421	u8 seq0, crtcext1;
422
423	RREG_SEQ(0x00, seq0);
424	seq0 &= ~MGAREG_SEQ0_SYNCRST;
425	WREG_SEQ(0x00, seq0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
426
427	/*
428	 * TODO: replace busy waiting with vblank IRQ; put
429	 *       msleep(50) before changing SCROFF
430	 */
431	mga_wait_vsync(mdev);
432	mga_wait_busy(mdev);
433
434	RREG_ECRT(0x01, crtcext1);
435	crtcext1 |= MGAREG_CRTCEXT1_VSYNCOFF |
436		    MGAREG_CRTCEXT1_HSYNCOFF;
437	WREG_ECRT(0x01, crtcext1);
438}
439
440static void mgag200_handle_damage(struct mga_device *mdev, const struct iosys_map *vmap,
441				  struct drm_framebuffer *fb, struct drm_rect *clip)
442{
443	struct iosys_map dst = IOSYS_MAP_INIT_VADDR_IOMEM(mdev->vram);
444
445	iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, clip));
446	drm_fb_memcpy(&dst, fb->pitches, vmap, fb, clip);
447}
448
449/*
450 * Primary plane
451 */
452
453const uint32_t mgag200_primary_plane_formats[] = {
454	DRM_FORMAT_XRGB8888,
455	DRM_FORMAT_RGB565,
456	DRM_FORMAT_RGB888,
457};
458
459const size_t mgag200_primary_plane_formats_size = ARRAY_SIZE(mgag200_primary_plane_formats);
 
 
460
461const uint64_t mgag200_primary_plane_fmtmods[] = {
462	DRM_FORMAT_MOD_LINEAR,
463	DRM_FORMAT_MOD_INVALID
464};
465
466int mgag200_primary_plane_helper_atomic_check(struct drm_plane *plane,
467					      struct drm_atomic_state *new_state)
468{
469	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(new_state, plane);
470	struct drm_framebuffer *new_fb = new_plane_state->fb;
471	struct drm_framebuffer *fb = NULL;
472	struct drm_crtc *new_crtc = new_plane_state->crtc;
473	struct drm_crtc_state *new_crtc_state = NULL;
474	struct mgag200_crtc_state *new_mgag200_crtc_state;
475	int ret;
476
477	if (new_crtc)
478		new_crtc_state = drm_atomic_get_new_crtc_state(new_state, new_crtc);
479
480	ret = drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state,
481						  DRM_PLANE_NO_SCALING,
482						  DRM_PLANE_NO_SCALING,
483						  false, true);
484	if (ret)
485		return ret;
486	else if (!new_plane_state->visible)
487		return 0;
 
 
 
 
 
488
489	if (plane->state)
490		fb = plane->state->fb;
491
492	if (!fb || (fb->format != new_fb->format))
493		new_crtc_state->mode_changed = true; /* update PLL settings */
494
495	new_mgag200_crtc_state = to_mgag200_crtc_state(new_crtc_state);
496	new_mgag200_crtc_state->format = new_fb->format;
497
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
498	return 0;
499}
500
501void mgag200_primary_plane_helper_atomic_update(struct drm_plane *plane,
502						struct drm_atomic_state *old_state)
503{
504	struct drm_device *dev = plane->dev;
505	struct mga_device *mdev = to_mga_device(dev);
506	struct drm_plane_state *plane_state = plane->state;
507	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(old_state, plane);
508	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
509	struct drm_framebuffer *fb = plane_state->fb;
510	struct drm_atomic_helper_damage_iter iter;
511	struct drm_rect damage;
512
513	drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
514	drm_atomic_for_each_plane_damage(&iter, &damage) {
515		mgag200_handle_damage(mdev, shadow_plane_state->data, fb, &damage);
516	}
 
 
 
 
 
 
 
 
 
 
 
 
 
517
518	/* Always scanout image at VRAM offset 0 */
519	mgag200_set_startadd(mdev, (u32)0);
520	mgag200_set_offset(mdev, fb);
521}
522
523void mgag200_primary_plane_helper_atomic_enable(struct drm_plane *plane,
524						struct drm_atomic_state *state)
525{
526	struct drm_device *dev = plane->dev;
527	struct mga_device *mdev = to_mga_device(dev);
528	u8 seq1;
 
 
529
530	RREG_SEQ(0x01, seq1);
531	seq1 &= ~MGAREG_SEQ1_SCROFF;
532	WREG_SEQ(0x01, seq1);
533	msleep(20);
 
 
 
 
 
 
 
 
 
 
534}
535
536void mgag200_primary_plane_helper_atomic_disable(struct drm_plane *plane,
537						 struct drm_atomic_state *old_state)
 
538{
539	struct drm_device *dev = plane->dev;
540	struct mga_device *mdev = to_mga_device(dev);
541	u8 seq1;
542
543	RREG_SEQ(0x01, seq1);
544	seq1 |= MGAREG_SEQ1_SCROFF;
545	WREG_SEQ(0x01, seq1);
546	msleep(20);
547}
548
549int mgag200_primary_plane_helper_get_scanout_buffer(struct drm_plane *plane,
550						    struct drm_scanout_buffer *sb)
551{
552	struct mga_device *mdev = to_mga_device(plane->dev);
553	struct iosys_map map = IOSYS_MAP_INIT_VADDR_IOMEM(mdev->vram);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
554
555	if (plane->state && plane->state->fb) {
556		sb->format = plane->state->fb->format;
557		sb->width = plane->state->fb->width;
558		sb->height = plane->state->fb->height;
559		sb->pitch[0] = plane->state->fb->pitches[0];
560		sb->map[0] = map;
561		return 0;
 
 
 
 
 
 
 
 
 
 
 
 
562	}
563	return -ENODEV;
564}
565
566/*
567 * CRTC
 
 
568 */
569
570enum drm_mode_status mgag200_crtc_helper_mode_valid(struct drm_crtc *crtc,
571						    const struct drm_display_mode *mode)
572{
573	struct mga_device *mdev = to_mga_device(crtc->dev);
574	const struct mgag200_device_info *info = mdev->info;
 
575
576	/*
577	 * Some devices have additional limits on the size of the
578	 * display mode.
579	 */
580	if (mode->hdisplay > info->max_hdisplay)
581		return MODE_VIRTUAL_X;
582	if (mode->vdisplay > info->max_vdisplay)
583		return MODE_VIRTUAL_Y;
584
585	if ((mode->hdisplay % 8) != 0 || (mode->hsync_start % 8) != 0 ||
586	    (mode->hsync_end % 8) != 0 || (mode->htotal % 8) != 0) {
587		return MODE_H_ILLEGAL;
 
 
 
 
 
 
 
 
 
 
 
 
 
588	}
589
590	if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 ||
591	    mode->crtc_hsync_end > 4096 || mode->crtc_htotal > 4096 ||
592	    mode->crtc_vdisplay > 2048 || mode->crtc_vsync_start > 4096 ||
593	    mode->crtc_vsync_end > 4096 || mode->crtc_vtotal > 4096) {
594		return MODE_BAD;
595	}
596
597	return MODE_OK;
598}
599
600int mgag200_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *new_state)
 
 
 
 
601{
602	struct drm_device *dev = crtc->dev;
603	struct mga_device *mdev = to_mga_device(dev);
604	const struct mgag200_device_funcs *funcs = mdev->funcs;
605	struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(new_state, crtc);
606	struct drm_property_blob *new_gamma_lut = new_crtc_state->gamma_lut;
607	int ret;
608
609	if (!new_crtc_state->enable)
610		return 0;
611
612	ret = drm_atomic_helper_check_crtc_primary_plane(new_crtc_state);
613	if (ret)
614		return ret;
615
616	if (new_crtc_state->mode_changed) {
617		if (funcs->pixpllc_atomic_check) {
618			ret = funcs->pixpllc_atomic_check(crtc, new_state);
619			if (ret)
620				return ret;
621		}
622	}
 
 
623
624	if (new_crtc_state->color_mgmt_changed && new_gamma_lut) {
625		if (new_gamma_lut->length != MGAG200_LUT_SIZE * sizeof(struct drm_color_lut)) {
626			drm_dbg(dev, "Wrong size for gamma_lut %zu\n", new_gamma_lut->length);
627			return -EINVAL;
628		}
629	}
 
 
 
 
630
631	return 0;
632}
633
634void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *old_state)
 
635{
636	struct drm_crtc_state *crtc_state = crtc->state;
637	struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state);
638	struct drm_device *dev = crtc->dev;
639	struct mga_device *mdev = to_mga_device(dev);
640
641	if (crtc_state->enable && crtc_state->color_mgmt_changed) {
642		const struct drm_format_info *format = mgag200_crtc_state->format;
 
643
644		if (crtc_state->gamma_lut)
645			mgag200_crtc_set_gamma(mdev, format, crtc_state->gamma_lut->data);
646		else
647			mgag200_crtc_set_gamma_linear(mdev, format);
 
 
 
 
 
648	}
 
649}
650
651void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
652{
653	struct drm_device *dev = crtc->dev;
654	struct mga_device *mdev = to_mga_device(dev);
655	const struct mgag200_device_funcs *funcs = mdev->funcs;
656	struct drm_crtc_state *crtc_state = crtc->state;
657	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
658	struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state);
659	const struct drm_format_info *format = mgag200_crtc_state->format;
660
661	mgag200_set_format_regs(mdev, format);
662	mgag200_set_mode_regs(mdev, adjusted_mode, mgag200_crtc_state->set_vidrst);
663
664	if (funcs->pixpllc_atomic_update)
665		funcs->pixpllc_atomic_update(crtc, old_state);
666
667	if (crtc_state->gamma_lut)
668		mgag200_crtc_set_gamma(mdev, format, crtc_state->gamma_lut->data);
669	else
670		mgag200_crtc_set_gamma_linear(mdev, format);
671
672	mgag200_enable_display(mdev);
673}
674
675void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
676{
677	struct mga_device *mdev = to_mga_device(crtc->dev);
678
679	mgag200_disable_display(mdev);
680}
681
682void mgag200_crtc_reset(struct drm_crtc *crtc)
683{
684	struct mgag200_crtc_state *mgag200_crtc_state;
 
685
686	if (crtc->state)
687		crtc->funcs->atomic_destroy_state(crtc, crtc->state);
 
688
689	mgag200_crtc_state = kzalloc(sizeof(*mgag200_crtc_state), GFP_KERNEL);
690	if (mgag200_crtc_state)
691		__drm_atomic_helper_crtc_reset(crtc, &mgag200_crtc_state->base);
692	else
693		__drm_atomic_helper_crtc_reset(crtc, NULL);
694}
695
696struct drm_crtc_state *mgag200_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
697{
698	struct drm_crtc_state *crtc_state = crtc->state;
699	struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state);
700	struct mgag200_crtc_state *new_mgag200_crtc_state;
 
701
702	if (!crtc_state)
703		return NULL;
 
 
 
 
 
 
 
 
 
 
 
 
 
704
705	new_mgag200_crtc_state = kzalloc(sizeof(*new_mgag200_crtc_state), GFP_KERNEL);
706	if (!new_mgag200_crtc_state)
707		return NULL;
708	__drm_atomic_helper_crtc_duplicate_state(crtc, &new_mgag200_crtc_state->base);
709
710	new_mgag200_crtc_state->format = mgag200_crtc_state->format;
711	memcpy(&new_mgag200_crtc_state->pixpllc, &mgag200_crtc_state->pixpllc,
712	       sizeof(new_mgag200_crtc_state->pixpllc));
713	new_mgag200_crtc_state->set_vidrst = mgag200_crtc_state->set_vidrst;
714
715	return &new_mgag200_crtc_state->base;
716}
 
717
718void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state)
719{
720	struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state);
721
722	__drm_atomic_helper_crtc_destroy_state(&mgag200_crtc_state->base);
723	kfree(mgag200_crtc_state);
724}
725
726/*
727 * Mode config
728 */
729
730static void mgag200_mode_config_helper_atomic_commit_tail(struct drm_atomic_state *state)
731{
732	struct mga_device *mdev = to_mga_device(state->dev);
 
 
733
734	/*
735	 * Concurrent operations could possibly trigger a call to
736	 * drm_connector_helper_funcs.get_modes by trying to read the
737	 * display modes. Protect access to I/O registers by acquiring
738	 * the I/O-register lock.
739	 */
740	mutex_lock(&mdev->rmmio_lock);
741	drm_atomic_helper_commit_tail(state);
742	mutex_unlock(&mdev->rmmio_lock);
743}
744
745static const struct drm_mode_config_helper_funcs mgag200_mode_config_helper_funcs = {
746	.atomic_commit_tail = mgag200_mode_config_helper_atomic_commit_tail,
747};
748
749/* Calculates a mode's required memory bandwidth (in KiB/sec). */
750static uint32_t mgag200_calculate_mode_bandwidth(const struct drm_display_mode *mode,
751						 unsigned int bits_per_pixel)
752{
753	uint32_t total_area, divisor;
754	uint64_t active_area, pixels_per_second, bandwidth;
755	uint64_t bytes_per_pixel = (bits_per_pixel + 7) / 8;
756
757	divisor = 1024;
758
759	if (!mode->htotal || !mode->vtotal || !mode->clock)
760		return 0;
761
762	active_area = mode->hdisplay * mode->vdisplay;
763	total_area = mode->htotal * mode->vtotal;
764
765	pixels_per_second = active_area * mode->clock * 1000;
766	do_div(pixels_per_second, total_area);
767
768	bandwidth = pixels_per_second * bytes_per_pixel * 100;
769	do_div(bandwidth, divisor);
770
771	return (uint32_t)bandwidth;
772}
773
774static enum drm_mode_status mgag200_mode_config_mode_valid(struct drm_device *dev,
775							   const struct drm_display_mode *mode)
 
 
776{
777	static const unsigned int max_bpp = 4; // DRM_FORMAT_XRGB8888
778	struct mga_device *mdev = to_mga_device(dev);
779	unsigned long fbsize, fbpages, max_fbpages;
780	const struct mgag200_device_info *info = mdev->info;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
781
782	max_fbpages = mdev->vram_available >> PAGE_SHIFT;
 
 
 
783
784	fbsize = mode->hdisplay * mode->vdisplay * max_bpp;
785	fbpages = DIV_ROUND_UP(fbsize, PAGE_SIZE);
 
 
 
 
786
787	if (fbpages > max_fbpages)
788		return MODE_MEM;
 
 
 
789
790	/*
791	 * Test the mode's required memory bandwidth if the device
792	 * specifies a maximum. Not all devices do though.
793	 */
794	if (info->max_mem_bandwidth) {
795		uint32_t mode_bandwidth = mgag200_calculate_mode_bandwidth(mode, max_bpp * 8);
796
797		if (mode_bandwidth > (info->max_mem_bandwidth * 1024))
798			return MODE_BAD;
799	}
800
801	return MODE_OK;
802}
803
804static const struct drm_mode_config_funcs mgag200_mode_config_funcs = {
805	.fb_create = drm_gem_fb_create_with_dirty,
806	.mode_valid = mgag200_mode_config_mode_valid,
807	.atomic_check = drm_atomic_helper_check,
808	.atomic_commit = drm_atomic_helper_commit,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
809};
810
811int mgag200_mode_config_init(struct mga_device *mdev, resource_size_t vram_available)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
812{
813	struct drm_device *dev = &mdev->base;
814	int ret;
 
 
 
 
 
 
 
815
816	mdev->vram_available = vram_available;
817
818	ret = drmm_mode_config_init(dev);
819	if (ret) {
820		drm_err(dev, "drmm_mode_config_init() failed: %d\n", ret);
821		return ret;
 
 
 
 
 
 
822	}
823
824	dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH;
825	dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT;
826	dev->mode_config.preferred_depth = 24;
827	dev->mode_config.funcs = &mgag200_mode_config_funcs;
828	dev->mode_config.helper_private = &mgag200_mode_config_helper_funcs;
829
830	return 0;
 
 
 
 
 
831}