xref: /openbmc/u-boot/drivers/pci/pcie_aspeed.c (revision d6f57adb772ff60825daa5774acd62ea5916cf15)
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