1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2021 BayLibre, SAS
4  * Author: Neil Armstrong <narmstrong@baylibre.com>
5  *
6  * Copyright (c) 2021 Rockchip, Inc.
7  *
8  * Copyright (C) 2018 Texas Instruments, Inc
9  */
10 
11 #include <common.h>
12 #include <dm.h>
13 #include <log.h>
14 #include <pci.h>
15 #include <dm/device_compat.h>
16 #include <asm/io.h>
17 #include <linux/delay.h>
18 #include "pcie_dw_common.h"
19 
pcie_dw_get_link_speed(struct pcie_dw * pci)20 int pcie_dw_get_link_speed(struct pcie_dw *pci)
21 {
22 	return (readl(pci->dbi_base + PCIE_LINK_STATUS_REG) &
23 		PCIE_LINK_STATUS_SPEED_MASK) >> PCIE_LINK_STATUS_SPEED_OFF;
24 }
25 
pcie_dw_get_link_width(struct pcie_dw * pci)26 int pcie_dw_get_link_width(struct pcie_dw *pci)
27 {
28 	return (readl(pci->dbi_base + PCIE_LINK_STATUS_REG) &
29 		PCIE_LINK_STATUS_WIDTH_MASK) >> PCIE_LINK_STATUS_WIDTH_OFF;
30 }
31 
dw_pcie_writel_ob_unroll(struct pcie_dw * pci,u32 index,u32 reg,u32 val)32 static void dw_pcie_writel_ob_unroll(struct pcie_dw *pci, u32 index, u32 reg,
33 				     u32 val)
34 {
35 	u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
36 	void __iomem *base = pci->atu_base;
37 
38 	writel(val, base + offset + reg);
39 }
40 
dw_pcie_readl_ob_unroll(struct pcie_dw * pci,u32 index,u32 reg)41 static u32 dw_pcie_readl_ob_unroll(struct pcie_dw *pci, u32 index, u32 reg)
42 {
43 	u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
44 	void __iomem *base = pci->atu_base;
45 
46 	return readl(base + offset + reg);
47 }
48 
49 /**
50  * pcie_dw_prog_outbound_atu_unroll() - Configure ATU for outbound accesses
51  *
52  * @pcie: Pointer to the PCI controller state
53  * @index: ATU region index
54  * @type: ATU accsess type
55  * @cpu_addr: the physical address for the translation entry
56  * @pci_addr: the pcie bus address for the translation entry
57  * @size: the size of the translation entry
58  *
59  * Return: 0 is successful and -1 is failure
60  */
pcie_dw_prog_outbound_atu_unroll(struct pcie_dw * pci,int index,int type,u64 cpu_addr,u64 pci_addr,u32 size)61 int pcie_dw_prog_outbound_atu_unroll(struct pcie_dw *pci, int index,
62 				     int type, u64 cpu_addr,
63 					     u64 pci_addr, u32 size)
64 {
65 	u32 retries, val;
66 
67 	dev_dbg(pci->dev, "ATU programmed with: index: %d, type: %d, cpu addr: %8llx, pci addr: %8llx, size: %8x\n",
68 		index, type, cpu_addr, pci_addr, size);
69 
70 	dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_BASE,
71 				 lower_32_bits(cpu_addr));
72 	dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_BASE,
73 				 upper_32_bits(cpu_addr));
74 	dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LIMIT,
75 				 lower_32_bits(cpu_addr + size - 1));
76 	dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_TARGET,
77 				 lower_32_bits(pci_addr));
78 	dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET,
79 				 upper_32_bits(pci_addr));
80 	dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1,
81 				 type);
82 	dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
83 				 PCIE_ATU_ENABLE);
84 
85 	/*
86 	 * Make sure ATU enable takes effect before any subsequent config
87 	 * and I/O accesses.
88 	 */
89 	for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
90 		val = dw_pcie_readl_ob_unroll(pci, index,
91 					      PCIE_ATU_UNR_REGION_CTRL2);
92 		if (val & PCIE_ATU_ENABLE)
93 			return 0;
94 
95 		udelay(LINK_WAIT_IATU);
96 	}
97 	dev_err(pci->dev, "outbound iATU is not being enabled\n");
98 
99 	return -1;
100 }
101 
102 /**
103  * set_cfg_address() - Configure the PCIe controller config space access
104  *
105  * @pcie: Pointer to the PCI controller state
106  * @d: PCI device to access
107  * @where: Offset in the configuration space
108  *
109  * Configures the PCIe controller to access the configuration space of
110  * a specific PCIe device and returns the address to use for this
111  * access.
112  *
113  * Return: Address that can be used to access the configation space
114  *         of the requested device / offset
115  */
set_cfg_address(struct pcie_dw * pcie,pci_dev_t d,uint where)116 static uintptr_t set_cfg_address(struct pcie_dw *pcie,
117 				 pci_dev_t d, uint where)
118 {
119 	int bus = PCI_BUS(d) - pcie->first_busno;
120 	uintptr_t va_address;
121 	u32 atu_type;
122 	int ret;
123 
124 	/* Use dbi_base for own configuration read and write */
125 	if (!bus) {
126 		va_address = (uintptr_t)pcie->dbi_base;
127 		goto out;
128 	}
129 
130 	if (bus == 1)
131 		/*
132 		 * For local bus whose primary bus number is root bridge,
133 		 * change TLP Type field to 4.
134 		 */
135 		atu_type = PCIE_ATU_TYPE_CFG0;
136 	else
137 		/* Otherwise, change TLP Type field to 5. */
138 		atu_type = PCIE_ATU_TYPE_CFG1;
139 
140 	/*
141 	 * Not accessing root port configuration space?
142 	 * Region #0 is used for Outbound CFG space access.
143 	 * Direction = Outbound
144 	 * Region Index = 0
145 	 */
146 	d = PCI_MASK_BUS(d);
147 	d = PCI_ADD_BUS(bus, d);
148 	ret = pcie_dw_prog_outbound_atu_unroll(pcie, PCIE_ATU_REGION_INDEX1,
149 					       atu_type, (u64)pcie->cfg_base,
150 						d << 8, pcie->cfg_size);
151 	if (ret)
152 		return (uintptr_t)ret;
153 
154 	va_address = (uintptr_t)pcie->cfg_base;
155 
156 out:
157 	va_address += where & ~0x3;
158 
159 	return va_address;
160 }
161 
162 /**
163  * pcie_dw_addr_valid() - Check for valid bus address
164  *
165  * @d: The PCI device to access
166  * @first_busno: Bus number of the PCIe controller root complex
167  *
168  * Return 1 (true) if the PCI device can be accessed by this controller.
169  *
170  * Return: 1 on valid, 0 on invalid
171  */
pcie_dw_addr_valid(pci_dev_t d,int first_busno)172 static int pcie_dw_addr_valid(pci_dev_t d, int first_busno)
173 {
174 	if ((PCI_BUS(d) == first_busno) && (PCI_DEV(d) > 0))
175 		return 0;
176 	if ((PCI_BUS(d) == first_busno + 1) && (PCI_DEV(d) > 0))
177 		return 0;
178 
179 	return 1;
180 }
181 
182 /**
183  * pcie_dw_read_config() - Read from configuration space
184  *
185  * @bus: Pointer to the PCI bus
186  * @bdf: Identifies the PCIe device to access
187  * @offset: The offset into the device's configuration space
188  * @valuep: A pointer at which to store the read value
189  * @size: Indicates the size of access to perform
190  *
191  * Read a value of size @size from offset @offset within the configuration
192  * space of the device identified by the bus, device & function numbers in @bdf
193  * on the PCI bus @bus.
194  *
195  * Return: 0 on success
196  */
pcie_dw_read_config(const struct udevice * bus,pci_dev_t bdf,uint offset,ulong * valuep,enum pci_size_t size)197 int pcie_dw_read_config(const struct udevice *bus, pci_dev_t bdf,
198 			uint offset, ulong *valuep,
199 			enum pci_size_t size)
200 {
201 	struct pcie_dw *pcie = dev_get_priv(bus);
202 	uintptr_t va_address;
203 	ulong value;
204 
205 	dev_dbg(pcie->dev, "PCIE CFG read: bdf=%2x:%2x:%2x ",
206 		PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
207 
208 	if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) {
209 		debug("- out of range\n");
210 		*valuep = pci_get_ff(size);
211 		return 0;
212 	}
213 
214 	va_address = set_cfg_address(pcie, bdf, offset);
215 
216 	value = readl((void __iomem *)va_address);
217 
218 	debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
219 	*valuep = pci_conv_32_to_size(value, offset, size);
220 
221 	return pcie_dw_prog_outbound_atu_unroll(pcie, PCIE_ATU_REGION_INDEX1,
222 						 PCIE_ATU_TYPE_IO, pcie->io.phys_start,
223 						 pcie->io.bus_start, pcie->io.size);
224 }
225 
226 /**
227  * pcie_dw_write_config() - Write to configuration space
228  *
229  * @bus: Pointer to the PCI bus
230  * @bdf: Identifies the PCIe device to access
231  * @offset: The offset into the device's configuration space
232  * @value: The value to write
233  * @size: Indicates the size of access to perform
234  *
235  * Write the value @value of size @size from offset @offset within the
236  * configuration space of the device identified by the bus, device & function
237  * numbers in @bdf on the PCI bus @bus.
238  *
239  * Return: 0 on success
240  */
pcie_dw_write_config(struct udevice * bus,pci_dev_t bdf,uint offset,ulong value,enum pci_size_t size)241 int pcie_dw_write_config(struct udevice *bus, pci_dev_t bdf,
242 			 uint offset, ulong value,
243 			 enum pci_size_t size)
244 {
245 	struct pcie_dw *pcie = dev_get_priv(bus);
246 	uintptr_t va_address;
247 	ulong old;
248 
249 	dev_dbg(pcie->dev, "PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
250 		PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
251 	dev_dbg(pcie->dev, "(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
252 
253 	if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) {
254 		debug("- out of range\n");
255 		return 0;
256 	}
257 
258 	va_address = set_cfg_address(pcie, bdf, offset);
259 
260 	old = readl((void __iomem *)va_address);
261 	value = pci_conv_size_to_32(old, value, offset, size);
262 	writel(value, (void __iomem *)va_address);
263 
264 	return pcie_dw_prog_outbound_atu_unroll(pcie, PCIE_ATU_REGION_INDEX1,
265 						 PCIE_ATU_TYPE_IO, pcie->io.phys_start,
266 						 pcie->io.bus_start, pcie->io.size);
267 }
268 
269 /**
270  * pcie_dw_setup_host() - Setup the PCIe controller for RC opertaion
271  *
272  * @pcie: Pointer to the PCI controller state
273  *
274  * Configure the host BARs of the PCIe controller root port so that
275  * PCI(e) devices may access the system memory.
276  */
pcie_dw_setup_host(struct pcie_dw * pci)277 void pcie_dw_setup_host(struct pcie_dw *pci)
278 {
279 	struct udevice *ctlr = pci_get_controller(pci->dev);
280 	struct pci_controller *hose = dev_get_uclass_priv(ctlr);
281 	u32 ret;
282 
283 	if (!pci->atu_base)
284 		pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
285 
286 	/* setup RC BARs */
287 	writel(PCI_BASE_ADDRESS_MEM_TYPE_64,
288 	       pci->dbi_base + PCI_BASE_ADDRESS_0);
289 	writel(0x0, pci->dbi_base + PCI_BASE_ADDRESS_1);
290 
291 	/* setup interrupt pins */
292 	clrsetbits_le32(pci->dbi_base + PCI_INTERRUPT_LINE,
293 			0xff00, 0x100);
294 
295 	/* setup bus numbers */
296 	clrsetbits_le32(pci->dbi_base + PCI_PRIMARY_BUS,
297 			0xffffff, 0x00ff0100);
298 
299 	/* setup command register */
300 	clrsetbits_le32(pci->dbi_base + PCI_PRIMARY_BUS,
301 			0xffff,
302 			PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
303 			PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
304 
305 	/* Enable write permission for the DBI read-only register */
306 	dw_pcie_dbi_write_enable(pci, true);
307 	/* program correct class for RC */
308 	writew(PCI_CLASS_BRIDGE_PCI, pci->dbi_base + PCI_CLASS_DEVICE);
309 	/* Better disable write permission right after the update */
310 	dw_pcie_dbi_write_enable(pci, false);
311 
312 	setbits_le32(pci->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL,
313 		     PORT_LOGIC_SPEED_CHANGE);
314 
315 	for (ret = 0; ret < hose->region_count; ret++) {
316 		if (hose->regions[ret].flags == PCI_REGION_IO) {
317 			pci->io.phys_start = hose->regions[ret].phys_start; /* IO base */
318 			pci->io.bus_start = hose->regions[ret].bus_start;  /* IO_bus_addr */
319 			pci->io.size = hose->regions[ret].size;      /* IO size */
320 		} else if (hose->regions[ret].flags == PCI_REGION_MEM) {
321 			pci->mem.phys_start = hose->regions[ret].phys_start; /* MEM base */
322 			pci->mem.bus_start = hose->regions[ret].bus_start;  /* MEM_bus_addr */
323 			pci->mem.size = hose->regions[ret].size;	    /* MEM size */
324 		} else if (hose->regions[ret].flags == PCI_REGION_PREFETCH) {
325 			pci->prefetch.phys_start = hose->regions[ret].phys_start; /* PREFETCH base */
326 			pci->prefetch.bus_start = hose->regions[ret].bus_start;  /* PREFETCH_bus_addr */
327 			pci->prefetch.size = hose->regions[ret].size;	    /* PREFETCH size */
328 		} else if (hose->regions[ret].flags == PCI_REGION_SYS_MEMORY) {
329 			pci->cfg_base = (void *)(pci->io.phys_start - pci->io.size);
330 			pci->cfg_size = pci->io.size;
331 		} else {
332 			dev_err(pci->dev, "invalid flags type!\n");
333 		}
334 	}
335 
336 	dev_dbg(pci->dev, "Config space: [0x%llx - 0x%llx, size 0x%llx]\n",
337 		(u64)pci->cfg_base, (u64)pci->cfg_base + pci->cfg_size,
338 		(u64)pci->cfg_size);
339 
340 	dev_dbg(pci->dev, "IO space: [0x%llx - 0x%llx, size 0x%llx]\n",
341 		(u64)pci->io.phys_start, (u64)pci->io.phys_start + pci->io.size,
342 		(u64)pci->io.size);
343 
344 	dev_dbg(pci->dev, "IO bus:   [0x%llx - 0x%llx, size 0x%llx]\n",
345 		(u64)pci->io.bus_start,	(u64)pci->io.bus_start + pci->io.size,
346 		(u64)pci->io.size);
347 
348 	dev_dbg(pci->dev, "MEM space: [0x%llx - 0x%llx, size 0x%llx]\n",
349 		(u64)pci->mem.phys_start,
350 		(u64)pci->mem.phys_start + pci->mem.size,
351 		(u64)pci->mem.size);
352 
353 	dev_dbg(pci->dev, "MEM bus:   [0x%llx - 0x%llx, size 0x%llx]\n",
354 		(u64)pci->mem.bus_start,
355 		(u64)pci->mem.bus_start + pci->mem.size,
356 		(u64)pci->mem.size);
357 
358 	if (pci->prefetch.size) {
359 		dev_dbg(pci->dev, "PREFETCH space: [0x%llx - 0x%llx, size 0x%llx]\n",
360 			(u64)pci->prefetch.phys_start,
361 			(u64)pci->prefetch.phys_start + pci->prefetch.size,
362 			(u64)pci->prefetch.size);
363 
364 		dev_dbg(pci->dev, "PREFETCH bus:   [0x%llx - 0x%llx, size 0x%llx]\n",
365 			(u64)pci->prefetch.bus_start,
366 			(u64)pci->prefetch.bus_start + pci->prefetch.size,
367 			(u64)pci->prefetch.size);
368 	}
369 }
370