1 // SPDX-License-Identifier: GPL-2.0-only
3 * PCI-E support for CNS3xxx
5 * Copyright 2008 Cavium Networks
6 * Richard Liu <richard.liu@caviumnetworks.com>
7 * Copyright 2010 MontaVista Software, LLC.
8 * Anton Vorontsov <avorontsov@mvista.com>
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/bug.h>
14 #include <linux/pci.h>
16 #include <linux/ioport.h>
17 #include <linux/interrupt.h>
18 #include <linux/ptrace.h>
19 #include <asm/mach/map.h>
24 void __iomem
*host_regs
; /* PCI config registers for host bridge */
25 void __iomem
*cfg0_regs
; /* PCI Type 0 config registers */
26 void __iomem
*cfg1_regs
; /* PCI Type 1 config registers */
28 struct resource res_io
;
29 struct resource res_mem
;
34 static struct cns3xxx_pcie
*sysdata_to_cnspci(void *sysdata
)
36 struct pci_sys_data
*root
= sysdata
;
38 return root
->private_data
;
41 static struct cns3xxx_pcie
*pdev_to_cnspci(const struct pci_dev
*dev
)
43 return sysdata_to_cnspci(dev
->sysdata
);
46 static struct cns3xxx_pcie
*pbus_to_cnspci(struct pci_bus
*bus
)
48 return sysdata_to_cnspci(bus
->sysdata
);
51 static void __iomem
*cns3xxx_pci_map_bus(struct pci_bus
*bus
,
52 unsigned int devfn
, int where
)
54 struct cns3xxx_pcie
*cnspci
= pbus_to_cnspci(bus
);
55 int busno
= bus
->number
;
56 int slot
= PCI_SLOT(devfn
);
59 /* If there is no link, just show the CNS PCI bridge. */
60 if (!cnspci
->linked
&& busno
> 0)
64 * The CNS PCI bridge doesn't fit into the PCI hierarchy, though
65 * we still want to access it.
66 * We place the host bridge on bus 0, and the directly connected
67 * device on bus 1, slot 0.
69 if (busno
== 0) { /* internal PCIe bus, host bridge device */
70 if (devfn
== 0) /* device# and function# are ignored by hw */
71 base
= cnspci
->host_regs
;
73 return NULL
; /* no such device */
75 } else if (busno
== 1) { /* directly connected PCIe device */
76 if (slot
== 0) /* device# is ignored by hw */
77 base
= cnspci
->cfg0_regs
;
79 return NULL
; /* no such device */
80 } else /* remote PCI bus */
81 base
= cnspci
->cfg1_regs
+ ((busno
& 0xf) << 20);
83 return base
+ where
+ (devfn
<< 12);
86 static int cns3xxx_pci_read_config(struct pci_bus
*bus
, unsigned int devfn
,
87 int where
, int size
, u32
*val
)
90 u32 mask
= (0x1ull
<< (size
* 8)) - 1;
91 int shift
= (where
% 4) * 8;
93 ret
= pci_generic_config_read(bus
, devfn
, where
, size
, val
);
95 if (ret
== PCIBIOS_SUCCESSFUL
&& !bus
->number
&& !devfn
&&
96 (where
& 0xffc) == PCI_CLASS_REVISION
)
98 * RC's class is 0xb, but Linux PCI driver needs 0x604
99 * for a PCIe bridge. So we must fixup the class code
102 *val
= ((((*val
<< shift
) & 0xff) | (0x604 << 16)) >> shift
) & mask
;
107 static int cns3xxx_pci_setup(int nr
, struct pci_sys_data
*sys
)
109 struct cns3xxx_pcie
*cnspci
= sysdata_to_cnspci(sys
);
110 struct resource
*res_io
= &cnspci
->res_io
;
111 struct resource
*res_mem
= &cnspci
->res_mem
;
113 BUG_ON(request_resource(&iomem_resource
, res_io
) ||
114 request_resource(&iomem_resource
, res_mem
));
116 pci_add_resource_offset(&sys
->resources
, res_io
, sys
->io_offset
);
117 pci_add_resource_offset(&sys
->resources
, res_mem
, sys
->mem_offset
);
122 static struct pci_ops cns3xxx_pcie_ops
= {
123 .map_bus
= cns3xxx_pci_map_bus
,
124 .read
= cns3xxx_pci_read_config
,
125 .write
= pci_generic_config_write
,
128 static int cns3xxx_pcie_map_irq(const struct pci_dev
*dev
, u8 slot
, u8 pin
)
130 struct cns3xxx_pcie
*cnspci
= pdev_to_cnspci(dev
);
131 int irq
= cnspci
->irqs
[!!dev
->bus
->number
];
133 pr_info("PCIe map irq: %04d:%02x:%02x.%02x slot %d, pin %d, irq: %d\n",
134 pci_domain_nr(dev
->bus
), dev
->bus
->number
, PCI_SLOT(dev
->devfn
),
135 PCI_FUNC(dev
->devfn
), slot
, pin
, irq
);
140 static struct cns3xxx_pcie cns3xxx_pcie
[] = {
142 .host_regs
= (void __iomem
*)CNS3XXX_PCIE0_HOST_BASE_VIRT
,
143 .cfg0_regs
= (void __iomem
*)CNS3XXX_PCIE0_CFG0_BASE_VIRT
,
144 .cfg1_regs
= (void __iomem
*)CNS3XXX_PCIE0_CFG1_BASE_VIRT
,
146 .name
= "PCIe0 I/O space",
147 .start
= CNS3XXX_PCIE0_IO_BASE
,
148 .end
= CNS3XXX_PCIE0_CFG0_BASE
- 1, /* 16 MiB */
149 .flags
= IORESOURCE_IO
,
152 .name
= "PCIe0 non-prefetchable",
153 .start
= CNS3XXX_PCIE0_MEM_BASE
,
154 .end
= CNS3XXX_PCIE0_HOST_BASE
- 1, /* 176 MiB */
155 .flags
= IORESOURCE_MEM
,
157 .irqs
= { IRQ_CNS3XXX_PCIE0_RC
, IRQ_CNS3XXX_PCIE0_DEVICE
, },
161 .host_regs
= (void __iomem
*)CNS3XXX_PCIE1_HOST_BASE_VIRT
,
162 .cfg0_regs
= (void __iomem
*)CNS3XXX_PCIE1_CFG0_BASE_VIRT
,
163 .cfg1_regs
= (void __iomem
*)CNS3XXX_PCIE1_CFG1_BASE_VIRT
,
165 .name
= "PCIe1 I/O space",
166 .start
= CNS3XXX_PCIE1_IO_BASE
,
167 .end
= CNS3XXX_PCIE1_CFG0_BASE
- 1, /* 16 MiB */
168 .flags
= IORESOURCE_IO
,
171 .name
= "PCIe1 non-prefetchable",
172 .start
= CNS3XXX_PCIE1_MEM_BASE
,
173 .end
= CNS3XXX_PCIE1_HOST_BASE
- 1, /* 176 MiB */
174 .flags
= IORESOURCE_MEM
,
176 .irqs
= { IRQ_CNS3XXX_PCIE1_RC
, IRQ_CNS3XXX_PCIE1_DEVICE
, },
181 static void __init
cns3xxx_pcie_check_link(struct cns3xxx_pcie
*cnspci
)
183 int port
= cnspci
->port
;
187 reg
= __raw_readl(MISC_PCIE_CTRL(port
));
189 * Enable Application Request to 1, it will exit L1 automatically,
190 * but when chip back, it will use another clock, still can use 0x1.
193 __raw_writel(reg
, MISC_PCIE_CTRL(port
));
195 pr_info("PCIe: Port[%d] Enable PCIe LTSSM\n", port
);
196 pr_info("PCIe: Port[%d] Check data link layer...", port
);
200 reg
= __raw_readl(MISC_PCIE_PM_DEBUG(port
));
202 pr_info("Link up.\n");
205 } else if (time_after(jiffies
, time
+ 50)) {
206 pr_info("Device not found.\n");
212 static void cns3xxx_write_config(struct cns3xxx_pcie
*cnspci
,
213 int where
, int size
, u32 val
)
215 void __iomem
*base
= cnspci
->host_regs
+ (where
& 0xffc);
217 u32 mask
= (0x1ull
<< (size
* 8)) - 1;
218 int shift
= (where
% 4) * 8;
220 v
= readl_relaxed(base
);
222 v
&= ~(mask
<< shift
);
223 v
|= (val
& mask
) << shift
;
225 writel_relaxed(v
, base
);
229 static void __init
cns3xxx_pcie_hw_init(struct cns3xxx_pcie
*cnspci
)
231 u16 mem_base
= cnspci
->res_mem
.start
>> 16;
232 u16 mem_limit
= cnspci
->res_mem
.end
>> 16;
233 u16 io_base
= cnspci
->res_io
.start
>> 16;
234 u16 io_limit
= cnspci
->res_io
.end
>> 16;
236 cns3xxx_write_config(cnspci
, PCI_PRIMARY_BUS
, 1, 0);
237 cns3xxx_write_config(cnspci
, PCI_SECONDARY_BUS
, 1, 1);
238 cns3xxx_write_config(cnspci
, PCI_SUBORDINATE_BUS
, 1, 1);
239 cns3xxx_write_config(cnspci
, PCI_MEMORY_BASE
, 2, mem_base
);
240 cns3xxx_write_config(cnspci
, PCI_MEMORY_LIMIT
, 2, mem_limit
);
241 cns3xxx_write_config(cnspci
, PCI_IO_BASE_UPPER16
, 2, io_base
);
242 cns3xxx_write_config(cnspci
, PCI_IO_LIMIT_UPPER16
, 2, io_limit
);
247 /* Set Device Max_Read_Request_Size to 128 byte */
248 pcie_bus_config
= PCIE_BUS_PEER2PEER
;
250 /* Disable PCIe0 Interrupt Mask INTA to INTD */
251 __raw_writel(~0x3FFF, MISC_PCIE_INT_MASK(cnspci
->port
));
254 static int cns3xxx_pcie_abort_handler(unsigned long addr
, unsigned int fsr
,
255 struct pt_regs
*regs
)
262 void __init
cns3xxx_pcie_init_late(void)
266 struct hw_pci hw_pci
= {
268 .ops
= &cns3xxx_pcie_ops
,
269 .setup
= cns3xxx_pci_setup
,
270 .map_irq
= cns3xxx_pcie_map_irq
,
271 .private_data
= &private_data
,
277 hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler
, SIGBUS
, 0,
278 "imprecise external abort");
280 for (i
= 0; i
< ARRAY_SIZE(cns3xxx_pcie
); i
++) {
281 cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_PCIE(i
));
282 cns3xxx_pwr_soft_rst(0x1 << PM_SOFT_RST_REG_OFFST_PCIE(i
));
283 cns3xxx_pcie_check_link(&cns3xxx_pcie
[i
]);
284 cns3xxx_pcie_hw_init(&cns3xxx_pcie
[i
]);
285 private_data
= &cns3xxx_pcie
[i
];
286 pci_common_init(&hw_pci
);
289 pci_assign_unassigned_resources();