1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <pci.h> 9 #include <asm/io.h> 10 #include <asm/arch/h2x_ast2600.h> 11 #include <asm/arch/ahbc_aspeed.h> 12 13 DECLARE_GLOBAL_DATA_PTR; 14 15 /* PCI Host Controller registers */ 16 17 #define ASPEED_PCIE_CLASS_CODE 0x04 18 #define ASPEED_PCIE_GLOBAL 0x30 19 #define ASPEED_PCIE_CFG_DIN 0x50 20 #define ASPEED_PCIE_CFG3 0x58 21 #define ASPEED_PCIE_LOCK 0x7C 22 23 #define ASPEED_PCIE_LINK 0xC0 24 #define ASPEED_PCIE_INT 0xC4 25 26 /* AST_PCIE_CFG2 0x04 */ 27 #define PCIE_CFG_CLASS_CODE(x) (x << 8) 28 #define PCIE_CFG_REV_ID(x) (x) 29 30 /* AST_PCIE_GLOBAL 0x30 */ 31 #define ROOT_COMPLEX_ID(x) (x << 4) 32 33 /* AST_PCIE_LOCK 0x7C */ 34 #define PCIE_UNLOCK 0xa8 35 36 /* AST_PCIE_LINK 0xC0 */ 37 #define PCIE_LINK_STS BIT(5) 38 39 struct pcie_aspeed { 40 void *ctrl_base; 41 void *h2x_pt; 42 void *cfg_base; 43 fdt_size_t cfg_size; 44 45 int first_busno; 46 47 /* IO and MEM PCI regions */ 48 struct pci_region io; 49 struct pci_region mem; 50 }; 51 52 static int pcie_addr_valid(pci_dev_t d, int first_busno) 53 { 54 #if 0 55 if ((PCI_BUS(d) == first_busno) && (PCI_DEV(d) > 0)) 56 return 0; 57 if ((PCI_BUS(d) == first_busno + 1) && (PCI_DEV(d) > 0)) 58 return 0; 59 #endif 60 return 1; 61 } 62 63 static int pcie_aspeed_read_config(struct udevice *bus, pci_dev_t bdf, 64 uint offset, ulong *valuep, 65 enum pci_size_t size) 66 { 67 struct pcie_aspeed *pcie = dev_get_priv(bus); 68 69 debug("PCIE CFG read: (b,d,f)=(%2d,%2d,%2d) ", 70 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); 71 72 if (!pcie_addr_valid(bdf, pcie->first_busno)) { 73 printf("- out of range\n"); 74 *valuep = pci_get_ff(size); 75 return 0; 76 } 77 78 aspeed_pcie_cfg_read(pcie->h2x_pt, bdf, offset, valuep); 79 80 debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, *valuep); 81 *valuep = pci_conv_32_to_size(*valuep, offset, size); 82 83 return 0; 84 } 85 86 static int pcie_aspeed_write_config(struct udevice *bus, pci_dev_t bdf, 87 uint offset, ulong value, 88 enum pci_size_t size) 89 { 90 struct pcie_aspeed *pcie = dev_get_priv(bus); 91 92 debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ", 93 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); 94 debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); 95 96 if (!pcie_addr_valid(bdf, pcie->first_busno)) { 97 debug("- out of range\n"); 98 return 0; 99 } 100 101 aspeed_pcie_cfg_write(pcie->h2x_pt, bdf, offset, value, size); 102 103 return 0; 104 } 105 106 static int pcie_aspeed_probe(struct udevice *dev) 107 { 108 struct pcie_aspeed *pcie = dev_get_priv(dev); 109 struct udevice *ctlr = pci_get_controller(dev); 110 struct pci_controller *hose = dev_get_uclass_priv(ctlr); 111 struct udevice *ahbc_dev, *h2x_dev; 112 int ret = 0; 113 114 ret = uclass_get_device_by_driver(UCLASS_MISC, DM_GET_DRIVER(aspeed_ahbc), 115 &ahbc_dev); 116 if (ret) { 117 debug("ahbc device not defined\n"); 118 return ret; 119 } 120 121 ret = uclass_get_device_by_driver(UCLASS_MISC, DM_GET_DRIVER(aspeed_h2x), 122 &h2x_dev); 123 if (ret) { 124 debug("h2x device not defined\n"); 125 return ret; 126 } 127 128 pcie->h2x_pt = devfdt_get_addr_ptr(h2x_dev); 129 130 aspeed_ahbc_remap_enable(devfdt_get_addr_ptr(ahbc_dev)); 131 132 //plda enable 133 writel(PCIE_UNLOCK, pcie->ctrl_base + ASPEED_PCIE_LOCK); 134 writel(PCIE_CFG_CLASS_CODE(0x60000) | PCIE_CFG_REV_ID(4), pcie->ctrl_base + ASPEED_PCIE_CLASS_CODE); 135 writel(ROOT_COMPLEX_ID(0x3), pcie->ctrl_base + ASPEED_PCIE_GLOBAL); 136 #if 0 137 //fpga 138 writel(0x500460ff, pcie->ctrl_base + 0x2c); 139 #endif 140 141 pcie->first_busno = dev->seq; 142 143 /* Don't register host if link is down */ 144 if (readl(pcie->ctrl_base + ASPEED_PCIE_LINK) & PCIE_LINK_STS) { 145 printf("PCIE-%d: Link up\n", dev->seq); 146 } else { 147 printf("PCIE-%d: Link down\n", dev->seq); 148 } 149 150 /* Store the IO and MEM windows settings for future use by the ATU */ 151 pcie->io.phys_start = hose->regions[0].phys_start; /* IO base */ 152 pcie->io.bus_start = hose->regions[0].bus_start; /* IO_bus_addr */ 153 pcie->io.size = hose->regions[0].size; /* IO size */ 154 155 pcie->mem.phys_start = hose->regions[1].phys_start; /* MEM base */ 156 pcie->mem.bus_start = hose->regions[1].bus_start; /* MEM_bus_addr */ 157 pcie->mem.size = hose->regions[1].size; /* MEM size */ 158 159 return 0; 160 } 161 162 static int pcie_aspeed_ofdata_to_platdata(struct udevice *dev) 163 { 164 struct pcie_aspeed *pcie = dev_get_priv(dev); 165 166 /* Get the controller base address */ 167 pcie->ctrl_base = (void *)devfdt_get_addr_index(dev, 0); 168 169 /* Get the config space base address and size */ 170 pcie->cfg_base = (void *)devfdt_get_addr_size_index(dev, 1, 171 &pcie->cfg_size); 172 173 return 0; 174 } 175 176 static const struct dm_pci_ops pcie_aspeed_ops = { 177 .read_config = pcie_aspeed_read_config, 178 .write_config = pcie_aspeed_write_config, 179 }; 180 181 static const struct udevice_id pcie_aspeed_ids[] = { 182 { .compatible = "aspeed,ast2600-pcie" }, 183 { } 184 }; 185 186 U_BOOT_DRIVER(pcie_aspeed) = { 187 .name = "pcie_aspeed", 188 .id = UCLASS_PCI, 189 .of_match = pcie_aspeed_ids, 190 .ops = &pcie_aspeed_ops, 191 .ofdata_to_platdata = pcie_aspeed_ofdata_to_platdata, 192 .probe = pcie_aspeed_probe, 193 .priv_auto_alloc_size = sizeof(struct pcie_aspeed), 194 }; 195