pci-tx4927.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
  3. * and RBTX49xx patch from CELF patch archive.
  4. *
  5. * Copyright 2001, 2003-2005 MontaVista Software Inc.
  6. * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
  7. * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
  8. *
  9. * This file is subject to the terms and conditions of the GNU General Public
  10. * License. See the file "COPYING" in the main directory of this archive
  11. * for more details.
  12. */
  13. #include <linux/init.h>
  14. #include <linux/pci.h>
  15. #include <linux/kernel.h>
  16. #include <linux/interrupt.h>
  17. #include <asm/txx9/generic.h>
  18. #include <asm/txx9/tx4927.h>
  19. int __init tx4927_report_pciclk(void)
  20. {
  21. int pciclk = 0;
  22. pr_info("PCIC --%s PCICLK:",
  23. (__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCI66) ?
  24. " PCI66" : "");
  25. if (__raw_readq(&tx4927_ccfgptr->pcfg) & TX4927_PCFG_PCICLKEN_ALL) {
  26. u64 ccfg = __raw_readq(&tx4927_ccfgptr->ccfg);
  27. switch ((unsigned long)ccfg &
  28. TX4927_CCFG_PCIDIVMODE_MASK) {
  29. case TX4927_CCFG_PCIDIVMODE_2_5:
  30. pciclk = txx9_cpu_clock * 2 / 5; break;
  31. case TX4927_CCFG_PCIDIVMODE_3:
  32. pciclk = txx9_cpu_clock / 3; break;
  33. case TX4927_CCFG_PCIDIVMODE_5:
  34. pciclk = txx9_cpu_clock / 5; break;
  35. case TX4927_CCFG_PCIDIVMODE_6:
  36. pciclk = txx9_cpu_clock / 6; break;
  37. }
  38. pr_cont("Internal(%u.%uMHz)",
  39. (pciclk + 50000) / 1000000,
  40. ((pciclk + 50000) / 100000) % 10);
  41. } else {
  42. pr_cont("External");
  43. pciclk = -1;
  44. }
  45. pr_cont("\n");
  46. return pciclk;
  47. }
  48. int __init tx4927_pciclk66_setup(void)
  49. {
  50. int pciclk;
  51. /* Assert M66EN */
  52. tx4927_ccfg_set(TX4927_CCFG_PCI66);
  53. /* Double PCICLK (if possible) */
  54. if (__raw_readq(&tx4927_ccfgptr->pcfg) & TX4927_PCFG_PCICLKEN_ALL) {
  55. unsigned int pcidivmode = 0;
  56. u64 ccfg = __raw_readq(&tx4927_ccfgptr->ccfg);
  57. pcidivmode = (unsigned long)ccfg &
  58. TX4927_CCFG_PCIDIVMODE_MASK;
  59. switch (pcidivmode) {
  60. case TX4927_CCFG_PCIDIVMODE_5:
  61. case TX4927_CCFG_PCIDIVMODE_2_5:
  62. pcidivmode = TX4927_CCFG_PCIDIVMODE_2_5;
  63. pciclk = txx9_cpu_clock * 2 / 5;
  64. break;
  65. case TX4927_CCFG_PCIDIVMODE_6:
  66. case TX4927_CCFG_PCIDIVMODE_3:
  67. default:
  68. pcidivmode = TX4927_CCFG_PCIDIVMODE_3;
  69. pciclk = txx9_cpu_clock / 3;
  70. }
  71. tx4927_ccfg_change(TX4927_CCFG_PCIDIVMODE_MASK,
  72. pcidivmode);
  73. pr_debug("PCICLK: ccfg:%08lx\n",
  74. (unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg));
  75. } else
  76. pciclk = -1;
  77. return pciclk;
  78. }
  79. void __init tx4927_setup_pcierr_irq(void)
  80. {
  81. if (request_irq(TXX9_IRQ_BASE + TX4927_IR_PCIERR,
  82. tx4927_pcierr_interrupt,
  83. 0, "PCI error",
  84. (void *)TX4927_PCIC_REG))
  85. pr_warn("Failed to request irq for PCIERR\n");
  86. }