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