w83c553f.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  3. * Andreas Heppel <aheppel@sysgo.de>
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. /*
  24. * Initialisation of the PCI-to-ISA bridge and disabling the BIOS
  25. * write protection (for flash) in function 0 of the chip.
  26. * Enabling function 1 (IDE controller of the chip.
  27. */
  28. #include <common.h>
  29. #include <config.h>
  30. #include <asm/io.h>
  31. #include <pci.h>
  32. #include <w83c553f.h>
  33. #define out8(addr,val) do { \
  34. out_8((u8*) (addr),(val)); udelay(1); \
  35. } while (0)
  36. #define out16(addr,val) do { \
  37. out_be16((u16*) (addr),(val)); udelay(1); \
  38. } while (0)
  39. extern uint ide_bus_offset[CONFIG_SYS_IDE_MAXBUS];
  40. void initialise_pic(void);
  41. void initialise_dma(void);
  42. void initialise_w83c553f(void)
  43. {
  44. pci_dev_t devbusfn;
  45. unsigned char reg8;
  46. unsigned short reg16;
  47. unsigned int reg32;
  48. devbusfn = pci_find_device(W83C553F_VID, W83C553F_DID, 0);
  49. if (devbusfn == -1)
  50. {
  51. printf("Error: Cannot find W83C553F controller on any PCI bus.");
  52. return;
  53. }
  54. pci_read_config_word(devbusfn, PCI_COMMAND, &reg16);
  55. reg16 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
  56. pci_write_config_word(devbusfn, PCI_COMMAND, reg16);
  57. pci_read_config_byte(devbusfn, WINBOND_IPADCR, &reg8);
  58. /* 16 MB ISA memory space */
  59. reg8 |= (IPADCR_IPATOM4 | IPADCR_IPATOM5 | IPADCR_IPATOM6 | IPADCR_IPATOM7);
  60. reg8 &= ~IPADCR_MBE512;
  61. pci_write_config_byte(devbusfn, WINBOND_IPADCR, reg8);
  62. pci_read_config_byte(devbusfn, WINBOND_CSCR, &reg8);
  63. /* switch off BIOS write protection */
  64. reg8 |= CSCR_UBIOSCSE;
  65. reg8 &= ~CSCR_BIOSWP;
  66. pci_write_config_byte(devbusfn, WINBOND_CSCR, reg8);
  67. /*
  68. * Interrupt routing:
  69. * - IDE -> IRQ 9/0
  70. * - INTA -> IRQ 10
  71. * - INTB -> IRQ 11
  72. * - INTC -> IRQ 14
  73. * - INTD -> IRQ 15
  74. */
  75. pci_write_config_byte(devbusfn, WINBOND_IDEIRCR, 0x90);
  76. pci_write_config_word(devbusfn, WINBOND_PCIIRCR, 0xABEF);
  77. /*
  78. * Read IDE bus offsets from function 1 device.
  79. * We must unmask the LSB indicating that ist is an IO address.
  80. */
  81. devbusfn |= PCI_BDF(0,0,1);
  82. /*
  83. * Switch off legacy IRQ for IDE and IDE port 1.
  84. */
  85. pci_write_config_byte(devbusfn, 0x09, 0x8F);
  86. pci_read_config_dword(devbusfn, WINDOND_IDECSR, &reg32);
  87. reg32 &= ~(IDECSR_LEGIRQ | IDECSR_P1EN | IDECSR_P1F16);
  88. pci_write_config_dword(devbusfn, WINDOND_IDECSR, reg32);
  89. pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &ide_bus_offset[0]);
  90. ide_bus_offset[0] &= ~1;
  91. #if CONFIG_SYS_IDE_MAXBUS > 1
  92. pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_2, &ide_bus_offset[1]);
  93. ide_bus_offset[1] &= ~1;
  94. #endif
  95. /*
  96. * Enable function 1, IDE -> busmastering and IO space access
  97. */
  98. pci_read_config_word(devbusfn, PCI_COMMAND, &reg16);
  99. reg16 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
  100. pci_write_config_word(devbusfn, PCI_COMMAND, reg16);
  101. /*
  102. * Initialise ISA interrupt controller
  103. */
  104. initialise_pic();
  105. /*
  106. * Initialise DMA controller
  107. */
  108. initialise_dma();
  109. }
  110. void initialise_pic(void)
  111. {
  112. out8(W83C553F_PIC1_ICW1, 0x11);
  113. out8(W83C553F_PIC1_ICW2, 0x08);
  114. out8(W83C553F_PIC1_ICW3, 0x04);
  115. out8(W83C553F_PIC1_ICW4, 0x01);
  116. out8(W83C553F_PIC1_OCW1, 0xfb);
  117. out8(W83C553F_PIC1_ELC, 0x20);
  118. out8(W83C553F_PIC2_ICW1, 0x11);
  119. out8(W83C553F_PIC2_ICW2, 0x08);
  120. out8(W83C553F_PIC2_ICW3, 0x02);
  121. out8(W83C553F_PIC2_ICW4, 0x01);
  122. out8(W83C553F_PIC2_OCW1, 0xff);
  123. out8(W83C553F_PIC2_ELC, 0xce);
  124. out8(W83C553F_TMR1_CMOD, 0x74);
  125. out8(W83C553F_PIC2_OCW1, 0x20);
  126. out8(W83C553F_PIC1_OCW1, 0x20);
  127. out8(W83C553F_PIC2_OCW1, 0x2b);
  128. out8(W83C553F_PIC1_OCW1, 0x2b);
  129. }
  130. void initialise_dma(void)
  131. {
  132. unsigned int channel;
  133. unsigned int rvalue1, rvalue2;
  134. /* perform a H/W reset of the devices */
  135. out8(W83C553F_DMA1 + W83C553F_DMA1_MC, 0x00);
  136. out16(W83C553F_DMA2 + W83C553F_DMA2_MC, 0x0000);
  137. /* initialise all channels to a sane state */
  138. for (channel = 0; channel < 4; channel++) {
  139. /*
  140. * dependent upon the channel, setup the specifics:
  141. *
  142. * demand
  143. * address-increment
  144. * autoinitialize-disable
  145. * verify-transfer
  146. */
  147. switch (channel) {
  148. case 0:
  149. rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH0SEL|W83C553F_MODE_TT_VERIFY);
  150. rvalue2 = (W83C553F_MODE_TM_CASCADE|W83C553F_MODE_CH0SEL);
  151. break;
  152. case 1:
  153. rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH1SEL|W83C553F_MODE_TT_VERIFY);
  154. rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH1SEL|W83C553F_MODE_TT_VERIFY);
  155. break;
  156. case 2:
  157. rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH2SEL|W83C553F_MODE_TT_VERIFY);
  158. rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH2SEL|W83C553F_MODE_TT_VERIFY);
  159. break;
  160. case 3:
  161. rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH3SEL|W83C553F_MODE_TT_VERIFY);
  162. rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH3SEL|W83C553F_MODE_TT_VERIFY);
  163. break;
  164. default:
  165. rvalue1 = 0x00;
  166. rvalue2 = 0x00;
  167. break;
  168. }
  169. /* write to write mode registers */
  170. out8(W83C553F_DMA1 + W83C553F_DMA1_WM, rvalue1 & 0xFF);
  171. out16(W83C553F_DMA2 + W83C553F_DMA2_WM, rvalue2 & 0x00FF);
  172. }
  173. /* enable all channels */
  174. out8(W83C553F_DMA1 + W83C553F_DMA1_CM, 0x00);
  175. out16(W83C553F_DMA2 + W83C553F_DMA2_CM, 0x0000);
  176. /*
  177. * initialize the global DMA configuration
  178. *
  179. * DACK# active low
  180. * DREQ active high
  181. * fixed priority
  182. * channel group enable
  183. */
  184. out8(W83C553F_DMA1 + W83C553F_DMA1_CS, 0x00);
  185. out16(W83C553F_DMA2 + W83C553F_DMA2_CS, 0x0000);
  186. }