1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Cardbus bridge setup routines. 4 */ 5 6 #include <linux/ioport.h> 7 #include <linux/pci.h> 8 #include <linux/types.h> 9 10 #include "pci.h" 11 12 unsigned long pci_cardbus_resource_alignment(struct resource *res) 13 { 14 if (res->flags & IORESOURCE_IO) 15 return pci_cardbus_io_size; 16 if (res->flags & IORESOURCE_MEM) 17 return pci_cardbus_mem_size; 18 return 0; 19 } 20 21 int pci_bus_size_cardbus_bridge(struct pci_bus *bus, 22 struct list_head *realloc_head) 23 { 24 struct pci_dev *bridge = bus->self; 25 struct resource *b_res; 26 resource_size_t b_res_3_size = pci_cardbus_mem_size * 2; 27 u16 ctrl; 28 29 b_res = &bridge->resource[PCI_CB_BRIDGE_IO_0_WINDOW]; 30 if (resource_assigned(b_res)) 31 goto handle_b_res_1; 32 /* 33 * Reserve some resources for CardBus. We reserve a fixed amount 34 * of bus space for CardBus bridges. 35 */ 36 resource_set_range(b_res, pci_cardbus_io_size, pci_cardbus_io_size); 37 b_res->flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN; 38 if (realloc_head) { 39 b_res->end -= pci_cardbus_io_size; 40 pci_dev_res_add_to_list(realloc_head, bridge, b_res, 41 pci_cardbus_io_size, 42 pci_cardbus_io_size); 43 } 44 45 handle_b_res_1: 46 b_res = &bridge->resource[PCI_CB_BRIDGE_IO_1_WINDOW]; 47 if (resource_assigned(b_res)) 48 goto handle_b_res_2; 49 resource_set_range(b_res, pci_cardbus_io_size, pci_cardbus_io_size); 50 b_res->flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN; 51 if (realloc_head) { 52 b_res->end -= pci_cardbus_io_size; 53 pci_dev_res_add_to_list(realloc_head, bridge, b_res, 54 pci_cardbus_io_size, 55 pci_cardbus_io_size); 56 } 57 58 handle_b_res_2: 59 /* MEM1 must not be pref MMIO */ 60 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); 61 if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM1) { 62 ctrl &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1; 63 pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl); 64 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); 65 } 66 67 /* Check whether prefetchable memory is supported by this bridge. */ 68 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); 69 if (!(ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0)) { 70 ctrl |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0; 71 pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl); 72 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); 73 } 74 75 b_res = &bridge->resource[PCI_CB_BRIDGE_MEM_0_WINDOW]; 76 if (resource_assigned(b_res)) 77 goto handle_b_res_3; 78 /* 79 * If we have prefetchable memory support, allocate two regions. 80 * Otherwise, allocate one region of twice the size. 81 */ 82 if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { 83 resource_set_range(b_res, pci_cardbus_mem_size, 84 pci_cardbus_mem_size); 85 b_res->flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | 86 IORESOURCE_STARTALIGN; 87 if (realloc_head) { 88 b_res->end -= pci_cardbus_mem_size; 89 pci_dev_res_add_to_list(realloc_head, bridge, b_res, 90 pci_cardbus_mem_size, 91 pci_cardbus_mem_size); 92 } 93 94 /* Reduce that to half */ 95 b_res_3_size = pci_cardbus_mem_size; 96 } 97 98 handle_b_res_3: 99 b_res = &bridge->resource[PCI_CB_BRIDGE_MEM_1_WINDOW]; 100 if (resource_assigned(b_res)) 101 goto handle_done; 102 resource_set_range(b_res, pci_cardbus_mem_size, b_res_3_size); 103 b_res->flags |= IORESOURCE_MEM | IORESOURCE_STARTALIGN; 104 if (realloc_head) { 105 b_res->end -= b_res_3_size; 106 pci_dev_res_add_to_list(realloc_head, bridge, b_res, 107 b_res_3_size, pci_cardbus_mem_size); 108 } 109 110 handle_done: 111 return 0; 112 } 113 114 void pci_setup_cardbus_bridge(struct pci_bus *bus) 115 { 116 struct pci_dev *bridge = bus->self; 117 struct resource *res; 118 struct pci_bus_region region; 119 120 pci_info(bridge, "CardBus bridge to %pR\n", 121 &bus->busn_res); 122 123 res = bus->resource[0]; 124 pcibios_resource_to_bus(bridge->bus, ®ion, res); 125 if (resource_assigned(res) && res->flags & IORESOURCE_IO) { 126 /* 127 * The IO resource is allocated a range twice as large as it 128 * would normally need. This allows us to set both IO regs. 129 */ 130 pci_info(bridge, " bridge window %pR\n", res); 131 pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, 132 region.start); 133 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, 134 region.end); 135 } 136 137 res = bus->resource[1]; 138 pcibios_resource_to_bus(bridge->bus, ®ion, res); 139 if (resource_assigned(res) && res->flags & IORESOURCE_IO) { 140 pci_info(bridge, " bridge window %pR\n", res); 141 pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, 142 region.start); 143 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, 144 region.end); 145 } 146 147 res = bus->resource[2]; 148 pcibios_resource_to_bus(bridge->bus, ®ion, res); 149 if (resource_assigned(res) && res->flags & IORESOURCE_MEM) { 150 pci_info(bridge, " bridge window %pR\n", res); 151 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, 152 region.start); 153 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, 154 region.end); 155 } 156 157 res = bus->resource[3]; 158 pcibios_resource_to_bus(bridge->bus, ®ion, res); 159 if (resource_assigned(res) && res->flags & IORESOURCE_MEM) { 160 pci_info(bridge, " bridge window %pR\n", res); 161 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, 162 region.start); 163 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, 164 region.end); 165 } 166 } 167 EXPORT_SYMBOL(pci_setup_cardbus_bridge); 168