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