⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci_schizo.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
			break;		case 1:			/* 16-bit IO space, 16MB */			pbm->io_space.start = a;			pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL);			pbm->io_space.flags = IORESOURCE_IO;			saw_io = 1;			break;		case 2:			/* 32-bit MEM space, 2GB */			pbm->mem_space.start = a;			pbm->mem_space.end = a + (0x80000000UL - 1UL);			pbm->mem_space.flags = IORESOURCE_MEM;			saw_mem = 1;			break;		default:			break;		};	}	if (!saw_cfg || !saw_io || !saw_mem) {		prom_printf("%s: Fatal error, missing %s PBM range.\n",			    pbm->name,			    ((!saw_cfg ?			      "CFG" :			      (!saw_io ?			       "IO" : "MEM"))));		prom_halt();	}	printk("%s: PCI CFG[%lx] IO[%lx] MEM[%lx]\n",	       pbm->name,	       pbm->config_space,	       pbm->io_space.start,	       pbm->mem_space.start);}static void pbm_register_toplevel_resources(struct pci_controller_info *p,					    struct pci_pbm_info *pbm){	pbm->io_space.name = pbm->mem_space.name = pbm->name;	request_resource(&ioport_resource, &pbm->io_space);	request_resource(&iomem_resource, &pbm->mem_space);	pci_register_legacy_regions(&pbm->io_space,				    &pbm->mem_space);}#define SCHIZO_STRBUF_CONTROL		(0x02800UL)#define SCHIZO_STRBUF_FLUSH		(0x02808UL)#define SCHIZO_STRBUF_FSYNC		(0x02810UL)#define SCHIZO_STRBUF_CTXFLUSH		(0x02818UL)#define SCHIZO_STRBUF_CTXMATCH		(0x10000UL)static void schizo_pbm_strbuf_init(struct pci_pbm_info *pbm){	unsigned long base = pbm->pbm_regs;	u64 control;	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) {		/* TOMATILLO lacks streaming cache.  */		return;	}	/* SCHIZO has context flushing. */	pbm->stc.strbuf_control		= base + SCHIZO_STRBUF_CONTROL;	pbm->stc.strbuf_pflush		= base + SCHIZO_STRBUF_FLUSH;	pbm->stc.strbuf_fsync		= base + SCHIZO_STRBUF_FSYNC;	pbm->stc.strbuf_ctxflush	= base + SCHIZO_STRBUF_CTXFLUSH;	pbm->stc.strbuf_ctxmatch_base	= base + SCHIZO_STRBUF_CTXMATCH;	pbm->stc.strbuf_flushflag = (volatile unsigned long *)		((((unsigned long)&pbm->stc.__flushflag_buf[0])		  + 63UL)		 & ~63UL);	pbm->stc.strbuf_flushflag_pa = (unsigned long)		__pa(pbm->stc.strbuf_flushflag);	/* Turn off LRU locking and diag mode, enable the	 * streaming buffer and leave the rerun-disable	 * setting however OBP set it.	 */	control = schizo_read(pbm->stc.strbuf_control);	control &= ~(SCHIZO_STRBUF_CTRL_LPTR |		     SCHIZO_STRBUF_CTRL_LENAB |		     SCHIZO_STRBUF_CTRL_DENAB);	control |= SCHIZO_STRBUF_CTRL_ENAB;	schizo_write(pbm->stc.strbuf_control, control);	pbm->stc.strbuf_enabled = 1;}#define SCHIZO_IOMMU_CONTROL		(0x00200UL)#define SCHIZO_IOMMU_TSBBASE		(0x00208UL)#define SCHIZO_IOMMU_FLUSH		(0x00210UL)#define SCHIZO_IOMMU_CTXFLUSH		(0x00218UL)static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm){	struct pci_iommu *iommu = pbm->iommu;	unsigned long i, tagbase, database;	u32 vdma[2], dma_mask;	u64 control;	int err, tsbsize;	err = prom_getproperty(pbm->prom_node, "virtual-dma",			       (char *)&vdma[0], sizeof(vdma));	if (err == 0 || err == -1) {		/* No property, use default values. */		vdma[0] = 0xc0000000;		vdma[1] = 0x40000000;	}	dma_mask = vdma[0];	switch (vdma[1]) {		case 0x20000000:			dma_mask |= 0x1fffffff;			tsbsize = 64;			break;		case 0x40000000:			dma_mask |= 0x3fffffff;			tsbsize = 128;			break;		case 0x80000000:			dma_mask |= 0x7fffffff;			tsbsize = 128;			break;		default:			prom_printf("SCHIZO: strange virtual-dma size.\n");			prom_halt();	};	/* Register addresses, SCHIZO has iommu ctx flushing. */	iommu->iommu_control  = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL;	iommu->iommu_tsbbase  = pbm->pbm_regs + SCHIZO_IOMMU_TSBBASE;	iommu->iommu_flush    = pbm->pbm_regs + SCHIZO_IOMMU_FLUSH;	iommu->iommu_ctxflush = pbm->pbm_regs + SCHIZO_IOMMU_CTXFLUSH;	/* We use the main control/status register of SCHIZO as the write	 * completion register.	 */	iommu->write_complete_reg = pbm->controller_regs + 0x10000UL;	/*	 * Invalidate TLB Entries.	 */	control = schizo_read(iommu->iommu_control);	control |= SCHIZO_IOMMU_CTRL_DENAB;	schizo_write(iommu->iommu_control, control);	tagbase = SCHIZO_IOMMU_TAG, database = SCHIZO_IOMMU_DATA;	for(i = 0; i < 16; i++) {		schizo_write(pbm->pbm_regs + tagbase + (i * 8UL), 0);		schizo_write(pbm->pbm_regs + database + (i * 8UL), 0);	}	/* Leave diag mode enabled for full-flushing done	 * in pci_iommu.c	 */	pci_iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask);	schizo_write(iommu->iommu_tsbbase, __pa(iommu->page_table));	control = schizo_read(iommu->iommu_control);	control &= ~(SCHIZO_IOMMU_CTRL_TSBSZ | SCHIZO_IOMMU_CTRL_TBWSZ);	switch (tsbsize) {	case 64:		control |= SCHIZO_IOMMU_TSBSZ_64K;		break;	case 128:		control |= SCHIZO_IOMMU_TSBSZ_128K;		break;	};	control |= SCHIZO_IOMMU_CTRL_ENAB;	schizo_write(iommu->iommu_control, control);}#define SCHIZO_PCI_IRQ_RETRY	(0x1a00UL)#define  SCHIZO_IRQ_RETRY_INF	 0xffUL#define SCHIZO_PCI_DIAG			(0x2020UL)#define  SCHIZO_PCIDIAG_D_BADECC	(1UL << 10UL) /* Disable BAD ECC errors (Schizo) */#define  SCHIZO_PCIDIAG_D_BYPASS	(1UL <<  9UL) /* Disable MMU bypass mode (Schizo/Tomatillo) */#define  SCHIZO_PCIDIAG_D_TTO		(1UL <<  8UL) /* Disable TTO errors (Schizo/Tomatillo) */#define  SCHIZO_PCIDIAG_D_RTRYARB	(1UL <<  7UL) /* Disable retry arbitration (Schizo) */#define  SCHIZO_PCIDIAG_D_RETRY		(1UL <<  6UL) /* Disable retry limit (Schizo/Tomatillo) */#define  SCHIZO_PCIDIAG_D_INTSYNC	(1UL <<  5UL) /* Disable interrupt/DMA synch (Schizo/Tomatillo) */#define  SCHIZO_PCIDIAG_I_DMA_PARITY	(1UL <<  3UL) /* Invert DMA parity (Schizo/Tomatillo) */#define  SCHIZO_PCIDIAG_I_PIOD_PARITY	(1UL <<  2UL) /* Invert PIO data parity (Schizo/Tomatillo) */#define  SCHIZO_PCIDIAG_I_PIOA_PARITY	(1UL <<  1UL) /* Invert PIO address parity (Schizo/Tomatillo) */#define TOMATILLO_PCI_IOC_CSR		(0x2248UL)#define TOMATILLO_IOC_PART_WPENAB	0x0000000000080000UL#define TOMATILLO_IOC_RDMULT_PENAB	0x0000000000040000UL#define TOMATILLO_IOC_RDONE_PENAB	0x0000000000020000UL#define TOMATILLO_IOC_RDLINE_PENAB	0x0000000000010000UL#define TOMATILLO_IOC_RDMULT_PLEN	0x000000000000c000UL#define TOMATILLO_IOC_RDMULT_PLEN_SHIFT	14UL#define TOMATILLO_IOC_RDONE_PLEN	0x0000000000003000UL#define TOMATILLO_IOC_RDONE_PLEN_SHIFT	12UL#define TOMATILLO_IOC_RDLINE_PLEN	0x0000000000000c00UL#define TOMATILLO_IOC_RDLINE_PLEN_SHIFT	10UL#define TOMATILLO_IOC_PREF_OFF		0x00000000000003f8UL#define TOMATILLO_IOC_PREF_OFF_SHIFT	3UL#define TOMATILLO_IOC_RDMULT_CPENAB	0x0000000000000004UL#define TOMATILLO_IOC_RDONE_CPENAB	0x0000000000000002UL#define TOMATILLO_IOC_RDLINE_CPENAB	0x0000000000000001UL#define TOMATILLO_PCI_IOC_TDIAG		(0x2250UL)#define TOMATILLO_PCI_IOC_DDIAG		(0x2290UL)static void schizo_pbm_hw_init(struct pci_pbm_info *pbm){	u64 tmp;	schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5);	tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL);	/* Enable arbiter for all PCI slots.  */	tmp |= 0xff;	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO &&	    pbm->chip_version >= 0x2)		tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT;	if (!prom_getbool(pbm->prom_node, "no-bus-parking"))		tmp |= SCHIZO_PCICTRL_PARK;	else		tmp &= ~SCHIZO_PCICTRL_PARK;	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO &&	    pbm->chip_version <= 0x1)		tmp |= SCHIZO_PCICTRL_DTO_INT;	else		tmp &= ~SCHIZO_PCICTRL_DTO_INT;	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO)		tmp |= (SCHIZO_PCICTRL_MRM_PREF |			SCHIZO_PCICTRL_RDO_PREF |			SCHIZO_PCICTRL_RDL_PREF);	schizo_write(pbm->pbm_regs + SCHIZO_PCI_CTRL, tmp);	tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_DIAG);	tmp &= ~(SCHIZO_PCIDIAG_D_RTRYARB |		 SCHIZO_PCIDIAG_D_RETRY |		 SCHIZO_PCIDIAG_D_INTSYNC);	schizo_write(pbm->pbm_regs + SCHIZO_PCI_DIAG, tmp);	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) {		/* Clear prefetch lengths to workaround a bug in		 * Jalapeno...		 */		tmp = (TOMATILLO_IOC_PART_WPENAB |		       (1 << TOMATILLO_IOC_PREF_OFF_SHIFT) |		       TOMATILLO_IOC_RDMULT_CPENAB |		       TOMATILLO_IOC_RDONE_CPENAB |		       TOMATILLO_IOC_RDLINE_CPENAB);		schizo_write(pbm->pbm_regs + TOMATILLO_PCI_IOC_CSR,			     tmp);	}}static void schizo_pbm_init(struct pci_controller_info *p,			    int prom_node, u32 portid,			    int chip_type){	struct linux_prom64_registers pr_regs[4];	unsigned int busrange[2];	struct pci_pbm_info *pbm;	const char *chipset_name;	u32 ino_bitmap[2];	int is_pbm_a;	int err;	switch (chip_type) {	case PBM_CHIP_TYPE_TOMATILLO:		chipset_name = "TOMATILLO";		break;	case PBM_CHIP_TYPE_SCHIZO_PLUS:		chipset_name = "SCHIZO+";		break;	case PBM_CHIP_TYPE_SCHIZO:	default:		chipset_name = "SCHIZO";		break;	};	/* For SCHIZO, three OBP regs:	 * 1) PBM controller regs	 * 2) Schizo front-end controller regs (same for both PBMs)	 * 3) PBM PCI config space	 *	 * For TOMATILLO, four OBP regs:	 * 1) PBM controller regs	 * 2) Tomatillo front-end controller regs	 * 3) PBM PCI config space	 * 4) Ichip regs	 */	err = prom_getproperty(prom_node, "reg",			       (char *)&pr_regs[0],			       sizeof(pr_regs));	if (err == 0 || err == -1) {		prom_printf("%s: Fatal error, no reg property.\n",			    chipset_name);		prom_halt();	}	is_pbm_a = ((pr_regs[0].phys_addr & 0x00700000) == 0x00600000);	if (is_pbm_a)		pbm = &p->pbm_A;	else		pbm = &p->pbm_B;	pbm->portid = portid;	pbm->parent = p;	pbm->prom_node = prom_node;	pbm->pci_first_slot = 1;	pbm->chip_type = chip_type;	pbm->chip_version =		prom_getintdefault(prom_node, "version#", 0);	pbm->chip_revision =		prom_getintdefault(prom_node, "module-revision#", 0);	pbm->pbm_regs = pr_regs[0].phys_addr;	pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL;	if (chip_type == PBM_CHIP_TYPE_TOMATILLO)		pbm->sync_reg = pr_regs[3].phys_addr + 0x1a18UL;	sprintf(pbm->name,		(chip_type == PBM_CHIP_TYPE_TOMATILLO ?		 "TOMATILLO%d PBM%c" :		 "SCHIZO%d PBM%c"),		p->index,		(pbm == &p->pbm_A ? 'A' : 'B'));	printk("%s: ver[%x:%x], portid %x, "	       "cregs[%lx] pregs[%lx]\n",	       pbm->name,	       pbm->chip_version, pbm->chip_revision,	       pbm->portid,	       pbm->controller_regs,	       pbm->pbm_regs);	schizo_pbm_hw_init(pbm);	prom_getstring(prom_node, "name",		       pbm->prom_name,		       sizeof(pbm->prom_name));	err = prom_getproperty(prom_node, "ranges",			       (char *) pbm->pbm_ranges,			       sizeof(pbm->pbm_ranges));	if (err == 0 || err == -1) {		prom_printf("%s: Fatal error, no ranges property.\n",			    pbm->name);		prom_halt();	}	pbm->num_pbm_ranges =		(err / sizeof(struct linux_prom_pci_ranges));	schizo_determine_mem_io_space(pbm);	pbm_register_toplevel_resources(p, pbm);	err = prom_getproperty(prom_node, "interrupt-map",			       (char *)pbm->pbm_intmap,			       sizeof(pbm->pbm_intmap));	if (err != -1) {		pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap));		err = prom_getproperty(prom_node, "interrupt-map-mask",				       (char *)&pbm->pbm_intmask,				       sizeof(pbm->pbm_intmask));		if (err == -1) {			prom_printf("%s: Fatal error, no "				    "interrupt-map-mask.\n", pbm->name);			prom_halt();		}	} else {		pbm->num_pbm_intmap = 0;		memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));	}	err = prom_getproperty(prom_node, "ino-bitmap",			       (char *) &ino_bitmap[0],			       sizeof(ino_bitmap));	if (err == 0 || err == -1) {		prom_printf("%s: Fatal error, no ino-bitmap.\n", pbm->name);		prom_halt();	}	pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) |			   ((u64)ino_bitmap[0] <<  0UL));	err = prom_getproperty(prom_node, "bus-range",			       (char *)&busrange[0],			       sizeof(busrange));	if (err == 0 || err == -1) {		prom_printf("%s: Fatal error, no bus-range.\n", pbm->name);		prom_h

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -