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

📄 galileo.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) * * May be copied or modified under the terms of the GNU General Public * License.  See linux/COPYING for more information.                             * * This file contains the PCI routines required for the Galileo GT6411  * PCI bridge as used on the Orion and Overdrive boards. * */#include <linux/config.h>#include <linux/kernel.h>#include <linux/smp.h>#include <linux/smp_lock.h>#include <linux/init.h>#include <linux/errno.h>#include <linux/pci.h>#include <linux/delay.h>#include <linux/types.h>#include <linux/ioport.h>#include <asm/overdrive/overdrive.h>#include <asm/overdrive/gt64111.h>/* After boot, we shift the Galileo registers so that they appear  * in BANK6, along with IO space. This means we can have one contingous * lump of PCI address space without these registers appearing in the  * middle of them  */#define GT64111_BASE_ADDRESS  0xbb000000#define GT64111_IO_BASE_ADDRESS  0x1000/* The GT64111 registers appear at this address to the SH4 after reset */#define RESET_GT64111_BASE_ADDRESS           0xb4000000/* Macros used to access the Galileo registers */#define RESET_GT64111_REG(x) (RESET_GT64111_BASE_ADDRESS+x)#define GT64111_REG(x) (GT64111_BASE_ADDRESS+x)#define RESET_GT_WRITE(x,v) writel((v),RESET_GT64111_REG(x))#define RESET_GT_READ(x) readl(RESET_GT64111_REG(x))#define GT_WRITE(x,v) writel((v),GT64111_REG(x))#define GT_WRITE_BYTE(x,v) writeb((v),GT64111_REG(x))#define GT_WRITE_SHORT(x,v) writew((v),GT64111_REG(x))#define GT_READ(x)    readl(GT64111_REG(x))#define GT_READ_BYTE(x)  readb(GT64111_REG(x))#define GT_READ_SHORT(x) readw(GT64111_REG(x))/* Where the various SH banks start at */#define SH_BANK4_ADR 0xb0000000#define SH_BANK5_ADR 0xb4000000#define SH_BANK6_ADR 0xb8000000/* Masks out everything but lines 28,27,26 */#define BANK_SELECT_MASK 0x1c000000#define SH4_TO_BANK(x) ( (x) & BANK_SELECT_MASK)/*  * Masks used for address conversaion. Bank 6 is used for IO and  * has all the address bits zeroed by the FPGA. Special case this */#define MEMORY_BANK_MASK 0x1fffffff#define IO_BANK_MASK  0x03ffffff/* Mark bank 6 as the bank used for IO. You can change this in the FPGA code * if you want  */#define IO_BANK_ADR PCI_GTIO_BASE/* Will select the correct mask to apply depending on the SH$ address */#define SELECT_BANK_MASK(x) \   ( (SH4_TO_BANK(x)==SH4_TO_BANK(IO_BANK_ADR)) ? IO_BANK_MASK : MEMORY_BANK_MASK)/* Converts between PCI space and P2 region */#define SH4_TO_PCI(x) ((x)&SELECT_BANK_MASK(x))/* Various macros for figuring out what to stick in the Galileo registers.  * You *really* don't want to figure this stuff out by hand, you always get * it wrong */#define GT_MEM_LO_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7ff)#define GT_MEM_HI_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7f)#define GT_MEM_SUB_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>20)&0xff)#define PROGRAM_HI_LO(block,a,s) \    GT_WRITE(block##_LO_DEC_ADR,GT_MEM_LO_ADR(a));\    GT_WRITE(block##_HI_DEC_ADR,GT_MEM_HI_ADR(a+s-1))#define PROGRAM_SUB_HI_LO(block,a,s) \    GT_WRITE(block##_LO_DEC_ADR,GT_MEM_SUB_ADR(a));\    GT_WRITE(block##_HI_DEC_ADR,GT_MEM_SUB_ADR(a+s-1))/* We need to set the size, and the offset register */#define GT_BAR_MASK(x) ((x)&~0xfff)/* Macro to set up the BAR in the Galileo. Essentially used for the DRAM */#define PROGRAM_GT_BAR(block,a,s) \  GT_WRITE(PCI_##block##_BANK_SIZE,GT_BAR_MASK((s-1)));\  write_config_to_galileo(PCI_CONFIG_##block##_BASE_ADR,\			     GT_BAR_MASK(a))#define DISABLE_GT_BAR(block) \  GT_WRITE(PCI_##block##_BANK_SIZE,0),\  GT_CONFIG_WRITE(PCI_CONFIG_##block##_BASE_ADR,\    0x80000000)/* Macros to disable things we are not going to use */#define DISABLE_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0x7ff);\                          GT_WRITE(x##_HI_DEC_ADR,0x00)#define DISABLE_SUB_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0xff);\                              GT_WRITE(x##_HI_DEC_ADR,0x00)static void __init reset_pci(void){	/* Set RESET_PCI bit high */	writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL);	udelay(250);	/* Set RESET_PCI bit low */	writeb(readb(OVERDRIVE_CTRL) & RESET_PCI_MASK, OVERDRIVE_CTRL);	udelay(250);	writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL);	udelay(250);}static int write_config_to_galileo(int where, u32 val);#define GT_CONFIG_WRITE(where,val) write_config_to_galileo(where,val)#define ENABLE_PCI_DRAM#ifdef TEST_DRAM/* Test function to check out if the PCI DRAM is working OK */static int  /* __init */ test_dram(unsigned *base, unsigned size){	unsigned *p = base;	unsigned *end = (unsigned *) (((unsigned) base) + size);	unsigned w;	for (p = base; p < end; p++) {		*p = 0xffffffff;		if (*p != 0xffffffff) {			printk("AAARGH -write failed!!! at %p is %x\n", p,			       *p);			return 0;		}		*p = 0x0;		if (*p != 0x0) {			printk("AAARGH -write failed!!!\n");			return 0;		}	}	for (p = base; p < end; p++) {		*p = (unsigned) p;		if (*p != (unsigned) p) {			printk("Failed at 0x%p, actually is 0x%x\n", p,			       *p);			return 0;		}	}	for (p = base; p < end; p++) {		w = ((unsigned) p & 0xffff0000);		*p = w | (w >> 16);	}	for (p = base; p < end; p++) {		w = ((unsigned) p & 0xffff0000);		w |= (w >> 16);		if (*p != w) {			printk			    ("Failed at 0x%p, should be 0x%x actually is 0x%x\n",			     p, w, *p);			return 0;		}	}	return 1;}#endif/* Function to set up and initialise the galileo. This sets up the BARS, * maps the DRAM into the address space etc,etc */int __init galileo_init(void){	reset_pci();	/* Now shift the galileo regs into this block */	RESET_GT_WRITE(INTERNAL_SPACE_DEC,		       GT_MEM_LO_ADR(GT64111_BASE_ADDRESS));	/* Should have a sanity check here, that you can read back  at the new	 * address what you just wrote 	 */	/* Disable decode for all regions */	DISABLE_DECODE(RAS10);	DISABLE_DECODE(RAS32);	DISABLE_DECODE(CS20);	DISABLE_DECODE(CS3);	DISABLE_DECODE(PCI_IO);	DISABLE_DECODE(PCI_MEM0);	DISABLE_DECODE(PCI_MEM1);	/* Disable all BARS */	GT_WRITE(BAR_ENABLE_ADR, 0x1ff);	DISABLE_GT_BAR(RAS10);	DISABLE_GT_BAR(RAS32);	DISABLE_GT_BAR(CS20);	DISABLE_GT_BAR(CS3);	/* Tell the BAR where the IO registers now are */	GT_CONFIG_WRITE(PCI_CONFIG_INT_REG_IO_ADR,GT_BAR_MASK(					    (GT64111_IO_BASE_ADDRESS &					     IO_BANK_MASK)));	/* set up a 112 Mb decode */	PROGRAM_HI_LO(PCI_MEM0, SH_BANK4_ADR, 112 * 1024 * 1024);	/* Set up a 32 MB io space decode */	PROGRAM_HI_LO(PCI_IO, IO_BANK_ADR, 32 * 1024 * 1024);#ifdef ENABLE_PCI_DRAM	/* Program up the DRAM configuration - there is DRAM only in bank 0 */	/* Now set up the DRAM decode */	PROGRAM_HI_LO(RAS10, PCI_DRAM_BASE, PCI_DRAM_SIZE);	/* And the sub decode */	PROGRAM_SUB_HI_LO(RAS0, PCI_DRAM_BASE, PCI_DRAM_SIZE);	DISABLE_SUB_DECODE(RAS1);	/* Set refresh rate */	GT_WRITE(DRAM_BANK0_PARMS, 0x3f);	GT_WRITE(DRAM_CFG, 0x100);	/* we have to lob off the top bits rememeber!! */	PROGRAM_GT_BAR(RAS10, SH4_TO_PCI(PCI_DRAM_BASE), PCI_DRAM_SIZE);#endif	/* We are only interested in decoding RAS10 and the Galileo's internal 	 * registers (as IO) on the PCI bus	 */#ifdef ENABLE_PCI_DRAM	GT_WRITE(BAR_ENABLE_ADR, (~((1 << 8) | (1 << 3))) & 0x1ff);#else	GT_WRITE(BAR_ENABLE_ADR, (~(1 << 3)) & 0x1ff);#endif	/* Change the class code to host bridge, it actually powers up 	 * as a memory controller         */	GT_CONFIG_WRITE(8, 0x06000011);	/* Allow the galileo to master the PCI bus */	GT_CONFIG_WRITE(PCI_COMMAND,			PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |			PCI_COMMAND_IO);#if 0        printk("Testing PCI DRAM - ");	if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) {		printk("Passed\n");	}else {		printk("FAILED\n");	}#endif	return 0;}#define SET_CONFIG_BITS(bus,devfn,where)\  ((1<<31) | ((bus) << 16) | ((devfn) << 8) | ((where) & ~3))#define CONFIG_CMD(dev, where) SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where)/* This write to the galileo config registers, unlike the functions below, can * be used before the PCI subsystem has started up */static int __init write_config_to_galileo(int where, u32 val){

⌨️ 快捷键说明

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