189d63fe1SAtsushi Nemoto /* 289d63fe1SAtsushi Nemoto * linux/arch/mips/pci/pci-tx4938.c 389d63fe1SAtsushi Nemoto * 489d63fe1SAtsushi Nemoto * Based on linux/arch/mips/txx9/rbtx4938/setup.c, 589d63fe1SAtsushi Nemoto * and RBTX49xx patch from CELF patch archive. 689d63fe1SAtsushi Nemoto * 789d63fe1SAtsushi Nemoto * Copyright 2001, 2003-2005 MontaVista Software Inc. 889d63fe1SAtsushi Nemoto * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) 989d63fe1SAtsushi Nemoto * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 1089d63fe1SAtsushi Nemoto * 1189d63fe1SAtsushi Nemoto * This file is subject to the terms and conditions of the GNU General Public 1289d63fe1SAtsushi Nemoto * License. See the file "COPYING" in the main directory of this archive 1389d63fe1SAtsushi Nemoto * for more details. 1489d63fe1SAtsushi Nemoto */ 1589d63fe1SAtsushi Nemoto #include <linux/init.h> 1689d63fe1SAtsushi Nemoto #include <linux/pci.h> 1789d63fe1SAtsushi Nemoto #include <linux/kernel.h> 18455cc256SAtsushi Nemoto #include <linux/interrupt.h> 1989d63fe1SAtsushi Nemoto #include <asm/txx9/generic.h> 2089d63fe1SAtsushi Nemoto #include <asm/txx9/tx4938.h> 2189d63fe1SAtsushi Nemoto 2289d63fe1SAtsushi Nemoto int __init tx4938_report_pciclk(void) 2389d63fe1SAtsushi Nemoto { 2489d63fe1SAtsushi Nemoto int pciclk = 0; 2589d63fe1SAtsushi Nemoto 2689d63fe1SAtsushi Nemoto printk(KERN_INFO "PCIC --%s PCICLK:", 2789d63fe1SAtsushi Nemoto (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66) ? 2889d63fe1SAtsushi Nemoto " PCI66" : ""); 2989d63fe1SAtsushi Nemoto if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) { 3089d63fe1SAtsushi Nemoto u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); 3189d63fe1SAtsushi Nemoto switch ((unsigned long)ccfg & 3289d63fe1SAtsushi Nemoto TX4938_CCFG_PCIDIVMODE_MASK) { 3389d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_4: 3489d63fe1SAtsushi Nemoto pciclk = txx9_cpu_clock / 4; break; 3589d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_4_5: 3689d63fe1SAtsushi Nemoto pciclk = txx9_cpu_clock * 2 / 9; break; 3789d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_5: 3889d63fe1SAtsushi Nemoto pciclk = txx9_cpu_clock / 5; break; 3989d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_5_5: 4089d63fe1SAtsushi Nemoto pciclk = txx9_cpu_clock * 2 / 11; break; 4189d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_8: 4289d63fe1SAtsushi Nemoto pciclk = txx9_cpu_clock / 8; break; 4389d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_9: 4489d63fe1SAtsushi Nemoto pciclk = txx9_cpu_clock / 9; break; 4589d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_10: 4689d63fe1SAtsushi Nemoto pciclk = txx9_cpu_clock / 10; break; 4789d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_11: 4889d63fe1SAtsushi Nemoto pciclk = txx9_cpu_clock / 11; break; 4989d63fe1SAtsushi Nemoto } 5089d63fe1SAtsushi Nemoto printk("Internal(%u.%uMHz)", 5189d63fe1SAtsushi Nemoto (pciclk + 50000) / 1000000, 5289d63fe1SAtsushi Nemoto ((pciclk + 50000) / 100000) % 10); 5389d63fe1SAtsushi Nemoto } else { 5489d63fe1SAtsushi Nemoto printk("External"); 5589d63fe1SAtsushi Nemoto pciclk = -1; 5689d63fe1SAtsushi Nemoto } 5789d63fe1SAtsushi Nemoto printk("\n"); 5889d63fe1SAtsushi Nemoto return pciclk; 5989d63fe1SAtsushi Nemoto } 6089d63fe1SAtsushi Nemoto 6189d63fe1SAtsushi Nemoto void __init tx4938_report_pci1clk(void) 6289d63fe1SAtsushi Nemoto { 6389d63fe1SAtsushi Nemoto __u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); 6489d63fe1SAtsushi Nemoto unsigned int pciclk = 6589d63fe1SAtsushi Nemoto txx9_gbus_clock / ((ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2); 6689d63fe1SAtsushi Nemoto 6789d63fe1SAtsushi Nemoto printk(KERN_INFO "PCIC1 -- %sPCICLK:%u.%uMHz\n", 6889d63fe1SAtsushi Nemoto (ccfg & TX4938_CCFG_PCI1_66) ? "PCI66 " : "", 6989d63fe1SAtsushi Nemoto (pciclk + 50000) / 1000000, 7089d63fe1SAtsushi Nemoto ((pciclk + 50000) / 100000) % 10); 7189d63fe1SAtsushi Nemoto } 7289d63fe1SAtsushi Nemoto 7389d63fe1SAtsushi Nemoto int __init tx4938_pciclk66_setup(void) 7489d63fe1SAtsushi Nemoto { 7589d63fe1SAtsushi Nemoto int pciclk; 7689d63fe1SAtsushi Nemoto 7789d63fe1SAtsushi Nemoto /* Assert M66EN */ 7889d63fe1SAtsushi Nemoto tx4938_ccfg_set(TX4938_CCFG_PCI66); 7989d63fe1SAtsushi Nemoto /* Double PCICLK (if possible) */ 8089d63fe1SAtsushi Nemoto if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) { 8189d63fe1SAtsushi Nemoto unsigned int pcidivmode = 0; 8289d63fe1SAtsushi Nemoto u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); 8389d63fe1SAtsushi Nemoto pcidivmode = (unsigned long)ccfg & 8489d63fe1SAtsushi Nemoto TX4938_CCFG_PCIDIVMODE_MASK; 8589d63fe1SAtsushi Nemoto switch (pcidivmode) { 8689d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_8: 8789d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_4: 8889d63fe1SAtsushi Nemoto pcidivmode = TX4938_CCFG_PCIDIVMODE_4; 8989d63fe1SAtsushi Nemoto pciclk = txx9_cpu_clock / 4; 9089d63fe1SAtsushi Nemoto break; 9189d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_9: 9289d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_4_5: 9389d63fe1SAtsushi Nemoto pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5; 9489d63fe1SAtsushi Nemoto pciclk = txx9_cpu_clock * 2 / 9; 9589d63fe1SAtsushi Nemoto break; 9689d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_10: 9789d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_5: 9889d63fe1SAtsushi Nemoto pcidivmode = TX4938_CCFG_PCIDIVMODE_5; 9989d63fe1SAtsushi Nemoto pciclk = txx9_cpu_clock / 5; 10089d63fe1SAtsushi Nemoto break; 10189d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_11: 10289d63fe1SAtsushi Nemoto case TX4938_CCFG_PCIDIVMODE_5_5: 10389d63fe1SAtsushi Nemoto default: 10489d63fe1SAtsushi Nemoto pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5; 10589d63fe1SAtsushi Nemoto pciclk = txx9_cpu_clock * 2 / 11; 10689d63fe1SAtsushi Nemoto break; 10789d63fe1SAtsushi Nemoto } 10889d63fe1SAtsushi Nemoto tx4938_ccfg_change(TX4938_CCFG_PCIDIVMODE_MASK, 10989d63fe1SAtsushi Nemoto pcidivmode); 11089d63fe1SAtsushi Nemoto printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", 11189d63fe1SAtsushi Nemoto (unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg)); 11289d63fe1SAtsushi Nemoto } else 11389d63fe1SAtsushi Nemoto pciclk = -1; 11489d63fe1SAtsushi Nemoto return pciclk; 11589d63fe1SAtsushi Nemoto } 11689d63fe1SAtsushi Nemoto 11789d63fe1SAtsushi Nemoto int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) 11889d63fe1SAtsushi Nemoto { 11989d63fe1SAtsushi Nemoto if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) { 12089d63fe1SAtsushi Nemoto switch (slot) { 12189d63fe1SAtsushi Nemoto case TX4927_PCIC_IDSEL_AD_TO_SLOT(31): 12289d63fe1SAtsushi Nemoto if (__raw_readq(&tx4938_ccfgptr->pcfg) & 12389d63fe1SAtsushi Nemoto TX4938_PCFG_ETH0_SEL) 12489d63fe1SAtsushi Nemoto return TXX9_IRQ_BASE + TX4938_IR_ETH0; 12589d63fe1SAtsushi Nemoto break; 12689d63fe1SAtsushi Nemoto case TX4927_PCIC_IDSEL_AD_TO_SLOT(30): 12789d63fe1SAtsushi Nemoto if (__raw_readq(&tx4938_ccfgptr->pcfg) & 12889d63fe1SAtsushi Nemoto TX4938_PCFG_ETH1_SEL) 12989d63fe1SAtsushi Nemoto return TXX9_IRQ_BASE + TX4938_IR_ETH1; 13089d63fe1SAtsushi Nemoto break; 13189d63fe1SAtsushi Nemoto } 13289d63fe1SAtsushi Nemoto return 0; 13389d63fe1SAtsushi Nemoto } 13489d63fe1SAtsushi Nemoto return -1; 13589d63fe1SAtsushi Nemoto } 136455cc256SAtsushi Nemoto 137455cc256SAtsushi Nemoto void __init tx4938_setup_pcierr_irq(void) 138455cc256SAtsushi Nemoto { 139455cc256SAtsushi Nemoto if (request_irq(TXX9_IRQ_BASE + TX4938_IR_PCIERR, 140455cc256SAtsushi Nemoto tx4927_pcierr_interrupt, 141455cc256SAtsushi Nemoto IRQF_DISABLED, "PCI error", 142455cc256SAtsushi Nemoto (void *)TX4927_PCIC_REG)) 143455cc256SAtsushi Nemoto printk(KERN_WARNING "Failed to request irq for PCIERR\n"); 144455cc256SAtsushi Nemoto } 145