1 // SPDX-License-Identifier: GPL-2.0
3 * PCIe driver for Renesas R-Car SoCs
4 * Copyright (C) 2014-2020 Renesas Electronics Europe Ltd
6 * Author: Phil Edworthy <phil.edworthy@renesas.com>
9 #include <linux/delay.h>
10 #include <linux/pci.h>
12 #include "pcie-rcar.h"
14 void rcar_pci_write_reg(struct rcar_pcie
*pcie
, u32 val
, unsigned int reg
)
16 writel(val
, pcie
->base
+ reg
);
19 u32
rcar_pci_read_reg(struct rcar_pcie
*pcie
, unsigned int reg
)
21 return readl(pcie
->base
+ reg
);
24 void rcar_rmw32(struct rcar_pcie
*pcie
, int where
, u32 mask
, u32 data
)
26 unsigned int shift
= BITS_PER_BYTE
* (where
& 3);
27 u32 val
= rcar_pci_read_reg(pcie
, where
& ~3);
29 val
&= ~(mask
<< shift
);
31 rcar_pci_write_reg(pcie
, val
, where
& ~3);
34 int rcar_pcie_wait_for_phyrdy(struct rcar_pcie
*pcie
)
36 unsigned int timeout
= 10;
39 if (rcar_pci_read_reg(pcie
, PCIEPHYSR
) & PHYRDY
)
48 int rcar_pcie_wait_for_dl(struct rcar_pcie
*pcie
)
50 unsigned int timeout
= 10000;
53 if ((rcar_pci_read_reg(pcie
, PCIETSTR
) & DATA_LINK_ACTIVE
))
63 void rcar_pcie_set_outbound(struct rcar_pcie
*pcie
, int win
,
64 struct resource_entry
*window
)
66 /* Setup PCIe address space mappings for each resource */
67 struct resource
*res
= window
->res
;
68 resource_size_t res_start
;
72 rcar_pci_write_reg(pcie
, 0x00000000, PCIEPTCTLR(win
));
75 * The PAMR mask is calculated in units of 128Bytes, which
76 * keeps things pretty simple.
78 size
= resource_size(res
);
80 mask
= (roundup_pow_of_two(size
) / SZ_128
) - 1;
83 rcar_pci_write_reg(pcie
, mask
<< 7, PCIEPAMR(win
));
85 if (res
->flags
& IORESOURCE_IO
)
86 res_start
= pci_pio_to_address(res
->start
) - window
->offset
;
88 res_start
= res
->start
- window
->offset
;
90 rcar_pci_write_reg(pcie
, upper_32_bits(res_start
), PCIEPAUR(win
));
91 rcar_pci_write_reg(pcie
, lower_32_bits(res_start
) & ~0x7F,
94 /* First resource is for IO */
96 if (res
->flags
& IORESOURCE_IO
)
99 rcar_pci_write_reg(pcie
, mask
, PCIEPTCTLR(win
));
102 void rcar_pcie_set_inbound(struct rcar_pcie
*pcie
, u64 cpu_addr
,
103 u64 pci_addr
, u64 flags
, int idx
, bool host
)
106 * Set up 64-bit inbound regions as the range parser doesn't
107 * distinguish between 32 and 64-bit types.
110 rcar_pci_write_reg(pcie
, lower_32_bits(pci_addr
),
112 rcar_pci_write_reg(pcie
, lower_32_bits(cpu_addr
), PCIELAR(idx
));
113 rcar_pci_write_reg(pcie
, flags
, PCIELAMR(idx
));
116 rcar_pci_write_reg(pcie
, upper_32_bits(pci_addr
),
118 rcar_pci_write_reg(pcie
, upper_32_bits(cpu_addr
), PCIELAR(idx
+ 1));
119 rcar_pci_write_reg(pcie
, 0, PCIELAMR(idx
+ 1));