1 /* 2 * linux/arch/mips/pci/pci-tx4938.c 3 * 4 * Based on linux/arch/mips/txx9/rbtx4938/setup.c, 5 * and RBTX49xx patch from CELF patch archive. 6 * 7 * Copyright 2001, 2003-2005 MontaVista Software Inc. 8 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) 9 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 10 * 11 * This file is subject to the terms and conditions of the GNU General Public 12 * License. See the file "COPYING" in the main directory of this archive 13 * for more details. 14 */ 15 #include <linux/init.h> 16 #include <linux/pci.h> 17 #include <linux/kernel.h> 18 #include <asm/txx9/generic.h> 19 #include <asm/txx9/tx4938.h> 20 21 int __init tx4938_report_pciclk(void) 22 { 23 int pciclk = 0; 24 25 printk(KERN_INFO "PCIC --%s PCICLK:", 26 (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66) ? 27 " PCI66" : ""); 28 if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) { 29 u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); 30 switch ((unsigned long)ccfg & 31 TX4938_CCFG_PCIDIVMODE_MASK) { 32 case TX4938_CCFG_PCIDIVMODE_4: 33 pciclk = txx9_cpu_clock / 4; break; 34 case TX4938_CCFG_PCIDIVMODE_4_5: 35 pciclk = txx9_cpu_clock * 2 / 9; break; 36 case TX4938_CCFG_PCIDIVMODE_5: 37 pciclk = txx9_cpu_clock / 5; break; 38 case TX4938_CCFG_PCIDIVMODE_5_5: 39 pciclk = txx9_cpu_clock * 2 / 11; break; 40 case TX4938_CCFG_PCIDIVMODE_8: 41 pciclk = txx9_cpu_clock / 8; break; 42 case TX4938_CCFG_PCIDIVMODE_9: 43 pciclk = txx9_cpu_clock / 9; break; 44 case TX4938_CCFG_PCIDIVMODE_10: 45 pciclk = txx9_cpu_clock / 10; break; 46 case TX4938_CCFG_PCIDIVMODE_11: 47 pciclk = txx9_cpu_clock / 11; break; 48 } 49 printk("Internal(%u.%uMHz)", 50 (pciclk + 50000) / 1000000, 51 ((pciclk + 50000) / 100000) % 10); 52 } else { 53 printk("External"); 54 pciclk = -1; 55 } 56 printk("\n"); 57 return pciclk; 58 } 59 60 void __init tx4938_report_pci1clk(void) 61 { 62 __u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); 63 unsigned int pciclk = 64 txx9_gbus_clock / ((ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2); 65 66 printk(KERN_INFO "PCIC1 -- %sPCICLK:%u.%uMHz\n", 67 (ccfg & TX4938_CCFG_PCI1_66) ? "PCI66 " : "", 68 (pciclk + 50000) / 1000000, 69 ((pciclk + 50000) / 100000) % 10); 70 } 71 72 int __init tx4938_pciclk66_setup(void) 73 { 74 int pciclk; 75 76 /* Assert M66EN */ 77 tx4938_ccfg_set(TX4938_CCFG_PCI66); 78 /* Double PCICLK (if possible) */ 79 if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) { 80 unsigned int pcidivmode = 0; 81 u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); 82 pcidivmode = (unsigned long)ccfg & 83 TX4938_CCFG_PCIDIVMODE_MASK; 84 switch (pcidivmode) { 85 case TX4938_CCFG_PCIDIVMODE_8: 86 case TX4938_CCFG_PCIDIVMODE_4: 87 pcidivmode = TX4938_CCFG_PCIDIVMODE_4; 88 pciclk = txx9_cpu_clock / 4; 89 break; 90 case TX4938_CCFG_PCIDIVMODE_9: 91 case TX4938_CCFG_PCIDIVMODE_4_5: 92 pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5; 93 pciclk = txx9_cpu_clock * 2 / 9; 94 break; 95 case TX4938_CCFG_PCIDIVMODE_10: 96 case TX4938_CCFG_PCIDIVMODE_5: 97 pcidivmode = TX4938_CCFG_PCIDIVMODE_5; 98 pciclk = txx9_cpu_clock / 5; 99 break; 100 case TX4938_CCFG_PCIDIVMODE_11: 101 case TX4938_CCFG_PCIDIVMODE_5_5: 102 default: 103 pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5; 104 pciclk = txx9_cpu_clock * 2 / 11; 105 break; 106 } 107 tx4938_ccfg_change(TX4938_CCFG_PCIDIVMODE_MASK, 108 pcidivmode); 109 printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", 110 (unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg)); 111 } else 112 pciclk = -1; 113 return pciclk; 114 } 115 116 int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) 117 { 118 if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) { 119 switch (slot) { 120 case TX4927_PCIC_IDSEL_AD_TO_SLOT(31): 121 if (__raw_readq(&tx4938_ccfgptr->pcfg) & 122 TX4938_PCFG_ETH0_SEL) 123 return TXX9_IRQ_BASE + TX4938_IR_ETH0; 124 break; 125 case TX4927_PCIC_IDSEL_AD_TO_SLOT(30): 126 if (__raw_readq(&tx4938_ccfgptr->pcfg) & 127 TX4938_PCFG_ETH1_SEL) 128 return TXX9_IRQ_BASE + TX4938_IR_ETH1; 129 break; 130 } 131 return 0; 132 } 133 return -1; 134 } 135