1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4 */ 5 #include <linux/pci.h> 6 #include <linux/acpi.h> 7 #include <linux/init.h> 8 #include <linux/irq.h> 9 #include <linux/slab.h> 10 #include <linux/pci-acpi.h> 11 #include <linux/pci-ecam.h> 12 13 #include <asm/pci.h> 14 #include <asm/numa.h> 15 #include <asm/loongson.h> 16 17 struct pci_root_info { 18 struct acpi_pci_root_info common; 19 struct pci_config_window *cfg; 20 }; 21 22 void pcibios_add_bus(struct pci_bus *bus) 23 { 24 acpi_pci_add_bus(bus); 25 } 26 27 int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) 28 { 29 struct acpi_device *adev = NULL; 30 struct device *bus_dev = &bridge->bus->dev; 31 struct pci_config_window *cfg = bridge->bus->sysdata; 32 33 if (!acpi_disabled) 34 adev = to_acpi_device(cfg->parent); 35 36 ACPI_COMPANION_SET(&bridge->dev, adev); 37 set_dev_node(bus_dev, pa_to_nid(cfg->res.start)); 38 39 return 0; 40 } 41 42 int acpi_pci_bus_find_domain_nr(struct pci_bus *bus) 43 { 44 struct pci_config_window *cfg = bus->sysdata; 45 struct acpi_device *adev = to_acpi_device(cfg->parent); 46 struct acpi_pci_root *root = acpi_driver_data(adev); 47 48 return root->segment; 49 } 50 51 static void acpi_release_root_info(struct acpi_pci_root_info *ci) 52 { 53 struct pci_root_info *info; 54 55 info = container_of(ci, struct pci_root_info, common); 56 pci_ecam_free(info->cfg); 57 kfree(ci->ops); 58 kfree(info); 59 } 60 61 static int acpi_prepare_root_resources(struct acpi_pci_root_info *ci) 62 { 63 int status; 64 struct resource_entry *entry, *tmp; 65 struct acpi_device *device = ci->bridge; 66 67 status = acpi_pci_probe_root_resources(ci); 68 if (status > 0) { 69 resource_list_for_each_entry_safe(entry, tmp, &ci->resources) { 70 if (entry->res->flags & IORESOURCE_MEM) { 71 entry->offset = ci->root->mcfg_addr & GENMASK_ULL(63, 40); 72 entry->res->start |= entry->offset; 73 entry->res->end |= entry->offset; 74 } 75 } 76 return status; 77 } 78 79 resource_list_for_each_entry_safe(entry, tmp, &ci->resources) { 80 dev_dbg(&device->dev, 81 "host bridge window %pR (ignored)\n", entry->res); 82 resource_list_destroy_entry(entry); 83 } 84 85 return 0; 86 } 87 88 /* 89 * Create a PCI config space window 90 * - reserve mem region 91 * - alloc struct pci_config_window with space for all mappings 92 * - ioremap the config space 93 */ 94 static struct pci_config_window *arch_pci_ecam_create(struct device *dev, 95 struct resource *cfgres, struct resource *busr, const struct pci_ecam_ops *ops) 96 { 97 int bsz, bus_range, err; 98 struct resource *conflict; 99 struct pci_config_window *cfg; 100 101 if (busr->start > busr->end) 102 return ERR_PTR(-EINVAL); 103 104 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); 105 if (!cfg) 106 return ERR_PTR(-ENOMEM); 107 108 cfg->parent = dev; 109 cfg->ops = ops; 110 cfg->busr.start = busr->start; 111 cfg->busr.end = busr->end; 112 cfg->busr.flags = IORESOURCE_BUS; 113 bus_range = resource_size(cfgres) >> ops->bus_shift; 114 115 bsz = 1 << ops->bus_shift; 116 117 cfg->res.start = cfgres->start; 118 cfg->res.end = cfgres->end; 119 cfg->res.flags = IORESOURCE_MEM | IORESOURCE_BUSY; 120 cfg->res.name = "PCI ECAM"; 121 122 conflict = request_resource_conflict(&iomem_resource, &cfg->res); 123 if (conflict) { 124 err = -EBUSY; 125 dev_err(dev, "can't claim ECAM area %pR: address conflict with %s %pR\n", 126 &cfg->res, conflict->name, conflict); 127 goto err_exit; 128 } 129 130 cfg->win = pci_remap_cfgspace(cfgres->start, bus_range * bsz); 131 if (!cfg->win) 132 goto err_exit_iomap; 133 134 if (ops->init) { 135 err = ops->init(cfg); 136 if (err) 137 goto err_exit; 138 } 139 dev_info(dev, "ECAM at %pR for %pR\n", &cfg->res, &cfg->busr); 140 141 return cfg; 142 143 err_exit_iomap: 144 err = -ENOMEM; 145 dev_err(dev, "ECAM ioremap failed\n"); 146 err_exit: 147 pci_ecam_free(cfg); 148 return ERR_PTR(err); 149 } 150 151 /* 152 * Lookup the bus range for the domain in MCFG, and set up config space 153 * mapping. 154 */ 155 static struct pci_config_window * 156 pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) 157 { 158 int ret, bus_shift; 159 u16 seg = root->segment; 160 struct device *dev = &root->device->dev; 161 struct resource cfgres; 162 struct resource *bus_res = &root->secondary; 163 struct pci_config_window *cfg; 164 const struct pci_ecam_ops *ecam_ops; 165 166 ret = pci_mcfg_lookup(root, &cfgres, &ecam_ops); 167 if (ret < 0) { 168 dev_err(dev, "%04x:%pR ECAM region not found, use default value\n", seg, bus_res); 169 ecam_ops = &loongson_pci_ecam_ops; 170 root->mcfg_addr = mcfg_addr_init(0); 171 } 172 173 bus_shift = ecam_ops->bus_shift ? : 20; 174 175 if (bus_shift == 20) 176 cfg = pci_ecam_create(dev, &cfgres, bus_res, ecam_ops); 177 else { 178 cfgres.start = root->mcfg_addr + (bus_res->start << bus_shift); 179 cfgres.end = cfgres.start + (resource_size(bus_res) << bus_shift) - 1; 180 cfgres.end |= BIT(28) + (((PCI_CFG_SPACE_EXP_SIZE - 1) & 0xf00) << 16); 181 cfgres.flags = IORESOURCE_MEM; 182 cfg = arch_pci_ecam_create(dev, &cfgres, bus_res, ecam_ops); 183 } 184 185 if (IS_ERR(cfg)) { 186 dev_err(dev, "%04x:%pR error %ld mapping ECAM\n", seg, bus_res, PTR_ERR(cfg)); 187 return NULL; 188 } 189 190 return cfg; 191 } 192 193 struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) 194 { 195 struct pci_bus *bus; 196 struct pci_root_info *info; 197 struct acpi_pci_root_ops *root_ops; 198 int domain = root->segment; 199 int busnum = root->secondary.start; 200 201 info = kzalloc(sizeof(*info), GFP_KERNEL); 202 if (!info) { 203 pr_warn("pci_bus %04x:%02x: ignored (out of memory)\n", domain, busnum); 204 return NULL; 205 } 206 207 root_ops = kzalloc(sizeof(*root_ops), GFP_KERNEL); 208 if (!root_ops) { 209 kfree(info); 210 return NULL; 211 } 212 213 info->cfg = pci_acpi_setup_ecam_mapping(root); 214 if (!info->cfg) { 215 kfree(info); 216 kfree(root_ops); 217 return NULL; 218 } 219 220 root_ops->release_info = acpi_release_root_info; 221 root_ops->prepare_resources = acpi_prepare_root_resources; 222 root_ops->pci_ops = (struct pci_ops *)&info->cfg->ops->pci_ops; 223 224 bus = pci_find_bus(domain, busnum); 225 if (bus) { 226 memcpy(bus->sysdata, info->cfg, sizeof(struct pci_config_window)); 227 kfree(info); 228 } else { 229 struct pci_bus *child; 230 231 bus = acpi_pci_root_create(root, root_ops, 232 &info->common, info->cfg); 233 if (!bus) { 234 kfree(info); 235 kfree(root_ops); 236 return NULL; 237 } 238 239 pci_bus_size_bridges(bus); 240 pci_bus_assign_resources(bus); 241 list_for_each_entry(child, &bus->children, node) 242 pcie_bus_configure_settings(child); 243 } 244 245 return bus; 246 } 247