• Home
  • Raw
  • Download

Lines Matching +full:pcie +full:- +full:1

1 // SPDX-License-Identifier: GPL-2.0
3 * PCIe endpoint driver for Renesas R-Car SoCs
6 * Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
16 #include <linux/pci-epc.h>
20 #include "pcie-rcar.h"
22 #define RCAR_EPC_MAX_FUNCTIONS 1
24 /* Structure representing the PCIe interface */
26 struct rcar_pcie pcie; member
36 static void rcar_pcie_ep_hw_init(struct rcar_pcie *pcie) in rcar_pcie_ep_hw_init() argument
40 rcar_pci_write_reg(pcie, 0, PCIETCTLR); in rcar_pcie_ep_hw_init()
43 rcar_pci_write_reg(pcie, 0, PCIEMSR); in rcar_pcie_ep_hw_init()
46 rcar_rmw32(pcie, REXPCAP(0), 0xff, PCI_CAP_ID_EXP); in rcar_pcie_ep_hw_init()
47 rcar_rmw32(pcie, REXPCAP(PCI_EXP_FLAGS), in rcar_pcie_ep_hw_init()
49 rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f, in rcar_pcie_ep_hw_init()
53 rcar_rmw32(pcie, REXPCAP(PCI_EXP_SLTCAP), PCI_EXP_SLTCAP_PSN, 0); in rcar_pcie_ep_hw_init()
55 val = rcar_pci_read_reg(pcie, EXPCAP(1)); in rcar_pcie_ep_hw_init()
58 rcar_pci_write_reg(pcie, val, EXPCAP(1)); in rcar_pcie_ep_hw_init()
60 val = rcar_pci_read_reg(pcie, EXPCAP(2)); in rcar_pcie_ep_hw_init()
65 rcar_pci_write_reg(pcie, val, EXPCAP(2)); in rcar_pcie_ep_hw_init()
68 rcar_rmw32(pcie, EXPCAP(12), PCI_EXP_LNKSTA_CLS, in rcar_pcie_ep_hw_init()
72 rcar_rmw32(pcie, TLCTLR + 1, 0x3f, 50); in rcar_pcie_ep_hw_init()
75 rcar_rmw32(pcie, RVCCAP(0), 0xfff00000, 0); in rcar_pcie_ep_hw_init()
86 for (i = 0; i < ep->num_ob_windows; i++) in rcar_pcie_ep_get_window()
87 if (ep->ob_window[i].phys_base == addr) in rcar_pcie_ep_get_window()
90 return -EINVAL; in rcar_pcie_ep_get_window()
96 struct rcar_pcie *pcie = &ep->pcie; in rcar_pcie_parse_outbound_ranges() local
101 ep->num_ob_windows = 0; in rcar_pcie_parse_outbound_ranges()
108 dev_err(pcie->dev, "missing outbound window %u\n", i); in rcar_pcie_parse_outbound_ranges()
109 return -EINVAL; in rcar_pcie_parse_outbound_ranges()
111 if (!devm_request_mem_region(&pdev->dev, res->start, in rcar_pcie_parse_outbound_ranges()
114 dev_err(pcie->dev, "Cannot request memory region %s.\n", in rcar_pcie_parse_outbound_ranges()
116 return -EIO; in rcar_pcie_parse_outbound_ranges()
119 ep->ob_window[i].phys_base = res->start; in rcar_pcie_parse_outbound_ranges()
120 ep->ob_window[i].size = resource_size(res); in rcar_pcie_parse_outbound_ranges()
124 ep->ob_window[i].page_size = resource_size(res); in rcar_pcie_parse_outbound_ranges()
126 ep->num_ob_windows = i; in rcar_pcie_parse_outbound_ranges()
134 struct rcar_pcie *pcie = &ep->pcie; in rcar_pcie_ep_get_pdata() local
136 struct device *dev = pcie->dev; in rcar_pcie_ep_get_pdata()
140 err = of_address_to_resource(dev->of_node, 0, &res); in rcar_pcie_ep_get_pdata()
143 pcie->base = devm_ioremap_resource(dev, &res); in rcar_pcie_ep_get_pdata()
144 if (IS_ERR(pcie->base)) in rcar_pcie_ep_get_pdata()
145 return PTR_ERR(pcie->base); in rcar_pcie_ep_get_pdata()
147 ep->ob_window = devm_kcalloc(dev, RCAR_PCI_MAX_RESOURCES, in rcar_pcie_ep_get_pdata()
149 if (!ep->ob_window) in rcar_pcie_ep_get_pdata()
150 return -ENOMEM; in rcar_pcie_ep_get_pdata()
154 err = of_property_read_u8(dev->of_node, "max-functions", in rcar_pcie_ep_get_pdata()
155 &ep->max_functions); in rcar_pcie_ep_get_pdata()
156 if (err < 0 || ep->max_functions > RCAR_EPC_MAX_FUNCTIONS) in rcar_pcie_ep_get_pdata()
157 ep->max_functions = RCAR_EPC_MAX_FUNCTIONS; in rcar_pcie_ep_get_pdata()
166 struct rcar_pcie *pcie = &ep->pcie; in rcar_pcie_ep_write_header() local
170 val = hdr->vendorid; in rcar_pcie_ep_write_header()
172 val = rcar_pci_read_reg(pcie, IDSETR0); in rcar_pcie_ep_write_header()
173 val |= hdr->deviceid << 16; in rcar_pcie_ep_write_header()
174 rcar_pci_write_reg(pcie, val, IDSETR0); in rcar_pcie_ep_write_header()
176 val = hdr->revid; in rcar_pcie_ep_write_header()
177 val |= hdr->progif_code << 8; in rcar_pcie_ep_write_header()
178 val |= hdr->subclass_code << 16; in rcar_pcie_ep_write_header()
179 val |= hdr->baseclass_code << 24; in rcar_pcie_ep_write_header()
180 rcar_pci_write_reg(pcie, val, IDSETR1); in rcar_pcie_ep_write_header()
183 val = hdr->subsys_vendor_id; in rcar_pcie_ep_write_header()
185 val = rcar_pci_read_reg(pcie, SUBIDSETR); in rcar_pcie_ep_write_header()
186 val |= hdr->subsys_id << 16; in rcar_pcie_ep_write_header()
187 rcar_pci_write_reg(pcie, val, SUBIDSETR); in rcar_pcie_ep_write_header()
189 if (hdr->interrupt_pin > PCI_INTERRUPT_INTA) in rcar_pcie_ep_write_header()
190 return -EINVAL; in rcar_pcie_ep_write_header()
191 val = rcar_pci_read_reg(pcie, PCICONF(15)); in rcar_pcie_ep_write_header()
192 val |= (hdr->interrupt_pin << 8); in rcar_pcie_ep_write_header()
193 rcar_pci_write_reg(pcie, val, PCICONF(15)); in rcar_pcie_ep_write_header()
201 int flags = epf_bar->flags | LAR_ENABLE | LAM_64BIT; in rcar_pcie_ep_set_bar()
203 u64 size = 1ULL << fls64(epf_bar->size - 1); in rcar_pcie_ep_set_bar()
204 dma_addr_t cpu_addr = epf_bar->phys_addr; in rcar_pcie_ep_set_bar()
205 enum pci_barno bar = epf_bar->barno; in rcar_pcie_ep_set_bar()
206 struct rcar_pcie *pcie = &ep->pcie; in rcar_pcie_ep_set_bar() local
211 idx = find_first_zero_bit(ep->ib_window_map, ep->num_ib_windows); in rcar_pcie_ep_set_bar()
212 if (idx >= ep->num_ib_windows) { in rcar_pcie_ep_set_bar()
213 dev_err(pcie->dev, "no free inbound window\n"); in rcar_pcie_ep_set_bar()
214 return -EINVAL; in rcar_pcie_ep_set_bar()
220 ep->bar_to_atu[bar] = idx; in rcar_pcie_ep_set_bar()
221 /* use 64-bit BARs */ in rcar_pcie_ep_set_bar()
222 set_bit(idx, ep->ib_window_map); in rcar_pcie_ep_set_bar()
223 set_bit(idx + 1, ep->ib_window_map); in rcar_pcie_ep_set_bar()
227 u64 alignment = 1ULL << nr_zeros; in rcar_pcie_ep_set_bar()
232 size = min(size, 1ULL << 32); in rcar_pcie_ep_set_bar()
234 mask = roundup_pow_of_two(size) - 1; in rcar_pcie_ep_set_bar()
237 rcar_pcie_set_inbound(pcie, cpu_addr, in rcar_pcie_ep_set_bar()
240 err = rcar_pcie_wait_for_phyrdy(pcie); in rcar_pcie_ep_set_bar()
242 dev_err(pcie->dev, "phy not ready\n"); in rcar_pcie_ep_set_bar()
243 return -EINVAL; in rcar_pcie_ep_set_bar()
253 enum pci_barno bar = epf_bar->barno; in rcar_pcie_ep_clear_bar()
254 u32 atu_index = ep->bar_to_atu[bar]; in rcar_pcie_ep_clear_bar()
256 rcar_pcie_set_inbound(&ep->pcie, 0x0, 0x0, 0x0, bar, false); in rcar_pcie_ep_clear_bar()
258 clear_bit(atu_index, ep->ib_window_map); in rcar_pcie_ep_clear_bar()
259 clear_bit(atu_index + 1, ep->ib_window_map); in rcar_pcie_ep_clear_bar()
265 struct rcar_pcie *pcie = &ep->pcie; in rcar_pcie_ep_set_msi() local
268 flags = rcar_pci_read_reg(pcie, MSICAP(fn)); in rcar_pcie_ep_set_msi()
270 rcar_pci_write_reg(pcie, flags, MSICAP(fn)); in rcar_pcie_ep_set_msi()
278 struct rcar_pcie *pcie = &ep->pcie; in rcar_pcie_ep_get_msi() local
281 flags = rcar_pci_read_reg(pcie, MSICAP(fn)); in rcar_pcie_ep_get_msi()
283 return -EINVAL; in rcar_pcie_ep_get_msi()
292 struct rcar_pcie *pcie = &ep->pcie; in rcar_pcie_ep_map_addr() local
299 err = rcar_pcie_wait_for_dl(pcie); in rcar_pcie_ep_map_addr()
301 dev_err(pcie->dev, "link not up\n"); in rcar_pcie_ep_map_addr()
307 dev_err(pcie->dev, "failed to get corresponding window\n"); in rcar_pcie_ep_map_addr()
308 return -EINVAL; in rcar_pcie_ep_map_addr()
314 res.end = pci_addr + size - 1; in rcar_pcie_ep_map_addr()
318 rcar_pcie_set_outbound(pcie, window, &win); in rcar_pcie_ep_map_addr()
320 ep->ob_mapped_addr[window] = addr; in rcar_pcie_ep_map_addr()
333 for (idx = 0; idx < ep->num_ob_windows; idx++) in rcar_pcie_ep_unmap_addr()
334 if (ep->ob_mapped_addr[idx] == addr) in rcar_pcie_ep_unmap_addr()
337 if (idx >= ep->num_ob_windows) in rcar_pcie_ep_unmap_addr()
343 rcar_pcie_set_outbound(&ep->pcie, idx, &win); in rcar_pcie_ep_unmap_addr()
345 ep->ob_mapped_addr[idx] = 0; in rcar_pcie_ep_unmap_addr()
351 struct rcar_pcie *pcie = &ep->pcie; in rcar_pcie_ep_assert_intx() local
354 val = rcar_pci_read_reg(pcie, PCIEMSITXR); in rcar_pcie_ep_assert_intx()
356 dev_err(pcie->dev, "MSI is enabled, cannot assert INTx\n"); in rcar_pcie_ep_assert_intx()
357 return -EINVAL; in rcar_pcie_ep_assert_intx()
360 val = rcar_pci_read_reg(pcie, PCICONF(1)); in rcar_pcie_ep_assert_intx()
362 dev_err(pcie->dev, "INTx message transmission is disabled\n"); in rcar_pcie_ep_assert_intx()
363 return -EINVAL; in rcar_pcie_ep_assert_intx()
366 val = rcar_pci_read_reg(pcie, PCIEINTXR); in rcar_pcie_ep_assert_intx()
368 dev_err(pcie->dev, "INTx is already asserted\n"); in rcar_pcie_ep_assert_intx()
369 return -EINVAL; in rcar_pcie_ep_assert_intx()
373 rcar_pci_write_reg(pcie, val, PCIEINTXR); in rcar_pcie_ep_assert_intx()
375 val = rcar_pci_read_reg(pcie, PCIEINTXR); in rcar_pcie_ep_assert_intx()
377 rcar_pci_write_reg(pcie, val, PCIEINTXR); in rcar_pcie_ep_assert_intx()
382 static int rcar_pcie_ep_assert_msi(struct rcar_pcie *pcie, in rcar_pcie_ep_assert_msi() argument
389 val = rcar_pci_read_reg(pcie, MSICAP(fn)); in rcar_pcie_ep_assert_msi()
391 return -EINVAL; in rcar_pcie_ep_assert_msi()
395 msi_count = 1 << msi_count; in rcar_pcie_ep_assert_msi()
398 return -EINVAL; in rcar_pcie_ep_assert_msi()
400 val = rcar_pci_read_reg(pcie, PCIEMSITXR); in rcar_pcie_ep_assert_msi()
401 rcar_pci_write_reg(pcie, val | (interrupt_num - 1), PCIEMSITXR); in rcar_pcie_ep_assert_msi()
417 return rcar_pcie_ep_assert_msi(&ep->pcie, fn, interrupt_num); in rcar_pcie_ep_raise_irq()
420 return -EINVAL; in rcar_pcie_ep_raise_irq()
428 rcar_pci_write_reg(&ep->pcie, MACCTLR_INIT_VAL, MACCTLR); in rcar_pcie_ep_start()
429 rcar_pci_write_reg(&ep->pcie, CFINIT, PCIETCTLR); in rcar_pcie_ep_start()
438 rcar_pci_write_reg(&ep->pcie, 0, PCIETCTLR); in rcar_pcie_ep_stop()
445 /* use 64-bit BARs so mark BAR[1,3,5] as reserved */
446 .reserved_bar = 1 << BAR_1 | 1 << BAR_3 | 1 << BAR_5,
447 .bar_fixed_64bit = 1 << BAR_0 | 1 << BAR_2 | 1 << BAR_4,
474 { .compatible = "renesas,r8a774c0-pcie-ep", },
475 { .compatible = "renesas,rcar-gen3-pcie-ep" },
481 struct device *dev = &pdev->dev; in rcar_pcie_ep_probe()
483 struct rcar_pcie *pcie; in rcar_pcie_ep_probe() local
489 return -ENOMEM; in rcar_pcie_ep_probe()
491 pcie = &ep->pcie; in rcar_pcie_ep_probe()
492 pcie->dev = dev; in rcar_pcie_ep_probe()
507 ep->num_ib_windows = MAX_NR_INBOUND_MAPS; in rcar_pcie_ep_probe()
508 ep->ib_window_map = in rcar_pcie_ep_probe()
509 devm_kcalloc(dev, BITS_TO_LONGS(ep->num_ib_windows), in rcar_pcie_ep_probe()
511 if (!ep->ib_window_map) { in rcar_pcie_ep_probe()
512 err = -ENOMEM; in rcar_pcie_ep_probe()
517 ep->ob_mapped_addr = devm_kcalloc(dev, ep->num_ob_windows, in rcar_pcie_ep_probe()
518 sizeof(*ep->ob_mapped_addr), in rcar_pcie_ep_probe()
520 if (!ep->ob_mapped_addr) { in rcar_pcie_ep_probe()
521 err = -ENOMEM; in rcar_pcie_ep_probe()
533 epc->max_functions = ep->max_functions; in rcar_pcie_ep_probe()
536 rcar_pcie_ep_hw_init(pcie); in rcar_pcie_ep_probe()
538 err = pci_epc_multi_mem_init(epc, ep->ob_window, ep->num_ob_windows); in rcar_pcie_ep_probe()
557 .name = "rcar-pcie-ep",