1// SPDX-License-Identifier: GPL-2.0
2/*
3 * PCIe host controller driver for Amazon's Annapurna Labs IP (used in chips
4 * such as Graviton and Alpine)
5 *
6 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
7 *
8 * Author: Jonathan Chocron <jonnyc@amazon.com>
9 */
10
11#include <linux/pci.h>
12#include <linux/pci-ecam.h>
13#include <linux/pci-acpi.h>
14#include "../../pci.h"
15
16#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
17
18struct al_pcie_acpi  {
19	void __iomem *dbi_base;
20};
21
22static void __iomem *al_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
23				     int where)
24{
25	struct pci_config_window *cfg = bus->sysdata;
26	struct al_pcie_acpi *pcie = cfg->priv;
27	void __iomem *dbi_base = pcie->dbi_base;
28
29	if (bus->number == cfg->busr.start) {
30		/*
31		 * The DW PCIe core doesn't filter out transactions to other
32		 * devices/functions on the root bus num, so we do this here.
33		 */
34		if (PCI_SLOT(devfn) > 0)
35			return NULL;
36		else
37			return dbi_base + where;
38	}
39
40	return pci_ecam_map_bus(bus, devfn, where);
41}
42
43static int al_pcie_init(struct pci_config_window *cfg)
44{
45	struct device *dev = cfg->parent;
46	struct acpi_device *adev = to_acpi_device(dev);
47	struct acpi_pci_root *root = acpi_driver_data(adev);
48	struct al_pcie_acpi *al_pcie;
49	struct resource *res;
50	int ret;
51
52	al_pcie = devm_kzalloc(dev, sizeof(*al_pcie), GFP_KERNEL);
53	if (!al_pcie)
54		return -ENOMEM;
55
56	res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
57	if (!res)
58		return -ENOMEM;
59
60	ret = acpi_get_rc_resources(dev, "AMZN0001", root->segment, res);
61	if (ret) {
62		dev_err(dev, "can't get rc dbi base address for SEG %d\n",
63			root->segment);
64		return ret;
65	}
66
67	dev_dbg(dev, "Root port dbi res: %pR\n", res);
68
69	al_pcie->dbi_base = devm_pci_remap_cfg_resource(dev, res);
70	if (IS_ERR(al_pcie->dbi_base))
71		return PTR_ERR(al_pcie->dbi_base);
72
73	cfg->priv = al_pcie;
74
75	return 0;
76}
77
78const struct pci_ecam_ops al_pcie_ops = {
79	.bus_shift    = 20,
80	.init         =  al_pcie_init,
81	.pci_ops      = {
82		.map_bus    = al_pcie_map_bus,
83		.read       = pci_generic_config_read,
84		.write      = pci_generic_config_write,
85	}
86};
87
88#endif /* defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) */
89
90#ifdef CONFIG_PCIE_AL
91
92#include <linux/of_pci.h>
93#include "pcie-designware.h"
94
95#define AL_PCIE_REV_ID_2	2
96#define AL_PCIE_REV_ID_3	3
97#define AL_PCIE_REV_ID_4	4
98
99#define AXI_BASE_OFFSET		0x0
100
101#define DEVICE_ID_OFFSET	0x16c
102
103#define DEVICE_REV_ID			0x0
104#define DEVICE_REV_ID_DEV_ID_MASK	GENMASK(31, 16)
105
106#define DEVICE_REV_ID_DEV_ID_X4		0
107#define DEVICE_REV_ID_DEV_ID_X8		2
108#define DEVICE_REV_ID_DEV_ID_X16	4
109
110#define OB_CTRL_REV1_2_OFFSET	0x0040
111#define OB_CTRL_REV3_5_OFFSET	0x0030
112
113#define CFG_TARGET_BUS			0x0
114#define CFG_TARGET_BUS_MASK_MASK	GENMASK(7, 0)
115#define CFG_TARGET_BUS_BUSNUM_MASK	GENMASK(15, 8)
116
117#define CFG_CONTROL			0x4
118#define CFG_CONTROL_SUBBUS_MASK		GENMASK(15, 8)
119#define CFG_CONTROL_SEC_BUS_MASK	GENMASK(23, 16)
120
121struct al_pcie_reg_offsets {
122	unsigned int ob_ctrl;
123};
124
125struct al_pcie_target_bus_cfg {
126	u8 reg_val;
127	u8 reg_mask;
128	u8 ecam_mask;
129};
130
131struct al_pcie {
132	struct dw_pcie *pci;
133	void __iomem *controller_base; /* base of PCIe unit (not DW core) */
134	struct device *dev;
135	resource_size_t ecam_size;
136	unsigned int controller_rev_id;
137	struct al_pcie_reg_offsets reg_offsets;
138	struct al_pcie_target_bus_cfg target_bus_cfg;
139};
140
141#define PCIE_ECAM_DEVFN(x)		(((x) & 0xff) << 12)
142
143#define to_al_pcie(x)		dev_get_drvdata((x)->dev)
144
145static inline u32 al_pcie_controller_readl(struct al_pcie *pcie, u32 offset)
146{
147	return readl_relaxed(pcie->controller_base + offset);
148}
149
150static inline void al_pcie_controller_writel(struct al_pcie *pcie, u32 offset,
151					     u32 val)
152{
153	writel_relaxed(val, pcie->controller_base + offset);
154}
155
156static int al_pcie_rev_id_get(struct al_pcie *pcie, unsigned int *rev_id)
157{
158	u32 dev_rev_id_val;
159	u32 dev_id_val;
160
161	dev_rev_id_val = al_pcie_controller_readl(pcie, AXI_BASE_OFFSET +
162						  DEVICE_ID_OFFSET +
163						  DEVICE_REV_ID);
164	dev_id_val = FIELD_GET(DEVICE_REV_ID_DEV_ID_MASK, dev_rev_id_val);
165
166	switch (dev_id_val) {
167	case DEVICE_REV_ID_DEV_ID_X4:
168		*rev_id = AL_PCIE_REV_ID_2;
169		break;
170	case DEVICE_REV_ID_DEV_ID_X8:
171		*rev_id = AL_PCIE_REV_ID_3;
172		break;
173	case DEVICE_REV_ID_DEV_ID_X16:
174		*rev_id = AL_PCIE_REV_ID_4;
175		break;
176	default:
177		dev_err(pcie->dev, "Unsupported dev_id_val (0x%x)\n",
178			dev_id_val);
179		return -EINVAL;
180	}
181
182	dev_dbg(pcie->dev, "dev_id_val: 0x%x\n", dev_id_val);
183
184	return 0;
185}
186
187static int al_pcie_reg_offsets_set(struct al_pcie *pcie)
188{
189	switch (pcie->controller_rev_id) {
190	case AL_PCIE_REV_ID_2:
191		pcie->reg_offsets.ob_ctrl = OB_CTRL_REV1_2_OFFSET;
192		break;
193	case AL_PCIE_REV_ID_3:
194	case AL_PCIE_REV_ID_4:
195		pcie->reg_offsets.ob_ctrl = OB_CTRL_REV3_5_OFFSET;
196		break;
197	default:
198		dev_err(pcie->dev, "Unsupported controller rev_id: 0x%x\n",
199			pcie->controller_rev_id);
200		return -EINVAL;
201	}
202
203	return 0;
204}
205
206static inline void al_pcie_target_bus_set(struct al_pcie *pcie,
207					  u8 target_bus,
208					  u8 mask_target_bus)
209{
210	u32 reg;
211
212	reg = FIELD_PREP(CFG_TARGET_BUS_MASK_MASK, mask_target_bus) |
213	      FIELD_PREP(CFG_TARGET_BUS_BUSNUM_MASK, target_bus);
214
215	al_pcie_controller_writel(pcie, AXI_BASE_OFFSET +
216				  pcie->reg_offsets.ob_ctrl + CFG_TARGET_BUS,
217				  reg);
218}
219
220static void __iomem *al_pcie_conf_addr_map_bus(struct pci_bus *bus,
221					       unsigned int devfn, int where)
222{
223	struct pcie_port *pp = bus->sysdata;
224	struct al_pcie *pcie = to_al_pcie(to_dw_pcie_from_pp(pp));
225	unsigned int busnr = bus->number;
226	struct al_pcie_target_bus_cfg *target_bus_cfg = &pcie->target_bus_cfg;
227	unsigned int busnr_ecam = busnr & target_bus_cfg->ecam_mask;
228	unsigned int busnr_reg = busnr & target_bus_cfg->reg_mask;
229	void __iomem *pci_base_addr;
230
231	pci_base_addr = (void __iomem *)((uintptr_t)pp->va_cfg0_base +
232					 (busnr_ecam << 20) +
233					 PCIE_ECAM_DEVFN(devfn));
234
235	if (busnr_reg != target_bus_cfg->reg_val) {
236		dev_dbg(pcie->pci->dev, "Changing target bus busnum val from 0x%x to 0x%x\n",
237			target_bus_cfg->reg_val, busnr_reg);
238		target_bus_cfg->reg_val = busnr_reg;
239		al_pcie_target_bus_set(pcie,
240				       target_bus_cfg->reg_val,
241				       target_bus_cfg->reg_mask);
242	}
243
244	return pci_base_addr + where;
245}
246
247static struct pci_ops al_child_pci_ops = {
248	.map_bus = al_pcie_conf_addr_map_bus,
249	.read = pci_generic_config_read,
250	.write = pci_generic_config_write,
251};
252
253static void al_pcie_config_prepare(struct al_pcie *pcie)
254{
255	struct al_pcie_target_bus_cfg *target_bus_cfg;
256	struct pcie_port *pp = &pcie->pci->pp;
257	unsigned int ecam_bus_mask;
258	u32 cfg_control_offset;
259	u8 subordinate_bus;
260	u8 secondary_bus;
261	u32 cfg_control;
262	u32 reg;
263	struct resource *bus = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS)->res;
264
265	target_bus_cfg = &pcie->target_bus_cfg;
266
267	ecam_bus_mask = (pcie->ecam_size >> 20) - 1;
268	if (ecam_bus_mask > 255) {
269		dev_warn(pcie->dev, "ECAM window size is larger than 256MB. Cutting off at 256\n");
270		ecam_bus_mask = 255;
271	}
272
273	/* This portion is taken from the transaction address */
274	target_bus_cfg->ecam_mask = ecam_bus_mask;
275	/* This portion is taken from the cfg_target_bus reg */
276	target_bus_cfg->reg_mask = ~target_bus_cfg->ecam_mask;
277	target_bus_cfg->reg_val = bus->start & target_bus_cfg->reg_mask;
278
279	al_pcie_target_bus_set(pcie, target_bus_cfg->reg_val,
280			       target_bus_cfg->reg_mask);
281
282	secondary_bus = bus->start + 1;
283	subordinate_bus = bus->end;
284
285	/* Set the valid values of secondary and subordinate buses */
286	cfg_control_offset = AXI_BASE_OFFSET + pcie->reg_offsets.ob_ctrl +
287			     CFG_CONTROL;
288
289	cfg_control = al_pcie_controller_readl(pcie, cfg_control_offset);
290
291	reg = cfg_control &
292	      ~(CFG_CONTROL_SEC_BUS_MASK | CFG_CONTROL_SUBBUS_MASK);
293
294	reg |= FIELD_PREP(CFG_CONTROL_SUBBUS_MASK, subordinate_bus) |
295	       FIELD_PREP(CFG_CONTROL_SEC_BUS_MASK, secondary_bus);
296
297	al_pcie_controller_writel(pcie, cfg_control_offset, reg);
298}
299
300static int al_pcie_host_init(struct pcie_port *pp)
301{
302	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
303	struct al_pcie *pcie = to_al_pcie(pci);
304	int rc;
305
306	pp->bridge->child_ops = &al_child_pci_ops;
307
308	rc = al_pcie_rev_id_get(pcie, &pcie->controller_rev_id);
309	if (rc)
310		return rc;
311
312	rc = al_pcie_reg_offsets_set(pcie);
313	if (rc)
314		return rc;
315
316	al_pcie_config_prepare(pcie);
317
318	return 0;
319}
320
321static const struct dw_pcie_host_ops al_pcie_host_ops = {
322	.host_init = al_pcie_host_init,
323};
324
325static int al_add_pcie_port(struct pcie_port *pp,
326			    struct platform_device *pdev)
327{
328	struct device *dev = &pdev->dev;
329	int ret;
330
331	pp->ops = &al_pcie_host_ops;
332
333	ret = dw_pcie_host_init(pp);
334	if (ret) {
335		dev_err(dev, "failed to initialize host\n");
336		return ret;
337	}
338
339	return 0;
340}
341
342static const struct dw_pcie_ops dw_pcie_ops = {
343};
344
345static int al_pcie_probe(struct platform_device *pdev)
346{
347	struct device *dev = &pdev->dev;
348	struct resource *controller_res;
349	struct resource *ecam_res;
350	struct resource *dbi_res;
351	struct al_pcie *al_pcie;
352	struct dw_pcie *pci;
353
354	al_pcie = devm_kzalloc(dev, sizeof(*al_pcie), GFP_KERNEL);
355	if (!al_pcie)
356		return -ENOMEM;
357
358	pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
359	if (!pci)
360		return -ENOMEM;
361
362	pci->dev = dev;
363	pci->ops = &dw_pcie_ops;
364
365	al_pcie->pci = pci;
366	al_pcie->dev = dev;
367
368	dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
369	pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_res);
370	if (IS_ERR(pci->dbi_base))
371		return PTR_ERR(pci->dbi_base);
372
373	ecam_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
374	if (!ecam_res) {
375		dev_err(dev, "couldn't find 'config' reg in DT\n");
376		return -ENOENT;
377	}
378	al_pcie->ecam_size = resource_size(ecam_res);
379
380	controller_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
381						      "controller");
382	al_pcie->controller_base = devm_ioremap_resource(dev, controller_res);
383	if (IS_ERR(al_pcie->controller_base)) {
384		dev_err(dev, "couldn't remap controller base %pR\n",
385			controller_res);
386		return PTR_ERR(al_pcie->controller_base);
387	}
388
389	dev_dbg(dev, "From DT: dbi_base: %pR, controller_base: %pR\n",
390		dbi_res, controller_res);
391
392	platform_set_drvdata(pdev, al_pcie);
393
394	return al_add_pcie_port(&pci->pp, pdev);
395}
396
397static const struct of_device_id al_pcie_of_match[] = {
398	{ .compatible = "amazon,al-alpine-v2-pcie",
399	},
400	{ .compatible = "amazon,al-alpine-v3-pcie",
401	},
402	{},
403};
404
405static struct platform_driver al_pcie_driver = {
406	.driver = {
407		.name	= "al-pcie",
408		.of_match_table = al_pcie_of_match,
409		.suppress_bind_attrs = true,
410	},
411	.probe = al_pcie_probe,
412};
413builtin_platform_driver(al_pcie_driver);
414
415#endif /* CONFIG_PCIE_AL*/
416