rockchip: rk3128-cru: sync the clock dt-binding header from Linux
[platform/kernel/u-boot.git] / drivers / pci / pcie_dw_common.c
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
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
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
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
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  */
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  */
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  */
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  */
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  */
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  */
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 }