📄 toshiba_rbtx4927_setup.c
字号:
/* * Toshiba rbtx4927 specific setup * * Author: MontaVista Software, Inc. * source@mvista.com * * Copyright 2001-2002 MontaVista Software Inc. * * Copyright (C) 1996, 1997, 2001 Ralf Baechle * Copyright (C) 2000 RidgeRun, Inc. * Author: RidgeRun, Inc. * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com * * Copyright 2001 MontaVista Software Inc. * Author: jsun@mvista.com or jsun@junsun.net * * Copyright 2002 MontaVista Software Inc. * Author: Michael Pruznick, michael_pruznick@mvista.com * * Copyright (C) 2000-2001 Toshiba Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */#include <linux/config.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/types.h>#include <linux/mm.h>#include <linux/swap.h>#include <linux/ioport.h>#include <linux/sched.h>#include <linux/interrupt.h>#include <linux/pci.h>#include <linux/timex.h>#include <asm/bootinfo.h>#include <asm/page.h>#include <asm/bootinfo.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/pci.h>#include <asm/processor.h>#include <asm/ptrace.h>#include <asm/reboot.h>#include <asm/time.h>#include <linux/version.h>#include <linux/bootmem.h>#include <linux/blk.h>#include <linux/console.h>#ifdef CONFIG_DS1742#include <asm/mc146818rtc.h>#endif#ifdef CONFIG_TOSHIBA_FPCIB0#include <asm/smsc_fdc37m81x.h>#endif#include <asm/tx4927/toshiba_rbtx4927.h>#ifdef CONFIG_PCI#include <asm/tx4927/tx4927_pci.h>#include <linux/types.h>#include <linux/pci.h>#include <linux/kernel.h>#include <linux/init.h>#include <asm/pci_channel.h>#endif#ifdef CONFIG_PC_KEYB#include <asm/keyboard.h>#endif#ifdef CONFIG_BLK_DEV_IDEPCI#include <linux/hdreg.h>#include <asm/ptrace.h>#include <linux/ide.h>extern struct ide_ops std_ide_ops;#endif#undef TOSHIBA_RBTX4927_SETUP_DEBUG#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG#define TOSHIBA_RBTX4927_SETUP_NONE 0x00000000#define TOSHIBA_RBTX4927_SETUP_INFO ( 1 << 0 )#define TOSHIBA_RBTX4927_SETUP_WARN ( 1 << 1 )#define TOSHIBA_RBTX4927_SETUP_EROR ( 1 << 2 )#define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 )#define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 )#define TOSHIBA_RBTX4927_SETUP_TIME_INIT ( 1 << 5 )#define TOSHIBA_RBTX4927_SETUP_TIMER_SETUP ( 1 << 6 )#define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 )#define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 )#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 )#define TOSHIBA_RBTX4927_SETUP_PCI66 ( 1 << 10 )#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff#endif#ifdef TOSHIBA_RBTX4927_SETUP_DEBUGstatic const u32 toshiba_rbtx4927_setup_debug_flag = (TOSHIBA_RBTX4927_SETUP_NONE | TOSHIBA_RBTX4927_SETUP_INFO | TOSHIBA_RBTX4927_SETUP_WARN | TOSHIBA_RBTX4927_SETUP_EROR | TOSHIBA_RBTX4927_SETUP_EFWFU | TOSHIBA_RBTX4927_SETUP_SETUP | TOSHIBA_RBTX4927_SETUP_TIME_INIT | TOSHIBA_RBTX4927_SETUP_TIMER_SETUP | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 | TOSHIBA_RBTX4927_SETUP_PCI2 | TOSHIBA_RBTX4927_SETUP_PCI66);#endif#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag,str...) \ if ( (toshiba_rbtx4927_setup_debug_flag) & (flag) ) \ { \ char tmp[100]; \ sprintf( tmp, str ); \ printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ }#else#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag,str...)#endif/* These functions are used for rebooting or halting the machine*/extern void toshiba_rbtx4927_restart(char *command);extern void toshiba_rbtx4927_halt(void);extern void toshiba_rbtx4927_power_off(void);int tx4927_using_backplane = 0;extern void gt64120_time_init(void);extern void toshiba_rbtx4927_irq_setup(void);#ifdef CONFIG_PCI#define CONFIG_TX4927BUG_WORKAROUND#undef TX4927_SUPPORT_COMMAND_IO#undef TX4927_SUPPORT_PCI_66int tx4927_cpu_clock = 100000000; /* 100MHz */unsigned long mips_pci_io_base;unsigned long mips_pci_io_size;unsigned long mips_pci_mem_base;unsigned long mips_pci_mem_size;/* for legacy I/O, PCI I/O PCI Bus address must be 0 */unsigned long mips_pci_io_pciaddr = 0;unsigned long mips_memory_upper;static int tx4927_ccfg_toeon = 1;static int tx4927_pcic_trdyto = 0; /* default: disabled */unsigned long tx4927_ce_base[8];void tx4927_pci_setup(void);void tx4927_reset_pci_pcic(void);#ifdef TX4927_SUPPORT_PCI_66void tx4927_pci66_setup(void);extern int tx4927_pci66_check(void);#endifint tx4927_pci66 = 0; /* 0:auto */#endifchar *toshiba_name = "";#ifdef CONFIG_PCIvoid tx4927_dump_pcic_settings(void){ printk("%s pcic settings:",toshiba_name); { int i; unsigned long *preg = (unsigned long *) tx4927_pcicptr; for (i = 0; i < sizeof(struct tx4927_pcic_reg); i += 4) { if (i % 32 == 0) printk("\n%04x:", i); if (preg == &tx4927_pcicptr->g2pintack || preg == &tx4927_pcicptr->g2pspc#ifdef CONFIG_TX4927BUG_WORKAROUND || preg == &tx4927_pcicptr->g2pcfgadrs || preg == &tx4927_pcicptr->g2pcfgdata#endif ) { printk(" XXXXXXXX"); preg++; continue; } printk(" %08lx", *preg++); if (preg == &tx4927_pcicptr->g2pcfgadrs) break; } printk("\n"); }}static void tx4927_pcierr_interrupt(int irq, void *dev_id, struct pt_regs *regs){ extern void tx4927_dump_pcic_settings(void);#ifdef CONFIG_BLK_DEV_IDEPCI /* ignore MasterAbort for ide probing... */ if (irq == TX4927_IRQ_IRC_PCIERR && ((tx4927_pcicptr->pcistatus >> 16) & 0xf900) == PCI_STATUS_REC_MASTER_ABORT) { tx4927_pcicptr->pcistatus = (tx4927_pcicptr-> pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT << 16); return; }#endif printk("PCI error interrupt (irq 0x%x).\n", irq); printk("pcistat:%04x, g2pstatus:%08lx, pcicstatus:%08lx\n", (unsigned short) (tx4927_pcicptr->pcistatus >> 16), tx4927_pcicptr->g2pstatus, tx4927_pcicptr->pcicstatus); printk("ccfg:%08lx, tear:%02lx_%08lx\n", (unsigned long) tx4927_ccfgptr->ccfg, (unsigned long) (tx4927_ccfgptr->tear >> 32), (unsigned long) tx4927_ccfgptr->tear); show_regs(regs); //tx4927_dump_pcic_settings(); panic("PCI error at PC:%08lx.", regs->cp0_epc);}static struct irqaction pcic_action = { tx4927_pcierr_interrupt, 0, 0, "PCI-C", NULL, NULL};static struct irqaction pcierr_action = { tx4927_pcierr_interrupt, 0, 0, "PCI-ERR", NULL, NULL};void __init toshiba_rbtx4927_pci_irq_init(void){ setup_irq(TX4927_IRQ_IRC_PCIC, &pcic_action); setup_irq(TX4927_IRQ_IRC_PCIERR, &pcierr_action);}void tx4927_reset_pci_pcic(void){ /* Reset PCI Bus */ *tx4927_pcireset_ptr = 1; /* Reset PCIC */ tx4927_ccfgptr->clkctr |= TX4927_CLKCTR_PCIRST; udelay(10000); /* clear PCIC reset */ tx4927_ccfgptr->clkctr &= ~TX4927_CLKCTR_PCIRST; *tx4927_pcireset_ptr = 0;}#endif /* CONFIG_PCI */#ifdef CONFIG_PCI#ifdef TX4927_SUPPORT_PCI_66void tx4927_pci66_setup(void){ int pciclk, pciclkin = 1; TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI66, "-\n"); if (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) return; tx4927_reset_pci_pcic(); /* Assert M66EN */ tx4927_ccfgptr->ccfg |= TX4927_CCFG_PCI66; /* set PCICLK 66MHz */ if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) { unsigned int pcidivmode = 0; pcidivmode = (unsigned long) tx4927_ccfgptr-> ccfg & TX4927_CCFG_PCIDIVMODE_MASK; if (tx4927_cpu_clock >= 170000000) { /* CPU 200MHz */ pcidivmode = TX4927_CCFG_PCIDIVMODE_3; pciclk = tx4927_cpu_clock / 3; } else { /* CPU 166MHz */ pcidivmode = TX4927_CCFG_PCIDIVMODE_2_5; pciclk = tx4927_cpu_clock * 2 / 5; } tx4927_ccfgptr->ccfg = (tx4927_ccfgptr->ccfg & ~TX4927_CCFG_PCIDIVMODE_MASK) | pcidivmode; TOSHIBA_RBTX4927_SETUP_DPRINTK (TOSHIBA_RBTX4927_SETUP_PCI66, ":PCICLK: ccfg:0x%08lx\n", (unsigned long) tx4927_ccfgptr->ccfg); } else { int pciclk_setting = *tx4927_pci_clk_ptr; pciclkin = 0; pciclk = 66666666; pciclk_setting &= ~TX4927_PCI_CLK_MASK; pciclk_setting |= TX4927_PCI_CLK_66; *tx4927_pci_clk_ptr = pciclk_setting; TOSHIBA_RBTX4927_SETUP_DPRINTK (TOSHIBA_RBTX4927_SETUP_PCI66, "PCICLK: pci_clk:%02x\n", *tx4927_pci_clk_ptr); } udelay(10000); /* clear PCIC reset */ tx4927_ccfgptr->clkctr &= ~TX4927_CLKCTR_PCIRST; /* clear PCI reset */ *tx4927_pcireset_ptr = 0; TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI66, "+\n");}#endif /* TX4927_SUPPORT_PCI_66 */void print_pci_status(void){ printk("PCI STATUS %lx\n", tx4927_pcicptr->pcistatus); printk("PCIC STATUS %lx\n", tx4927_pcicptr->pcicstatus);}static struct pci_dev *fake_pci_dev(struct pci_channel *hose, int top_bus, int busnr, int devfn){ static struct pci_dev dev; static struct pci_bus bus; dev.bus = &bus; dev.sysdata = hose; dev.devfn = devfn; bus.number = busnr; bus.ops = hose->pci_ops; if (busnr != top_bus) /* Fake a parent bus structure. */ bus.parent = &bus; else bus.parent = NULL; return &dev;}#define EARLY_PCI_OP(rw, size, type) \static int early_##rw##_config_##size(struct pci_channel *hose, \ int top_bus, int bus, int devfn, int offset, type value) \{ \ return pci_##rw##_config_##size( \ fake_pci_dev(hose, top_bus, bus, devfn), \ offset, value); \}EARLY_PCI_OP(read, byte, u8 *)EARLY_PCI_OP(read, dword, u32 *)EARLY_PCI_OP(write, byte, u8)EARLY_PCI_OP(write, dword, u32)static int __init tx4927_pcibios_init(int busno, struct pci_channel *hose){ u32 pci_devfn; int devfn_start = 0; int devfn_stop = 0xff; unsigned int id; TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCIBIOS, "-\n"); if (hose->first_devfn) devfn_start = hose->first_devfn; if (hose->last_devfn) devfn_stop = hose->last_devfn; for (pci_devfn = devfn_start; pci_devfn < devfn_stop; pci_devfn++) { early_read_config_dword(hose, busno, busno, pci_devfn, PCI_VENDOR_ID, &id); if (id == 0xffffffff) { continue; } if (id == 0x94601055) { u8 v08_64; u32 v32_b0; u8 v08_e1;#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG char *s = " sb/isa --";#endif TOSHIBA_RBTX4927_SETUP_DPRINTK (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg\n", s); early_read_config_byte(hose, busno, busno, pci_devfn, 0x64, &v08_64); early_read_config_dword(hose, busno, busno, pci_devfn, 0xb0, &v32_b0); early_read_config_byte(hose, busno, busno, pci_devfn, 0xe1, &v08_e1); TOSHIBA_RBTX4927_SETUP_DPRINTK (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg 0x64 = 0x%02x\n", s, v08_64); TOSHIBA_RBTX4927_SETUP_DPRINTK (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg 0xb0 = 0x%02x\n", s, v32_b0); TOSHIBA_RBTX4927_SETUP_DPRINTK (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg 0xe1 = 0x%02x\n", s, v08_e1); /* serial irq control */ v08_64 = 0xd0; /* serial irq pin */ v32_b0 |= 0x00010000; /* ide irq on isa14 */ v08_e1 &= 0xf0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -