aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bcma/driver_pci_host.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bcma/driver_pci_host.c')
-rw-r--r--drivers/bcma/driver_pci_host.c62
1 files changed, 38 insertions, 24 deletions
diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c
index af0c9fabee54..d3bde6cec927 100644
--- a/drivers/bcma/driver_pci_host.c
+++ b/drivers/bcma/driver_pci_host.c
@@ -94,19 +94,19 @@ static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
94 if (dev == 0) { 94 if (dev == 0) {
95 /* we support only two functions on device 0 */ 95 /* we support only two functions on device 0 */
96 if (func > 1) 96 if (func > 1)
97 return -EINVAL; 97 goto out;
98 98
99 /* accesses to config registers with offsets >= 256 99 /* accesses to config registers with offsets >= 256
100 * requires indirect access. 100 * requires indirect access.
101 */ 101 */
102 if (off >= PCI_CONFIG_SPACE_SIZE) { 102 if (off >= PCI_CONFIG_SPACE_SIZE) {
103 addr = (func << 12); 103 addr = (func << 12);
104 addr |= (off & 0x0FFF); 104 addr |= (off & 0x0FFC);
105 val = bcma_pcie_read_config(pc, addr); 105 val = bcma_pcie_read_config(pc, addr);
106 } else { 106 } else {
107 addr = BCMA_CORE_PCI_PCICFG0; 107 addr = BCMA_CORE_PCI_PCICFG0;
108 addr |= (func << 8); 108 addr |= (func << 8);
109 addr |= (off & 0xfc); 109 addr |= (off & 0xFC);
110 val = pcicore_read32(pc, addr); 110 val = pcicore_read32(pc, addr);
111 } 111 }
112 } else { 112 } else {
@@ -119,11 +119,9 @@ static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
119 goto out; 119 goto out;
120 120
121 if (mips_busprobe32(val, mmio)) { 121 if (mips_busprobe32(val, mmio)) {
122 val = 0xffffffff; 122 val = 0xFFFFFFFF;
123 goto unmap; 123 goto unmap;
124 } 124 }
125
126 val = readl(mmio);
127 } 125 }
128 val >>= (8 * (off & 3)); 126 val >>= (8 * (off & 3));
129 127
@@ -151,7 +149,7 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
151 const void *buf, int len) 149 const void *buf, int len)
152{ 150{
153 int err = -EINVAL; 151 int err = -EINVAL;
154 u32 addr = 0, val = 0; 152 u32 addr, val;
155 void __iomem *mmio = 0; 153 void __iomem *mmio = 0;
156 u16 chipid = pc->core->bus->chipinfo.id; 154 u16 chipid = pc->core->bus->chipinfo.id;
157 155
@@ -159,16 +157,22 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
159 if (unlikely(len != 1 && len != 2 && len != 4)) 157 if (unlikely(len != 1 && len != 2 && len != 4))
160 goto out; 158 goto out;
161 if (dev == 0) { 159 if (dev == 0) {
160 /* we support only two functions on device 0 */
161 if (func > 1)
162 goto out;
163
162 /* accesses to config registers with offsets >= 256 164 /* accesses to config registers with offsets >= 256
163 * requires indirect access. 165 * requires indirect access.
164 */ 166 */
165 if (off < PCI_CONFIG_SPACE_SIZE) { 167 if (off >= PCI_CONFIG_SPACE_SIZE) {
166 addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0; 168 addr = (func << 12);
169 addr |= (off & 0x0FFC);
170 val = bcma_pcie_read_config(pc, addr);
171 } else {
172 addr = BCMA_CORE_PCI_PCICFG0;
167 addr |= (func << 8); 173 addr |= (func << 8);
168 addr |= (off & 0xfc); 174 addr |= (off & 0xFC);
169 mmio = ioremap_nocache(addr, sizeof(val)); 175 val = pcicore_read32(pc, addr);
170 if (!mmio)
171 goto out;
172 } 176 }
173 } else { 177 } else {
174 addr = bcma_get_cfgspace_addr(pc, dev, func, off); 178 addr = bcma_get_cfgspace_addr(pc, dev, func, off);
@@ -180,19 +184,17 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
180 goto out; 184 goto out;
181 185
182 if (mips_busprobe32(val, mmio)) { 186 if (mips_busprobe32(val, mmio)) {
183 val = 0xffffffff; 187 val = 0xFFFFFFFF;
184 goto unmap; 188 goto unmap;
185 } 189 }
186 } 190 }
187 191
188 switch (len) { 192 switch (len) {
189 case 1: 193 case 1:
190 val = readl(mmio);
191 val &= ~(0xFF << (8 * (off & 3))); 194 val &= ~(0xFF << (8 * (off & 3)));
192 val |= *((const u8 *)buf) << (8 * (off & 3)); 195 val |= *((const u8 *)buf) << (8 * (off & 3));
193 break; 196 break;
194 case 2: 197 case 2:
195 val = readl(mmio);
196 val &= ~(0xFFFF << (8 * (off & 3))); 198 val &= ~(0xFFFF << (8 * (off & 3)));
197 val |= *((const u16 *)buf) << (8 * (off & 3)); 199 val |= *((const u16 *)buf) << (8 * (off & 3));
198 break; 200 break;
@@ -200,13 +202,14 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
200 val = *((const u32 *)buf); 202 val = *((const u32 *)buf);
201 break; 203 break;
202 } 204 }
203 if (dev == 0 && !addr) { 205 if (dev == 0) {
204 /* accesses to config registers with offsets >= 256 206 /* accesses to config registers with offsets >= 256
205 * requires indirect access. 207 * requires indirect access.
206 */ 208 */
207 addr = (func << 12); 209 if (off >= PCI_CONFIG_SPACE_SIZE)
208 addr |= (off & 0x0FFF); 210 bcma_pcie_write_config(pc, addr, val);
209 bcma_pcie_write_config(pc, addr, val); 211 else
212 pcicore_write32(pc, addr, val);
210 } else { 213 } else {
211 writel(val, mmio); 214 writel(val, mmio);
212 215
@@ -276,7 +279,7 @@ static u8 bcma_find_pci_capability(struct bcma_drv_pci *pc, unsigned int dev,
276 /* check for Header type 0 */ 279 /* check for Header type 0 */
277 bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val, 280 bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
278 sizeof(u8)); 281 sizeof(u8));
279 if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL) 282 if ((byte_val & 0x7F) != PCI_HEADER_TYPE_NORMAL)
280 return cap_ptr; 283 return cap_ptr;
281 284
282 /* check if the capability pointer field exists */ 285 /* check if the capability pointer field exists */
@@ -426,7 +429,7 @@ void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
426 /* Reset RC */ 429 /* Reset RC */
427 usleep_range(3000, 5000); 430 usleep_range(3000, 5000);
428 pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE); 431 pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
429 usleep_range(1000, 2000); 432 msleep(50);
430 pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST | 433 pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
431 BCMA_CORE_PCI_CTL_RST_OE); 434 BCMA_CORE_PCI_CTL_RST_OE);
432 435
@@ -488,6 +491,17 @@ void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
488 491
489 bcma_core_pci_enable_crs(pc); 492 bcma_core_pci_enable_crs(pc);
490 493
494 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706 ||
495 bus->chipinfo.id == BCMA_CHIP_ID_BCM4716) {
496 u16 val16;
497 bcma_extpci_read_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL,
498 &val16, sizeof(val16));
499 val16 |= (2 << 5); /* Max payload size of 512 */
500 val16 |= (2 << 12); /* MRRS 512 */
501 bcma_extpci_write_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL,
502 &val16, sizeof(val16));
503 }
504
491 /* Enable PCI bridge BAR0 memory & master access */ 505 /* Enable PCI bridge BAR0 memory & master access */
492 tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; 506 tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
493 bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp)); 507 bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
@@ -576,7 +590,7 @@ int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
576 pr_info("PCI: Fixing up device %s\n", pci_name(dev)); 590 pr_info("PCI: Fixing up device %s\n", pci_name(dev));
577 591
578 /* Fix up interrupt lines */ 592 /* Fix up interrupt lines */
579 dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2; 593 dev->irq = bcma_core_irq(pc_host->pdev->core);
580 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 594 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
581 595
582 return 0; 596 return 0;
@@ -595,6 +609,6 @@ int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev)
595 609
596 pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host, 610 pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
597 pci_ops); 611 pci_ops);
598 return bcma_core_mips_irq(pc_host->pdev->core) + 2; 612 return bcma_core_irq(pc_host->pdev->core);
599} 613}
600EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq); 614EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);