2 * Copyright (C) 2013 Imagination Technologies
3 * Author: Paul Burton <paul.burton@mips.com>
5 * SPDX-License-Identifier: GPL-2.0+
11 #include <pci_msc01.h>
14 #define PCI_ACCESS_READ 0
15 #define PCI_ACCESS_WRITE 1
17 struct msc01_pci_controller
{
18 struct pci_controller hose
;
22 static inline struct msc01_pci_controller
*
23 hose_to_msc01(struct pci_controller
*hose
)
25 return container_of(hose
, struct msc01_pci_controller
, hose
);
28 static int msc01_config_access(struct msc01_pci_controller
*msc01
,
29 unsigned char access_type
, pci_dev_t bdf
,
32 const u32 aborts
= MSC01_PCI_INTSTAT_MA_MSK
| MSC01_PCI_INTSTAT_TA_MSK
;
33 void *intstat
= msc01
->base
+ MSC01_PCI_INTSTAT_OFS
;
34 void *cfgdata
= msc01
->base
+ MSC01_PCI_CFGDATA_OFS
;
35 unsigned int bus
= PCI_BUS(bdf
);
36 unsigned int dev
= PCI_DEV(bdf
);
37 unsigned int devfn
= PCI_DEV(bdf
) << 3 | PCI_FUNC(bdf
);
39 /* clear abort status */
40 __raw_writel(aborts
, intstat
);
43 __raw_writel((bus
<< MSC01_PCI_CFGADDR_BNUM_SHF
) |
44 (dev
<< MSC01_PCI_CFGADDR_DNUM_SHF
) |
45 (devfn
<< MSC01_PCI_CFGADDR_FNUM_SHF
) |
46 ((where
/ 4) << MSC01_PCI_CFGADDR_RNUM_SHF
),
47 msc01
->base
+ MSC01_PCI_CFGADDR_OFS
);
50 if (access_type
== PCI_ACCESS_WRITE
)
51 __raw_writel(*data
, cfgdata
);
53 *data
= __raw_readl(cfgdata
);
55 /* check for aborts */
56 if (__raw_readl(intstat
) & aborts
) {
57 /* clear abort status */
58 __raw_writel(aborts
, intstat
);
65 static int msc01_read_config_dword(struct pci_controller
*hose
, pci_dev_t dev
,
66 int where
, u32
*value
)
68 struct msc01_pci_controller
*msc01
= hose_to_msc01(hose
);
71 return msc01_config_access(msc01
, PCI_ACCESS_READ
, dev
, where
, value
);
74 static int msc01_write_config_dword(struct pci_controller
*hose
, pci_dev_t dev
,
77 struct msc01_pci_controller
*gt
= hose_to_msc01(hose
);
80 return msc01_config_access(gt
, PCI_ACCESS_WRITE
, dev
, where
, &data
);
83 void msc01_pci_init(void *base
, unsigned long sys_bus
, unsigned long sys_phys
,
84 unsigned long sys_size
, unsigned long mem_bus
,
85 unsigned long mem_phys
, unsigned long mem_size
,
86 unsigned long io_bus
, unsigned long io_phys
,
87 unsigned long io_size
)
89 static struct msc01_pci_controller global_msc01
;
90 struct msc01_pci_controller
*msc01
;
91 struct pci_controller
*hose
;
93 msc01
= &global_msc01
;
98 hose
->first_busno
= 0;
101 /* System memory space */
102 pci_set_region(&hose
->regions
[0], sys_bus
, sys_phys
, sys_size
,
103 PCI_REGION_MEM
| PCI_REGION_SYS_MEMORY
);
105 /* PCI memory space */
106 pci_set_region(&hose
->regions
[1], mem_bus
, mem_phys
, mem_size
,
110 pci_set_region(&hose
->regions
[2], io_bus
, io_phys
, io_size
,
113 hose
->region_count
= 3;
116 pci_hose_read_config_byte_via_dword
,
117 pci_hose_read_config_word_via_dword
,
118 msc01_read_config_dword
,
119 pci_hose_write_config_byte_via_dword
,
120 pci_hose_write_config_word_via_dword
,
121 msc01_write_config_dword
);
123 pci_register_hose(hose
);
124 hose
->last_busno
= pci_hose_scan(hose
);