^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* pci_common.c: PCI controller common support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/oplib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "pci_impl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "pci_sun4v.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static int config_out_of_range(struct pci_pbm_info *pbm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) unsigned long bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) unsigned long devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) unsigned long reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) if (bus < pbm->pci_first_busno ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) bus > pbm->pci_last_busno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static void *sun4u_config_mkaddr(struct pci_pbm_info *pbm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) unsigned long bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) unsigned long devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned long reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) unsigned long rbits = pbm->config_space_reg_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (config_out_of_range(pbm, bus, devfn, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) reg = (reg & ((1 << rbits) - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) devfn <<= rbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) bus <<= rbits + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return (void *) (pbm->config_space | bus | devfn | reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* At least on Sabre, it is necessary to access all PCI host controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * registers at their natural size, otherwise zeros are returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Strange but true, and I see no language in the UltraSPARC-IIi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * programmer's manual that mentions this even indirectly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static int sun4u_read_pci_cfg_host(struct pci_pbm_info *pbm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned char bus, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int where, int size, u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u32 tmp32, *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u16 tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u8 tmp8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (!addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (where < 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned long align = (unsigned long) addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) align &= ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) pci_config_read16((u16 *)align, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (where & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) *value = tmp16 >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) *value = tmp16 & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) pci_config_read8((u8 *)addr, &tmp8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *value = (u32) tmp8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (where < 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) pci_config_read16((u16 *)addr, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *value = (u32) tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) pci_config_read8((u8 *)addr, &tmp8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *value = (u32) tmp8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) pci_config_read8(((u8 *)addr) + 1, &tmp8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) *value |= ((u32) tmp8) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) tmp32 = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) sun4u_read_pci_cfg_host(pbm, bus, devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) where, 2, &tmp32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) *value = tmp32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) tmp32 = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) sun4u_read_pci_cfg_host(pbm, bus, devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) where + 2, 2, &tmp32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *value |= tmp32 << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int sun4u_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int where, int size, u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct pci_pbm_info *pbm = bus_dev->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned char bus = bus_dev->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u32 *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u16 tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u8 tmp8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *value = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) *value = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *value = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (!bus_dev->number && !PCI_SLOT(devfn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return sun4u_read_pci_cfg_host(pbm, bus, devfn, where,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) size, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (!addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) pci_config_read8((u8 *)addr, &tmp8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) *value = (u32) tmp8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (where & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) printk("pci_read_config_word: misaligned reg [%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) where);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) pci_config_read16((u16 *)addr, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) *value = (u32) tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (where & 0x03) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) printk("pci_read_config_dword: misaligned reg [%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) where);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) pci_config_read32(addr, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static int sun4u_write_pci_cfg_host(struct pci_pbm_info *pbm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) unsigned char bus, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) int where, int size, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u32 *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (!addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (where < 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) unsigned long align = (unsigned long) addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u16 tmp16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) align &= ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) pci_config_read16((u16 *)align, &tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (where & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) tmp16 &= 0x00ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) tmp16 |= value << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) tmp16 &= 0xff00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) tmp16 |= value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) pci_config_write16((u16 *)align, tmp16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) pci_config_write8((u8 *)addr, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (where < 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) pci_config_write16((u16 *)addr, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) pci_config_write8((u8 *)addr, value & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) pci_config_write8(((u8 *)addr) + 1, value >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) sun4u_write_pci_cfg_host(pbm, bus, devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) where, 2, value & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) sun4u_write_pci_cfg_host(pbm, bus, devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) where + 2, 2, value >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static int sun4u_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) int where, int size, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct pci_pbm_info *pbm = bus_dev->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) unsigned char bus = bus_dev->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) u32 *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!bus_dev->number && !PCI_SLOT(devfn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return sun4u_write_pci_cfg_host(pbm, bus, devfn, where,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) size, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (!addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) pci_config_write8((u8 *)addr, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (where & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) printk("pci_write_config_word: misaligned reg [%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) where);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) pci_config_write16((u16 *)addr, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (where & 0x03) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) printk("pci_write_config_dword: misaligned reg [%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) where);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) pci_config_write32(addr, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct pci_ops sun4u_pci_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .read = sun4u_read_pci_cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .write = sun4u_write_pci_cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) int where, int size, u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct pci_pbm_info *pbm = bus_dev->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) u32 devhandle = pbm->devhandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) unsigned int bus = bus_dev->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) unsigned int device = PCI_SLOT(devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) unsigned int func = PCI_FUNC(devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) unsigned long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (config_out_of_range(pbm, bus, devfn, where)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ret = ~0UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ret = pci_sun4v_config_get(devhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) HV_PCI_DEVICE_BUILD(bus, device, func),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) where, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) *value = ret & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *value = ret & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *value = ret & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int where, int size, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct pci_pbm_info *pbm = bus_dev->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) u32 devhandle = pbm->devhandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) unsigned int bus = bus_dev->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) unsigned int device = PCI_SLOT(devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) unsigned int func = PCI_FUNC(devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (config_out_of_range(pbm, bus, devfn, where)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* Do nothing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* We don't check for hypervisor errors here, but perhaps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * we should and influence our return value depending upon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * what kind of error is thrown.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) pci_sun4v_config_put(devhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) HV_PCI_DEVICE_BUILD(bus, device, func),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) where, size, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct pci_ops sun4v_pci_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) .read = sun4v_read_pci_cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .write = sun4v_write_pci_cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) void pci_get_pbm_props(struct pci_pbm_info *pbm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) const u32 *val = of_get_property(pbm->op->dev.of_node, "bus-range", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) pbm->pci_first_busno = val[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) pbm->pci_last_busno = val[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) val = of_get_property(pbm->op->dev.of_node, "ino-bitmap", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) pbm->ino_bitmap = (((u64)val[1] << 32UL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ((u64)val[0] << 0UL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static void pci_register_iommu_region(struct pci_pbm_info *pbm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) const u32 *vdma = of_get_property(pbm->op->dev.of_node, "virtual-dma",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (vdma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (!rp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) pr_info("%s: Cannot allocate IOMMU resource.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) pbm->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) rp->name = "IOMMU";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) rp->flags = IORESOURCE_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (request_resource(&pbm->mem_space, rp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pr_info("%s: Unable to request IOMMU resource.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) pbm->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) kfree(rp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) const struct linux_prom_pci_ranges *pbm_ranges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int i, saw_mem, saw_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) int num_pbm_ranges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* Corresponding generic code in of_pci_get_host_bridge_resources() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) saw_mem = saw_io = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) pbm_ranges = of_get_property(pbm->op->dev.of_node, "ranges", &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (!pbm_ranges) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) prom_printf("PCI: Fatal error, missing PBM ranges property "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) " for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) pbm->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) prom_halt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) num_pbm_ranges = i / sizeof(*pbm_ranges);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) memset(&pbm->mem64_space, 0, sizeof(struct resource));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) for (i = 0; i < num_pbm_ranges; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) const struct linux_prom_pci_ranges *pr = &pbm_ranges[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) unsigned long a, size, region_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) u32 parent_phys_hi, parent_phys_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) u32 child_phys_mid, child_phys_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) u32 size_hi, size_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) parent_phys_hi = pr->parent_phys_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) parent_phys_lo = pr->parent_phys_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) child_phys_mid = pr->child_phys_mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) child_phys_lo = pr->child_phys_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (tlb_type == hypervisor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) parent_phys_hi &= 0x0fffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) size_hi = pr->size_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) size_lo = pr->size_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) type = (pr->child_phys_hi >> 24) & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) a = (((unsigned long)parent_phys_hi << 32UL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ((unsigned long)parent_phys_lo << 0UL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) region_a = (((unsigned long)child_phys_mid << 32UL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ((unsigned long)child_phys_lo << 0UL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) size = (((unsigned long)size_hi << 32UL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ((unsigned long)size_lo << 0UL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* PCI config space, 16MB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) pbm->config_space = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* 16-bit IO space, 16MB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) pbm->io_space.start = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) pbm->io_space.end = a + size - 1UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) pbm->io_space.flags = IORESOURCE_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) pbm->io_offset = a - region_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) saw_io = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* 32-bit MEM space, 2GB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) pbm->mem_space.start = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) pbm->mem_space.end = a + size - 1UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) pbm->mem_space.flags = IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) pbm->mem_offset = a - region_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) saw_mem = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* 64-bit MEM handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) pbm->mem64_space.start = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) pbm->mem64_space.end = a + size - 1UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) pbm->mem64_space.flags = IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) pbm->mem64_offset = a - region_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) saw_mem = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (!saw_io || !saw_mem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) prom_printf("%s: Fatal error, missing %s PBM range.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) pbm->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) (!saw_io ? "IO" : "MEM"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) prom_halt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (pbm->io_space.flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) printk("%s: PCI IO %pR offset %llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) pbm->name, &pbm->io_space, pbm->io_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (pbm->mem_space.flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) printk("%s: PCI MEM %pR offset %llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) pbm->name, &pbm->mem_space, pbm->mem_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (pbm->mem64_space.flags && pbm->mem_space.flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (pbm->mem64_space.start <= pbm->mem_space.end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) pbm->mem64_space.start = pbm->mem_space.end + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (pbm->mem64_space.start > pbm->mem64_space.end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) pbm->mem64_space.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (pbm->mem64_space.flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) printk("%s: PCI MEM64 %pR offset %llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) pbm->name, &pbm->mem64_space, pbm->mem64_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) pbm->io_space.name = pbm->mem_space.name = pbm->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) pbm->mem64_space.name = pbm->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) request_resource(&ioport_resource, &pbm->io_space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) request_resource(&iomem_resource, &pbm->mem_space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (pbm->mem64_space.flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) request_resource(&iomem_resource, &pbm->mem64_space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) pci_register_iommu_region(pbm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /* Generic helper routines for PCI error reporting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) void pci_scan_for_target_abort(struct pci_pbm_info *pbm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct pci_bus *pbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct pci_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) list_for_each_entry(pdev, &pbus->devices, bus_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) u16 status, error_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) pci_read_config_word(pdev, PCI_STATUS, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) error_bits =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) (status & (PCI_STATUS_SIG_TARGET_ABORT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) PCI_STATUS_REC_TARGET_ABORT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (error_bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) pci_write_config_word(pdev, PCI_STATUS, error_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) pci_info(pdev, "%s: Device saw Target Abort [%016x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) pbm->name, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) list_for_each_entry(bus, &pbus->children, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) pci_scan_for_target_abort(pbm, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) void pci_scan_for_master_abort(struct pci_pbm_info *pbm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct pci_bus *pbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct pci_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) list_for_each_entry(pdev, &pbus->devices, bus_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) u16 status, error_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) pci_read_config_word(pdev, PCI_STATUS, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) error_bits =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) (status & (PCI_STATUS_REC_MASTER_ABORT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (error_bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) pci_write_config_word(pdev, PCI_STATUS, error_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) pci_info(pdev, "%s: Device received Master Abort "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) "[%016x]\n", pbm->name, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) list_for_each_entry(bus, &pbus->children, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) pci_scan_for_master_abort(pbm, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) void pci_scan_for_parity_error(struct pci_pbm_info *pbm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct pci_bus *pbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct pci_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) list_for_each_entry(pdev, &pbus->devices, bus_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) u16 status, error_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) pci_read_config_word(pdev, PCI_STATUS, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) error_bits =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) (status & (PCI_STATUS_PARITY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) PCI_STATUS_DETECTED_PARITY));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (error_bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) pci_write_config_word(pdev, PCI_STATUS, error_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) pci_info(pdev, "%s: Device saw Parity Error [%016x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) pbm->name, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) list_for_each_entry(bus, &pbus->children, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) pci_scan_for_parity_error(pbm, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }