cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nv_driver.c (9774B)


      1/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
      2/*
      3 * Copyright 1996-1997  David J. McKay
      4 *
      5 * Permission is hereby granted, free of charge, to any person obtaining a
      6 * copy of this software and associated documentation files (the "Software"),
      7 * to deal in the Software without restriction, including without limitation
      8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9 * and/or sell copies of the Software, and to permit persons to whom the
     10 * Software is furnished to do so, subject to the following conditions:
     11 *
     12 * The above copyright notice and this permission notice shall be included in
     13 * all copies or substantial portions of the Software.
     14 *
     15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18 * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     20 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     21 * SOFTWARE.
     22 */
     23
     24/*
     25 * GPL licensing note -- nVidia is allowing a liberal interpretation of
     26 * the documentation restriction above, to merely say that this nVidia's
     27 * copyright and disclaimer should be included with all code derived
     28 * from this source.  -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 
     29 */
     30
     31/* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen
     32   <jpaana@s2.org> */
     33
     34/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.18 2002/08/0
     355 20:47:06 mvojkovi Exp $ */
     36
     37#include <linux/delay.h>
     38#include <linux/pci.h>
     39#include <linux/pci_ids.h>
     40#include "nv_type.h"
     41#include "rivafb.h"
     42#include "nvreg.h"
     43
     44#define PFX "rivafb: "
     45
     46static inline unsigned char MISCin(struct riva_par *par)
     47{
     48	return (VGA_RD08(par->riva.PVIO, 0x3cc));
     49}
     50
     51static Bool 
     52riva_is_connected(struct riva_par *par, Bool second)
     53{
     54	volatile U032 __iomem *PRAMDAC = par->riva.PRAMDAC0;
     55	U032 reg52C, reg608;
     56	Bool present;
     57
     58	if(second) PRAMDAC += 0x800;
     59
     60	reg52C = NV_RD32(PRAMDAC, 0x052C);
     61	reg608 = NV_RD32(PRAMDAC, 0x0608);
     62
     63	NV_WR32(PRAMDAC, 0x0608, reg608 & ~0x00010000);
     64
     65	NV_WR32(PRAMDAC, 0x052C, reg52C & 0x0000FEEE);
     66	mdelay(1); 
     67	NV_WR32(PRAMDAC, 0x052C, NV_RD32(PRAMDAC, 0x052C) | 1);
     68
     69	NV_WR32(par->riva.PRAMDAC0, 0x0610, 0x94050140);
     70	NV_WR32(par->riva.PRAMDAC0, 0x0608, 0x00001000);
     71
     72	mdelay(1);
     73
     74	present = (NV_RD32(PRAMDAC, 0x0608) & (1 << 28)) ? TRUE : FALSE;
     75
     76	NV_WR32(par->riva.PRAMDAC0, 0x0608,
     77		NV_RD32(par->riva.PRAMDAC0, 0x0608) & 0x0000EFFF);
     78
     79	NV_WR32(PRAMDAC, 0x052C, reg52C);
     80	NV_WR32(PRAMDAC, 0x0608, reg608);
     81
     82	return present;
     83}
     84
     85static void
     86riva_override_CRTC(struct riva_par *par)
     87{
     88	printk(KERN_INFO PFX
     89		"Detected CRTC controller %i being used\n",
     90		par->SecondCRTC ? 1 : 0);
     91
     92	if(par->forceCRTC != -1) {
     93		printk(KERN_INFO PFX
     94			"Forcing usage of CRTC %i\n", par->forceCRTC);
     95		par->SecondCRTC = par->forceCRTC;
     96	}
     97}
     98
     99static void
    100riva_is_second(struct riva_par *par)
    101{
    102	if (par->FlatPanel == 1) {
    103		switch(par->Chipset & 0xffff) {
    104		case 0x0174:
    105		case 0x0175:
    106		case 0x0176:
    107		case 0x0177:
    108		case 0x0179:
    109		case 0x017C:
    110		case 0x017D:
    111		case 0x0186:
    112		case 0x0187:
    113		/* this might not be a good default for the chips below */
    114		case 0x0286:
    115		case 0x028C:
    116		case 0x0316:
    117		case 0x0317:
    118		case 0x031A:
    119		case 0x031B:
    120		case 0x031C:
    121		case 0x031D:
    122		case 0x031E:
    123		case 0x031F:
    124		case 0x0324:
    125		case 0x0325:
    126		case 0x0328:
    127		case 0x0329:
    128		case 0x032C:
    129		case 0x032D:
    130			par->SecondCRTC = TRUE;
    131			break;
    132		default:
    133			par->SecondCRTC = FALSE;
    134			break;
    135		}
    136	} else {
    137		if(riva_is_connected(par, 0)) {
    138
    139			if (NV_RD32(par->riva.PRAMDAC0, 0x0000052C) & 0x100)
    140				par->SecondCRTC = TRUE;
    141			else
    142				par->SecondCRTC = FALSE;
    143		} else 
    144		if (riva_is_connected(par, 1)) {
    145			if(NV_RD32(par->riva.PRAMDAC0, 0x0000252C) & 0x100)
    146				par->SecondCRTC = TRUE;
    147			else
    148				par->SecondCRTC = FALSE;
    149		} else /* default */
    150			par->SecondCRTC = FALSE;
    151	}
    152	riva_override_CRTC(par);
    153}
    154
    155unsigned long riva_get_memlen(struct riva_par *par)
    156{
    157	RIVA_HW_INST *chip = &par->riva;
    158	unsigned long memlen = 0;
    159	unsigned int chipset = par->Chipset;
    160	struct pci_dev* dev;
    161	u32 amt;
    162	int domain = pci_domain_nr(par->pdev->bus);
    163
    164	switch (chip->Architecture) {
    165	case NV_ARCH_03:
    166		if (NV_RD32(chip->PFB, 0x00000000) & 0x00000020) {
    167			if (((NV_RD32(chip->PMC, 0x00000000) & 0xF0) == 0x20)
    168			    && ((NV_RD32(chip->PMC, 0x00000000)&0x0F)>=0x02)) {
    169				/*
    170				 * SDRAM 128 ZX.
    171				 */
    172				switch (NV_RD32(chip->PFB,0x00000000) & 0x03) {
    173				case 2:
    174					memlen = 1024 * 4;
    175					break;
    176				case 1:
    177					memlen = 1024 * 2;
    178					break;
    179				default:
    180					memlen = 1024 * 8;
    181					break;
    182				}
    183			} else {
    184				memlen = 1024 * 8;
    185			}            
    186		} else 	{
    187			/*
    188			 * SGRAM 128.
    189			 */
    190			switch (NV_RD32(chip->PFB, 0x00000000) & 0x00000003) {
    191			case 0:
    192				memlen = 1024 * 8;
    193				break;
    194			case 2:
    195				memlen = 1024 * 4;
    196				break;
    197			default:
    198				memlen = 1024 * 2;
    199				break;
    200			}
    201		}        
    202		break;
    203	case NV_ARCH_04:
    204		if (NV_RD32(chip->PFB, 0x00000000) & 0x00000100) {
    205			memlen = ((NV_RD32(chip->PFB, 0x00000000)>>12)&0x0F) *
    206				1024 * 2 + 1024 * 2;
    207		} else {
    208			switch (NV_RD32(chip->PFB, 0x00000000) & 0x00000003) {
    209			case 0:
    210				memlen = 1024 * 32;
    211				break;
    212			case 1:
    213				memlen = 1024 * 4;
    214				break;
    215			case 2:
    216				memlen = 1024 * 8;
    217				break;
    218			case 3:
    219			default:
    220				memlen = 1024 * 16;
    221				break;
    222			}
    223		}
    224		break;
    225	case NV_ARCH_10:
    226	case NV_ARCH_20:
    227	case NV_ARCH_30:
    228		if(chipset == NV_CHIP_IGEFORCE2) {
    229
    230			dev = pci_get_domain_bus_and_slot(domain, 0, 1);
    231			pci_read_config_dword(dev, 0x7C, &amt);
    232			pci_dev_put(dev);
    233			memlen = (((amt >> 6) & 31) + 1) * 1024;
    234		} else if (chipset == NV_CHIP_0x01F0) {
    235			dev = pci_get_domain_bus_and_slot(domain, 0, 1);
    236			pci_read_config_dword(dev, 0x84, &amt);
    237			pci_dev_put(dev);
    238			memlen = (((amt >> 4) & 127) + 1) * 1024;
    239		} else {
    240			switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) &
    241				0x000000FF){
    242			case 0x02:
    243				memlen = 1024 * 2;
    244				break;
    245			case 0x04:
    246				memlen = 1024 * 4;
    247				break;
    248			case 0x08:
    249				memlen = 1024 * 8;
    250				break;
    251			case 0x10:
    252				memlen = 1024 * 16;
    253				break;
    254			case 0x20:
    255				memlen = 1024 * 32;
    256				break;
    257			case 0x40:
    258				memlen = 1024 * 64;
    259				break;
    260			case 0x80:
    261				memlen = 1024 * 128;
    262				break;
    263			default:
    264				memlen = 1024 * 16;
    265				break;
    266			}
    267		}
    268		break;
    269	}
    270	return memlen;
    271}
    272
    273unsigned long riva_get_maxdclk(struct riva_par *par)
    274{
    275	RIVA_HW_INST *chip = &par->riva;
    276	unsigned long dclk = 0;
    277
    278	switch (chip->Architecture) {
    279	case NV_ARCH_03:
    280		if (NV_RD32(chip->PFB, 0x00000000) & 0x00000020) {
    281			if (((NV_RD32(chip->PMC, 0x00000000) & 0xF0) == 0x20)
    282			    && ((NV_RD32(chip->PMC,0x00000000)&0x0F) >= 0x02)) {
    283				/*
    284				 * SDRAM 128 ZX.
    285				 */
    286				dclk = 800000;
    287			} else {
    288				dclk = 1000000;
    289			}            
    290		} else {
    291			/*
    292			 * SGRAM 128.
    293			 */
    294			dclk = 1000000;
    295		} 
    296		break;
    297	case NV_ARCH_04:
    298	case NV_ARCH_10:
    299	case NV_ARCH_20:
    300	case NV_ARCH_30:
    301		switch ((NV_RD32(chip->PFB, 0x00000000) >> 3) & 0x00000003) {
    302		case 3:
    303			dclk = 800000;
    304			break;
    305		default:
    306			dclk = 1000000;
    307			break;
    308		}
    309		break;
    310	}
    311	return dclk;
    312}
    313
    314void
    315riva_common_setup(struct riva_par *par)
    316{
    317	par->riva.EnableIRQ = 0;
    318	par->riva.PRAMDAC0 =
    319		(volatile U032 __iomem *)(par->ctrl_base + 0x00680000);
    320	par->riva.PFB =
    321		(volatile U032 __iomem *)(par->ctrl_base + 0x00100000);
    322	par->riva.PFIFO =
    323		(volatile U032 __iomem *)(par->ctrl_base + 0x00002000);
    324	par->riva.PGRAPH =
    325		(volatile U032 __iomem *)(par->ctrl_base + 0x00400000);
    326	par->riva.PEXTDEV =
    327		(volatile U032 __iomem *)(par->ctrl_base + 0x00101000);
    328	par->riva.PTIMER =
    329		(volatile U032 __iomem *)(par->ctrl_base + 0x00009000);
    330	par->riva.PMC =
    331		(volatile U032 __iomem *)(par->ctrl_base + 0x00000000);
    332	par->riva.FIFO =
    333		(volatile U032 __iomem *)(par->ctrl_base + 0x00800000);
    334	par->riva.PCIO0 = par->ctrl_base + 0x00601000;
    335	par->riva.PDIO0 = par->ctrl_base + 0x00681000;
    336	par->riva.PVIO = par->ctrl_base + 0x000C0000;
    337
    338	par->riva.IO = (MISCin(par) & 0x01) ? 0x3D0 : 0x3B0;
    339	
    340	if (par->FlatPanel == -1) {
    341		switch (par->Chipset & 0xffff) {
    342		case 0x0112:   /* known laptop chips */
    343		case 0x0174:
    344		case 0x0175:
    345		case 0x0176:
    346		case 0x0177:
    347		case 0x0179:
    348		case 0x017C:
    349		case 0x017D:
    350		case 0x0186:
    351		case 0x0187:
    352		case 0x0286:
    353		case 0x028C:
    354		case 0x0316:
    355		case 0x0317:
    356		case 0x031A:
    357		case 0x031B:
    358		case 0x031C:
    359		case 0x031D:
    360		case 0x031E:
    361		case 0x031F:
    362		case 0x0324:
    363		case 0x0325:
    364		case 0x0328:
    365		case 0x0329:
    366		case 0x032C:
    367		case 0x032D:
    368			printk(KERN_INFO PFX 
    369				"On a laptop.  Assuming Digital Flat Panel\n");
    370			par->FlatPanel = 1;
    371			break;
    372		default:
    373			break;
    374		}
    375	}
    376	
    377	switch (par->Chipset & 0x0ff0) {
    378	case 0x0110:
    379		if (par->Chipset == NV_CHIP_GEFORCE2_GO)
    380			par->SecondCRTC = TRUE; 
    381#if defined(__powerpc__)
    382		if (par->FlatPanel == 1)
    383			par->SecondCRTC = TRUE;
    384#endif
    385		riva_override_CRTC(par);
    386		break;
    387	case 0x0170:
    388	case 0x0180:
    389	case 0x01F0:
    390	case 0x0250:
    391	case 0x0280:
    392	case 0x0300:
    393	case 0x0310:
    394	case 0x0320:
    395	case 0x0330:
    396	case 0x0340:
    397		riva_is_second(par);
    398		break;
    399	default:
    400		break;
    401	}
    402
    403	if (par->SecondCRTC) {
    404		par->riva.PCIO = par->riva.PCIO0 + 0x2000;
    405		par->riva.PCRTC = par->riva.PCRTC0 + 0x800;
    406		par->riva.PRAMDAC = par->riva.PRAMDAC0 + 0x800;
    407		par->riva.PDIO = par->riva.PDIO0 + 0x2000;
    408	} else {
    409		par->riva.PCIO = par->riva.PCIO0;
    410		par->riva.PCRTC = par->riva.PCRTC0;
    411		par->riva.PRAMDAC = par->riva.PRAMDAC0;
    412		par->riva.PDIO = par->riva.PDIO0;
    413	}
    414
    415	if (par->FlatPanel == -1) {
    416		/* Fix me, need x86 DDC code */
    417		par->FlatPanel = 0;
    418	}
    419	par->riva.flatPanel = (par->FlatPanel > 0) ? TRUE : FALSE;
    420
    421	RivaGetConfig(&par->riva, par->pdev, par->Chipset);
    422}
    423