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