w83c553f.c 5.2 KB

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