0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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
0076 tx4938_ccfg_set(TX4938_CCFG_PCI66);
0077
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 }