1*71e2f4ddSJiaxun Yang // SPDX-License-Identifier: GPL-2.0-or-later
2*71e2f4ddSJiaxun Yang /*
3*71e2f4ddSJiaxun Yang * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
4*71e2f4ddSJiaxun Yang * Author: Fuxin Zhang, zhangfx@lemote.com
5*71e2f4ddSJiaxun Yang */
6*71e2f4ddSJiaxun Yang #include <linux/pci.h>
7*71e2f4ddSJiaxun Yang
8*71e2f4ddSJiaxun Yang #include <pci.h>
9*71e2f4ddSJiaxun Yang #include <loongson.h>
10*71e2f4ddSJiaxun Yang
11*71e2f4ddSJiaxun Yang static struct resource loongson_pci_mem_resource = {
12*71e2f4ddSJiaxun Yang .name = "pci memory space",
13*71e2f4ddSJiaxun Yang .start = LOONGSON_PCI_MEM_START,
14*71e2f4ddSJiaxun Yang .end = LOONGSON_PCI_MEM_END,
15*71e2f4ddSJiaxun Yang .flags = IORESOURCE_MEM,
16*71e2f4ddSJiaxun Yang };
17*71e2f4ddSJiaxun Yang
18*71e2f4ddSJiaxun Yang static struct resource loongson_pci_io_resource = {
19*71e2f4ddSJiaxun Yang .name = "pci io space",
20*71e2f4ddSJiaxun Yang .start = LOONGSON_PCI_IO_START,
21*71e2f4ddSJiaxun Yang .end = IO_SPACE_LIMIT,
22*71e2f4ddSJiaxun Yang .flags = IORESOURCE_IO,
23*71e2f4ddSJiaxun Yang };
24*71e2f4ddSJiaxun Yang
25*71e2f4ddSJiaxun Yang static struct pci_controller loongson_pci_controller = {
26*71e2f4ddSJiaxun Yang .pci_ops = &loongson_pci_ops,
27*71e2f4ddSJiaxun Yang .io_resource = &loongson_pci_io_resource,
28*71e2f4ddSJiaxun Yang .mem_resource = &loongson_pci_mem_resource,
29*71e2f4ddSJiaxun Yang .mem_offset = 0x00000000UL,
30*71e2f4ddSJiaxun Yang .io_offset = 0x00000000UL,
31*71e2f4ddSJiaxun Yang };
32*71e2f4ddSJiaxun Yang
setup_pcimap(void)33*71e2f4ddSJiaxun Yang static void __init setup_pcimap(void)
34*71e2f4ddSJiaxun Yang {
35*71e2f4ddSJiaxun Yang /*
36*71e2f4ddSJiaxun Yang * local to PCI mapping for CPU accessing PCI space
37*71e2f4ddSJiaxun Yang * CPU address space [256M,448M] is window for accessing pci space
38*71e2f4ddSJiaxun Yang * we set pcimap_lo[0,1,2] to map it to pci space[0M,64M], [320M,448M]
39*71e2f4ddSJiaxun Yang *
40*71e2f4ddSJiaxun Yang * pcimap: PCI_MAP2 PCI_Mem_Lo2 PCI_Mem_Lo1 PCI_Mem_Lo0
41*71e2f4ddSJiaxun Yang * [<2G] [384M,448M] [320M,384M] [0M,64M]
42*71e2f4ddSJiaxun Yang */
43*71e2f4ddSJiaxun Yang LOONGSON_PCIMAP = LOONGSON_PCIMAP_PCIMAP_2 |
44*71e2f4ddSJiaxun Yang LOONGSON_PCIMAP_WIN(2, LOONGSON_PCILO2_BASE) |
45*71e2f4ddSJiaxun Yang LOONGSON_PCIMAP_WIN(1, LOONGSON_PCILO1_BASE) |
46*71e2f4ddSJiaxun Yang LOONGSON_PCIMAP_WIN(0, 0);
47*71e2f4ddSJiaxun Yang
48*71e2f4ddSJiaxun Yang /*
49*71e2f4ddSJiaxun Yang * PCI-DMA to local mapping: [2G,2G+256M] -> [0M,256M]
50*71e2f4ddSJiaxun Yang */
51*71e2f4ddSJiaxun Yang LOONGSON_PCIBASE0 = 0x80000000ul; /* base: 2G -> mmap: 0M */
52*71e2f4ddSJiaxun Yang /* size: 256M, burst transmission, pre-fetch enable, 64bit */
53*71e2f4ddSJiaxun Yang LOONGSON_PCI_HIT0_SEL_L = 0xc000000cul;
54*71e2f4ddSJiaxun Yang LOONGSON_PCI_HIT0_SEL_H = 0xfffffffful;
55*71e2f4ddSJiaxun Yang LOONGSON_PCI_HIT1_SEL_L = 0x00000006ul; /* set this BAR as invalid */
56*71e2f4ddSJiaxun Yang LOONGSON_PCI_HIT1_SEL_H = 0x00000000ul;
57*71e2f4ddSJiaxun Yang LOONGSON_PCI_HIT2_SEL_L = 0x00000006ul; /* set this BAR as invalid */
58*71e2f4ddSJiaxun Yang LOONGSON_PCI_HIT2_SEL_H = 0x00000000ul;
59*71e2f4ddSJiaxun Yang
60*71e2f4ddSJiaxun Yang /* avoid deadlock of PCI reading/writing lock operation */
61*71e2f4ddSJiaxun Yang LOONGSON_PCI_ISR4C = 0xd2000001ul;
62*71e2f4ddSJiaxun Yang
63*71e2f4ddSJiaxun Yang /* can not change gnt to break pci transfer when device's gnt not
64*71e2f4ddSJiaxun Yang deassert for some broken device */
65*71e2f4ddSJiaxun Yang LOONGSON_PXARB_CFG = 0x00fe0105ul;
66*71e2f4ddSJiaxun Yang
67*71e2f4ddSJiaxun Yang #ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
68*71e2f4ddSJiaxun Yang /*
69*71e2f4ddSJiaxun Yang * set cpu addr window2 to map CPU address space to PCI address space
70*71e2f4ddSJiaxun Yang */
71*71e2f4ddSJiaxun Yang LOONGSON_ADDRWIN_CPUTOPCI(ADDRWIN_WIN2, LOONGSON_CPU_MEM_SRC,
72*71e2f4ddSJiaxun Yang LOONGSON_PCI_MEM_DST, MMAP_CPUTOPCI_SIZE);
73*71e2f4ddSJiaxun Yang #endif
74*71e2f4ddSJiaxun Yang }
75*71e2f4ddSJiaxun Yang
pcibios_init(void)76*71e2f4ddSJiaxun Yang static int __init pcibios_init(void)
77*71e2f4ddSJiaxun Yang {
78*71e2f4ddSJiaxun Yang setup_pcimap();
79*71e2f4ddSJiaxun Yang
80*71e2f4ddSJiaxun Yang loongson_pci_controller.io_map_base = mips_io_port_base;
81*71e2f4ddSJiaxun Yang register_pci_controller(&loongson_pci_controller);
82*71e2f4ddSJiaxun Yang
83*71e2f4ddSJiaxun Yang
84*71e2f4ddSJiaxun Yang return 0;
85*71e2f4ddSJiaxun Yang }
86*71e2f4ddSJiaxun Yang
87*71e2f4ddSJiaxun Yang arch_initcall(pcibios_init);
88