Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

Apr 14-17, 2025
Register
Loading...
Note: File does not exist in v3.5.6.
  1// SPDX-License-Identifier: GPL-2.0
  2/**
  3 * Synopsys DesignWare PCIe Endpoint controller driver
  4 *
  5 * Copyright (C) 2017 Texas Instruments
  6 * Author: Kishon Vijay Abraham I <kishon@ti.com>
  7 */
  8
  9#include <linux/of.h>
 10
 11#include "pcie-designware.h"
 12#include <linux/pci-epc.h>
 13#include <linux/pci-epf.h>
 14
 15void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
 16{
 17	struct pci_epc *epc = ep->epc;
 18
 19	pci_epc_linkup(epc);
 20}
 21
 22static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar,
 23				   int flags)
 24{
 25	u32 reg;
 26
 27	reg = PCI_BASE_ADDRESS_0 + (4 * bar);
 28	dw_pcie_dbi_ro_wr_en(pci);
 29	dw_pcie_writel_dbi2(pci, reg, 0x0);
 30	dw_pcie_writel_dbi(pci, reg, 0x0);
 31	if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) {
 32		dw_pcie_writel_dbi2(pci, reg + 4, 0x0);
 33		dw_pcie_writel_dbi(pci, reg + 4, 0x0);
 34	}
 35	dw_pcie_dbi_ro_wr_dis(pci);
 36}
 37
 38void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
 39{
 40	__dw_pcie_ep_reset_bar(pci, bar, 0);
 41}
 42
 43static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
 44				   struct pci_epf_header *hdr)
 45{
 46	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 47	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 48
 49	dw_pcie_dbi_ro_wr_en(pci);
 50	dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, hdr->vendorid);
 51	dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, hdr->deviceid);
 52	dw_pcie_writeb_dbi(pci, PCI_REVISION_ID, hdr->revid);
 53	dw_pcie_writeb_dbi(pci, PCI_CLASS_PROG, hdr->progif_code);
 54	dw_pcie_writew_dbi(pci, PCI_CLASS_DEVICE,
 55			   hdr->subclass_code | hdr->baseclass_code << 8);
 56	dw_pcie_writeb_dbi(pci, PCI_CACHE_LINE_SIZE,
 57			   hdr->cache_line_size);
 58	dw_pcie_writew_dbi(pci, PCI_SUBSYSTEM_VENDOR_ID,
 59			   hdr->subsys_vendor_id);
 60	dw_pcie_writew_dbi(pci, PCI_SUBSYSTEM_ID, hdr->subsys_id);
 61	dw_pcie_writeb_dbi(pci, PCI_INTERRUPT_PIN,
 62			   hdr->interrupt_pin);
 63	dw_pcie_dbi_ro_wr_dis(pci);
 64
 65	return 0;
 66}
 67
 68static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
 69				  dma_addr_t cpu_addr,
 70				  enum dw_pcie_as_type as_type)
 71{
 72	int ret;
 73	u32 free_win;
 74	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 75
 76	free_win = find_first_zero_bit(ep->ib_window_map, ep->num_ib_windows);
 77	if (free_win >= ep->num_ib_windows) {
 78		dev_err(pci->dev, "no free inbound window\n");
 79		return -EINVAL;
 80	}
 81
 82	ret = dw_pcie_prog_inbound_atu(pci, free_win, bar, cpu_addr,
 83				       as_type);
 84	if (ret < 0) {
 85		dev_err(pci->dev, "Failed to program IB window\n");
 86		return ret;
 87	}
 88
 89	ep->bar_to_atu[bar] = free_win;
 90	set_bit(free_win, ep->ib_window_map);
 91
 92	return 0;
 93}
 94
 95static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
 96				   u64 pci_addr, size_t size)
 97{
 98	u32 free_win;
 99	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
100
101	free_win = find_first_zero_bit(ep->ob_window_map, ep->num_ob_windows);
102	if (free_win >= ep->num_ob_windows) {
103		dev_err(pci->dev, "no free outbound window\n");
104		return -EINVAL;
105	}
106
107	dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM,
108				  phys_addr, pci_addr, size);
109
110	set_bit(free_win, ep->ob_window_map);
111	ep->outbound_addr[free_win] = phys_addr;
112
113	return 0;
114}
115
116static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
117				 struct pci_epf_bar *epf_bar)
118{
119	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
120	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
121	enum pci_barno bar = epf_bar->barno;
122	u32 atu_index = ep->bar_to_atu[bar];
123
124	__dw_pcie_ep_reset_bar(pci, bar, epf_bar->flags);
125
126	dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND);
127	clear_bit(atu_index, ep->ib_window_map);
128}
129
130static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
131			      struct pci_epf_bar *epf_bar)
132{
133	int ret;
134	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
135	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
136	enum pci_barno bar = epf_bar->barno;
137	size_t size = epf_bar->size;
138	int flags = epf_bar->flags;
139	enum dw_pcie_as_type as_type;
140	u32 reg = PCI_BASE_ADDRESS_0 + (4 * bar);
141
142	if (!(flags & PCI_BASE_ADDRESS_SPACE))
143		as_type = DW_PCIE_AS_MEM;
144	else
145		as_type = DW_PCIE_AS_IO;
146
147	ret = dw_pcie_ep_inbound_atu(ep, bar, epf_bar->phys_addr, as_type);
148	if (ret)
149		return ret;
150
151	dw_pcie_dbi_ro_wr_en(pci);
152
153	dw_pcie_writel_dbi2(pci, reg, lower_32_bits(size - 1));
154	dw_pcie_writel_dbi(pci, reg, flags);
155
156	if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) {
157		dw_pcie_writel_dbi2(pci, reg + 4, upper_32_bits(size - 1));
158		dw_pcie_writel_dbi(pci, reg + 4, 0);
159	}
160
161	dw_pcie_dbi_ro_wr_dis(pci);
162
163	return 0;
164}
165
166static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
167			      u32 *atu_index)
168{
169	u32 index;
170
171	for (index = 0; index < ep->num_ob_windows; index++) {
172		if (ep->outbound_addr[index] != addr)
173			continue;
174		*atu_index = index;
175		return 0;
176	}
177
178	return -EINVAL;
179}
180
181static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
182				  phys_addr_t addr)
183{
184	int ret;
185	u32 atu_index;
186	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
187	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
188
189	ret = dw_pcie_find_index(ep, addr, &atu_index);
190	if (ret < 0)
191		return;
192
193	dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_OUTBOUND);
194	clear_bit(atu_index, ep->ob_window_map);
195}
196
197static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
198			       phys_addr_t addr,
199			       u64 pci_addr, size_t size)
200{
201	int ret;
202	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
203	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
204
205	ret = dw_pcie_ep_outbound_atu(ep, addr, pci_addr, size);
206	if (ret) {
207		dev_err(pci->dev, "failed to enable address\n");
208		return ret;
209	}
210
211	return 0;
212}
213
214static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
215{
216	int val;
217	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
218	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
219
220	val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
221	if (!(val & MSI_CAP_MSI_EN_MASK))
222		return -EINVAL;
223
224	val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT;
225	return val;
226}
227
228static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int)
229{
230	int val;
231	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
232	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
233
234	val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
235	val &= ~MSI_CAP_MMC_MASK;
236	val |= (encode_int << MSI_CAP_MMC_SHIFT) & MSI_CAP_MMC_MASK;
237	dw_pcie_dbi_ro_wr_en(pci);
238	dw_pcie_writew_dbi(pci, MSI_MESSAGE_CONTROL, val);
239	dw_pcie_dbi_ro_wr_dis(pci);
240
241	return 0;
242}
243
244static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no,
245				enum pci_epc_irq_type type, u8 interrupt_num)
246{
247	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
248
249	if (!ep->ops->raise_irq)
250		return -EINVAL;
251
252	return ep->ops->raise_irq(ep, func_no, type, interrupt_num);
253}
254
255static void dw_pcie_ep_stop(struct pci_epc *epc)
256{
257	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
258	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
259
260	if (!pci->ops->stop_link)
261		return;
262
263	pci->ops->stop_link(pci);
264}
265
266static int dw_pcie_ep_start(struct pci_epc *epc)
267{
268	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
269	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
270
271	if (!pci->ops->start_link)
272		return -EINVAL;
273
274	return pci->ops->start_link(pci);
275}
276
277static const struct pci_epc_ops epc_ops = {
278	.write_header		= dw_pcie_ep_write_header,
279	.set_bar		= dw_pcie_ep_set_bar,
280	.clear_bar		= dw_pcie_ep_clear_bar,
281	.map_addr		= dw_pcie_ep_map_addr,
282	.unmap_addr		= dw_pcie_ep_unmap_addr,
283	.set_msi		= dw_pcie_ep_set_msi,
284	.get_msi		= dw_pcie_ep_get_msi,
285	.raise_irq		= dw_pcie_ep_raise_irq,
286	.start			= dw_pcie_ep_start,
287	.stop			= dw_pcie_ep_stop,
288};
289
290int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
291			     u8 interrupt_num)
292{
293	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
294	struct pci_epc *epc = ep->epc;
295	u16 msg_ctrl, msg_data;
296	u32 msg_addr_lower, msg_addr_upper;
297	u64 msg_addr;
298	bool has_upper;
299	int ret;
300
301	/* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */
302	msg_ctrl = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
303	has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT);
304	msg_addr_lower = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32);
305	if (has_upper) {
306		msg_addr_upper = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32);
307		msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_64);
308	} else {
309		msg_addr_upper = 0;
310		msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_32);
311	}
312	msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower;
313	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
314				  epc->mem->page_size);
315	if (ret)
316		return ret;
317
318	writel(msg_data | (interrupt_num - 1), ep->msi_mem);
319
320	dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);
321
322	return 0;
323}
324
325void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
326{
327	struct pci_epc *epc = ep->epc;
328
329	pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
330			      epc->mem->page_size);
331
332	pci_epc_mem_exit(epc);
333}
334
335int dw_pcie_ep_init(struct dw_pcie_ep *ep)
336{
337	int ret;
338	void *addr;
339	struct pci_epc *epc;
340	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
341	struct device *dev = pci->dev;
342	struct device_node *np = dev->of_node;
343
344	if (!pci->dbi_base || !pci->dbi_base2) {
345		dev_err(dev, "dbi_base/dbi_base2 is not populated\n");
346		return -EINVAL;
347	}
348
349	ret = of_property_read_u32(np, "num-ib-windows", &ep->num_ib_windows);
350	if (ret < 0) {
351		dev_err(dev, "unable to read *num-ib-windows* property\n");
352		return ret;
353	}
354	if (ep->num_ib_windows > MAX_IATU_IN) {
355		dev_err(dev, "invalid *num-ib-windows*\n");
356		return -EINVAL;
357	}
358
359	ret = of_property_read_u32(np, "num-ob-windows", &ep->num_ob_windows);
360	if (ret < 0) {
361		dev_err(dev, "unable to read *num-ob-windows* property\n");
362		return ret;
363	}
364	if (ep->num_ob_windows > MAX_IATU_OUT) {
365		dev_err(dev, "invalid *num-ob-windows*\n");
366		return -EINVAL;
367	}
368
369	ep->ib_window_map = devm_kzalloc(dev, sizeof(long) *
370					 BITS_TO_LONGS(ep->num_ib_windows),
371					 GFP_KERNEL);
372	if (!ep->ib_window_map)
373		return -ENOMEM;
374
375	ep->ob_window_map = devm_kzalloc(dev, sizeof(long) *
376					 BITS_TO_LONGS(ep->num_ob_windows),
377					 GFP_KERNEL);
378	if (!ep->ob_window_map)
379		return -ENOMEM;
380
381	addr = devm_kzalloc(dev, sizeof(phys_addr_t) * ep->num_ob_windows,
382			    GFP_KERNEL);
383	if (!addr)
384		return -ENOMEM;
385	ep->outbound_addr = addr;
386
387	if (ep->ops->ep_init)
388		ep->ops->ep_init(ep);
389
390	epc = devm_pci_epc_create(dev, &epc_ops);
391	if (IS_ERR(epc)) {
392		dev_err(dev, "failed to create epc device\n");
393		return PTR_ERR(epc);
394	}
395
396	ret = of_property_read_u8(np, "max-functions", &epc->max_functions);
397	if (ret < 0)
398		epc->max_functions = 1;
399
400	ret = __pci_epc_mem_init(epc, ep->phys_base, ep->addr_size,
401				 ep->page_size);
402	if (ret < 0) {
403		dev_err(dev, "Failed to initialize address space\n");
404		return ret;
405	}
406
407	ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
408					     epc->mem->page_size);
409	if (!ep->msi_mem) {
410		dev_err(dev, "Failed to reserve memory for MSI\n");
411		return -ENOMEM;
412	}
413
414	ep->epc = epc;
415	epc_set_drvdata(epc, ep);
416	dw_pcie_setup(pci);
417
418	return 0;
419}