📄 galileo.c
字号:
/* * 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 + -