1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2004 Freescale Semiconductor. 4 * Copyright (C) 2003 Motorola Inc. 5 * Xianghua Xiao (x.xiao@motorola.com) 6 */ 7 8 /* 9 * PCI Configuration space access support for MPC85xx PCI Bridge 10 */ 11 #include <common.h> 12 #include <asm/cpm_85xx.h> 13 #include <pci.h> 14 15 #if !defined(CONFIG_FSL_PCI_INIT) 16 17 #ifndef CONFIG_SYS_PCI1_MEM_BUS 18 #define CONFIG_SYS_PCI1_MEM_BUS CONFIG_SYS_PCI1_MEM_BASE 19 #endif 20 21 #ifndef CONFIG_SYS_PCI1_IO_BUS 22 #define CONFIG_SYS_PCI1_IO_BUS CONFIG_SYS_PCI1_IO_BASE 23 #endif 24 25 #ifndef CONFIG_SYS_PCI2_MEM_BUS 26 #define CONFIG_SYS_PCI2_MEM_BUS CONFIG_SYS_PCI2_MEM_BASE 27 #endif 28 29 #ifndef CONFIG_SYS_PCI2_IO_BUS 30 #define CONFIG_SYS_PCI2_IO_BUS CONFIG_SYS_PCI2_IO_BASE 31 #endif 32 33 static struct pci_controller *pci_hose; 34 35 void 36 pci_mpc85xx_init(struct pci_controller *board_hose) 37 { 38 u16 reg16; 39 u32 dev; 40 41 volatile ccsr_pcix_t *pcix = (void *)(CONFIG_SYS_MPC85xx_PCIX_ADDR); 42 #ifdef CONFIG_MPC85XX_PCI2 43 volatile ccsr_pcix_t *pcix2 = (void *)(CONFIG_SYS_MPC85xx_PCIX2_ADDR); 44 #endif 45 volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 46 struct pci_controller * hose; 47 48 pci_hose = board_hose; 49 50 hose = &pci_hose[0]; 51 52 hose->first_busno = 0; 53 hose->last_busno = 0xff; 54 55 pci_setup_indirect(hose, 56 (CONFIG_SYS_IMMR+0x8000), 57 (CONFIG_SYS_IMMR+0x8004)); 58 59 /* 60 * Hose scan. 61 */ 62 dev = PCI_BDF(hose->first_busno, 0, 0); 63 pci_hose_read_config_word (hose, dev, PCI_COMMAND, ®16); 64 reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; 65 pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16); 66 67 /* 68 * Clear non-reserved bits in status register. 69 */ 70 pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff); 71 72 if (!(gur->pordevsr & MPC85xx_PORDEVSR_PCI1)) { 73 /* PCI-X init */ 74 if (CONFIG_SYS_CLK_FREQ < 66000000) 75 printf("PCI-X will only work at 66 MHz\n"); 76 77 reg16 = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ 78 | PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E; 79 pci_hose_write_config_word(hose, dev, PCIX_COMMAND, reg16); 80 } 81 82 pcix->potar1 = (CONFIG_SYS_PCI1_MEM_BUS >> 12) & 0x000fffff; 83 pcix->potear1 = 0x00000000; 84 pcix->powbar1 = (CONFIG_SYS_PCI1_MEM_PHYS >> 12) & 0x000fffff; 85 pcix->powbear1 = 0x00000000; 86 pcix->powar1 = (POWAR_EN | POWAR_MEM_READ | 87 POWAR_MEM_WRITE | (__ilog2(CONFIG_SYS_PCI1_MEM_SIZE) - 1)); 88 89 pcix->potar2 = (CONFIG_SYS_PCI1_IO_BUS >> 12) & 0x000fffff; 90 pcix->potear2 = 0x00000000; 91 pcix->powbar2 = (CONFIG_SYS_PCI1_IO_PHYS >> 12) & 0x000fffff; 92 pcix->powbear2 = 0x00000000; 93 pcix->powar2 = (POWAR_EN | POWAR_IO_READ | 94 POWAR_IO_WRITE | (__ilog2(CONFIG_SYS_PCI1_IO_SIZE) - 1)); 95 96 pcix->pitar1 = 0x00000000; 97 pcix->piwbar1 = 0x00000000; 98 pcix->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL | 99 PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G); 100 101 pcix->powar3 = 0; 102 pcix->powar4 = 0; 103 pcix->piwar2 = 0; 104 pcix->piwar3 = 0; 105 106 pci_set_region(hose->regions + 0, 107 CONFIG_SYS_PCI1_MEM_BUS, 108 CONFIG_SYS_PCI1_MEM_PHYS, 109 CONFIG_SYS_PCI1_MEM_SIZE, 110 PCI_REGION_MEM); 111 112 pci_set_region(hose->regions + 1, 113 CONFIG_SYS_PCI1_IO_BUS, 114 CONFIG_SYS_PCI1_IO_PHYS, 115 CONFIG_SYS_PCI1_IO_SIZE, 116 PCI_REGION_IO); 117 118 hose->region_count = 2; 119 120 pci_register_hose(hose); 121 122 #if defined(CONFIG_TARGET_MPC8555CDS) || defined(CONFIG_TARGET_MPC8541CDS) 123 /* 124 * This is a SW workaround for an apparent HW problem 125 * in the PCI controller on the MPC85555/41 CDS boards. 126 * The first config cycle must be to a valid, known 127 * device on the PCI bus in order to trick the PCI 128 * controller state machine into a known valid state. 129 * Without this, the first config cycle has the chance 130 * of hanging the controller permanently, just leaving 131 * it in a semi-working state, or leaving it working. 132 * 133 * Pick on the Tundra, Device 17, to get it right. 134 */ 135 { 136 u8 header_type; 137 138 pci_hose_read_config_byte(hose, 139 PCI_BDF(0,BRIDGE_ID,0), 140 PCI_HEADER_TYPE, 141 &header_type); 142 } 143 #endif 144 145 hose->last_busno = pci_hose_scan(hose); 146 147 #ifdef CONFIG_MPC85XX_PCI2 148 hose = &pci_hose[1]; 149 150 hose->first_busno = pci_hose[0].last_busno + 1; 151 hose->last_busno = 0xff; 152 153 pci_setup_indirect(hose, 154 (CONFIG_SYS_IMMR+0x9000), 155 (CONFIG_SYS_IMMR+0x9004)); 156 157 dev = PCI_BDF(hose->first_busno, 0, 0); 158 pci_hose_read_config_word (hose, dev, PCI_COMMAND, ®16); 159 reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; 160 pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16); 161 162 /* 163 * Clear non-reserved bits in status register. 164 */ 165 pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff); 166 167 pcix2->potar1 = (CONFIG_SYS_PCI2_MEM_BUS >> 12) & 0x000fffff; 168 pcix2->potear1 = 0x00000000; 169 pcix2->powbar1 = (CONFIG_SYS_PCI2_MEM_PHYS >> 12) & 0x000fffff; 170 pcix2->powbear1 = 0x00000000; 171 pcix2->powar1 = (POWAR_EN | POWAR_MEM_READ | 172 POWAR_MEM_WRITE | (__ilog2(CONFIG_SYS_PCI2_MEM_SIZE) - 1)); 173 174 pcix2->potar2 = (CONFIG_SYS_PCI2_IO_BUS >> 12) & 0x000fffff; 175 pcix2->potear2 = 0x00000000; 176 pcix2->powbar2 = (CONFIG_SYS_PCI2_IO_PHYS >> 12) & 0x000fffff; 177 pcix2->powbear2 = 0x00000000; 178 pcix2->powar2 = (POWAR_EN | POWAR_IO_READ | 179 POWAR_IO_WRITE | (__ilog2(CONFIG_SYS_PCI2_IO_SIZE) - 1)); 180 181 pcix2->pitar1 = 0x00000000; 182 pcix2->piwbar1 = 0x00000000; 183 pcix2->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL | 184 PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G); 185 186 pcix2->powar3 = 0; 187 pcix2->powar4 = 0; 188 pcix2->piwar2 = 0; 189 pcix2->piwar3 = 0; 190 191 pci_set_region(hose->regions + 0, 192 CONFIG_SYS_PCI2_MEM_BUS, 193 CONFIG_SYS_PCI2_MEM_PHYS, 194 CONFIG_SYS_PCI2_MEM_SIZE, 195 PCI_REGION_MEM); 196 197 pci_set_region(hose->regions + 1, 198 CONFIG_SYS_PCI2_IO_BUS, 199 CONFIG_SYS_PCI2_IO_PHYS, 200 CONFIG_SYS_PCI2_IO_SIZE, 201 PCI_REGION_IO); 202 203 hose->region_count = 2; 204 205 /* 206 * Hose scan. 207 */ 208 pci_register_hose(hose); 209 210 hose->last_busno = pci_hose_scan(hose); 211 #endif 212 } 213 #endif /* !CONFIG_FSL_PCI_INIT */ 214