Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
0003  *      and RBTX49xx patch from CELF patch archive.
0004  *
0005  * Copyright 2001, 2003-2005 MontaVista Software Inc.
0006  * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
0007  * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
0008  *
0009  * This file is subject to the terms and conditions of the GNU General Public
0010  * License.  See the file "COPYING" in the main directory of this archive
0011  * for more details.
0012  */
0013 #include <linux/init.h>
0014 #include <linux/pci.h>
0015 #include <linux/kernel.h>
0016 #include <linux/interrupt.h>
0017 #include <asm/txx9/generic.h>
0018 #include <asm/txx9/tx4938.h>
0019 
0020 int __init tx4938_report_pciclk(void)
0021 {
0022     int pciclk = 0;
0023 
0024     pr_info("PCIC --%s PCICLK:",
0025         (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66) ?
0026         " PCI66" : "");
0027     if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) {
0028         u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg);
0029         switch ((unsigned long)ccfg &
0030             TX4938_CCFG_PCIDIVMODE_MASK) {
0031         case TX4938_CCFG_PCIDIVMODE_4:
0032             pciclk = txx9_cpu_clock / 4; break;
0033         case TX4938_CCFG_PCIDIVMODE_4_5:
0034             pciclk = txx9_cpu_clock * 2 / 9; break;
0035         case TX4938_CCFG_PCIDIVMODE_5:
0036             pciclk = txx9_cpu_clock / 5; break;
0037         case TX4938_CCFG_PCIDIVMODE_5_5:
0038             pciclk = txx9_cpu_clock * 2 / 11; break;
0039         case TX4938_CCFG_PCIDIVMODE_8:
0040             pciclk = txx9_cpu_clock / 8; break;
0041         case TX4938_CCFG_PCIDIVMODE_9:
0042             pciclk = txx9_cpu_clock / 9; break;
0043         case TX4938_CCFG_PCIDIVMODE_10:
0044             pciclk = txx9_cpu_clock / 10; break;
0045         case TX4938_CCFG_PCIDIVMODE_11:
0046             pciclk = txx9_cpu_clock / 11; break;
0047         }
0048         pr_cont("Internal(%u.%uMHz)",
0049             (pciclk + 50000) / 1000000,
0050             ((pciclk + 50000) / 100000) % 10);
0051     } else {
0052         pr_cont("External");
0053         pciclk = -1;
0054     }
0055     pr_cont("\n");
0056     return pciclk;
0057 }
0058 
0059 void __init tx4938_report_pci1clk(void)
0060 {
0061     __u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg);
0062     unsigned int pciclk =
0063         txx9_gbus_clock / ((ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2);
0064 
0065     pr_info("PCIC1 -- %sPCICLK:%u.%uMHz\n",
0066         (ccfg & TX4938_CCFG_PCI1_66) ? "PCI66 " : "",
0067         (pciclk + 50000) / 1000000,
0068         ((pciclk + 50000) / 100000) % 10);
0069 }
0070 
0071 int __init tx4938_pciclk66_setup(void)
0072 {
0073     int pciclk;
0074 
0075     /* Assert M66EN */
0076     tx4938_ccfg_set(TX4938_CCFG_PCI66);
0077     /* Double PCICLK (if possible) */
0078     if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) {
0079         unsigned int pcidivmode = 0;
0080         u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg);
0081         pcidivmode = (unsigned long)ccfg &
0082             TX4938_CCFG_PCIDIVMODE_MASK;
0083         switch (pcidivmode) {
0084         case TX4938_CCFG_PCIDIVMODE_8:
0085         case TX4938_CCFG_PCIDIVMODE_4:
0086             pcidivmode = TX4938_CCFG_PCIDIVMODE_4;
0087             pciclk = txx9_cpu_clock / 4;
0088             break;
0089         case TX4938_CCFG_PCIDIVMODE_9:
0090         case TX4938_CCFG_PCIDIVMODE_4_5:
0091             pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5;
0092             pciclk = txx9_cpu_clock * 2 / 9;
0093             break;
0094         case TX4938_CCFG_PCIDIVMODE_10:
0095         case TX4938_CCFG_PCIDIVMODE_5:
0096             pcidivmode = TX4938_CCFG_PCIDIVMODE_5;
0097             pciclk = txx9_cpu_clock / 5;
0098             break;
0099         case TX4938_CCFG_PCIDIVMODE_11:
0100         case TX4938_CCFG_PCIDIVMODE_5_5:
0101         default:
0102             pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5;
0103             pciclk = txx9_cpu_clock * 2 / 11;
0104             break;
0105         }
0106         tx4938_ccfg_change(TX4938_CCFG_PCIDIVMODE_MASK,
0107                    pcidivmode);
0108         pr_debug("PCICLK: ccfg:%08lx\n",
0109              (unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg));
0110     } else
0111         pciclk = -1;
0112     return pciclk;
0113 }
0114 
0115 int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot)
0116 {
0117     if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) {
0118         switch (slot) {
0119         case TX4927_PCIC_IDSEL_AD_TO_SLOT(31):
0120             if (__raw_readq(&tx4938_ccfgptr->pcfg) &
0121                 TX4938_PCFG_ETH0_SEL)
0122                 return TXX9_IRQ_BASE + TX4938_IR_ETH0;
0123             break;
0124         case TX4927_PCIC_IDSEL_AD_TO_SLOT(30):
0125             if (__raw_readq(&tx4938_ccfgptr->pcfg) &
0126                 TX4938_PCFG_ETH1_SEL)
0127                 return TXX9_IRQ_BASE + TX4938_IR_ETH1;
0128             break;
0129         }
0130         return 0;
0131     }
0132     return -1;
0133 }
0134 
0135 void __init tx4938_setup_pcierr_irq(void)
0136 {
0137     if (request_irq(TXX9_IRQ_BASE + TX4938_IR_PCIERR,
0138             tx4927_pcierr_interrupt,
0139             0, "PCI error",
0140             (void *)TX4927_PCIC_REG))
0141         pr_warn("Failed to request irq for PCIERR\n");
0142 }