1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2013 Imagination Technologies
4 * Author: Paul Burton <paul.burton@mips.com>
10 #include <pci_msc01.h>
13 #define PCI_ACCESS_READ 0
14 #define PCI_ACCESS_WRITE 1
16 struct msc01_pci_controller
{
17 struct pci_controller hose
;
21 static inline struct msc01_pci_controller
*
22 hose_to_msc01(struct pci_controller
*hose
)
24 return container_of(hose
, struct msc01_pci_controller
, hose
);
27 static int msc01_config_access(struct msc01_pci_controller
*msc01
,
28 unsigned char access_type
, pci_dev_t bdf
,
31 const u32 aborts
= MSC01_PCI_INTSTAT_MA_MSK
| MSC01_PCI_INTSTAT_TA_MSK
;
32 void *intstat
= msc01
->base
+ MSC01_PCI_INTSTAT_OFS
;
33 void *cfgdata
= msc01
->base
+ MSC01_PCI_CFGDATA_OFS
;
34 unsigned int bus
= PCI_BUS(bdf
);
35 unsigned int dev
= PCI_DEV(bdf
);
36 unsigned int devfn
= PCI_DEV(bdf
) << 3 | PCI_FUNC(bdf
);
38 /* clear abort status */
39 __raw_writel(aborts
, intstat
);
42 __raw_writel((bus
<< MSC01_PCI_CFGADDR_BNUM_SHF
) |
43 (dev
<< MSC01_PCI_CFGADDR_DNUM_SHF
) |
44 (devfn
<< MSC01_PCI_CFGADDR_FNUM_SHF
) |
45 ((where
/ 4) << MSC01_PCI_CFGADDR_RNUM_SHF
),
46 msc01
->base
+ MSC01_PCI_CFGADDR_OFS
);
49 if (access_type
== PCI_ACCESS_WRITE
)
50 __raw_writel(*data
, cfgdata
);
52 *data
= __raw_readl(cfgdata
);
54 /* check for aborts */
55 if (__raw_readl(intstat
) & aborts
) {
56 /* clear abort status */
57 __raw_writel(aborts
, intstat
);
64 static int msc01_read_config_dword(struct pci_controller
*hose
, pci_dev_t dev
,
65 int where
, u32
*value
)
67 struct msc01_pci_controller
*msc01
= hose_to_msc01(hose
);
70 return msc01_config_access(msc01
, PCI_ACCESS_READ
, dev
, where
, value
);
73 static int msc01_write_config_dword(struct pci_controller
*hose
, pci_dev_t dev
,
76 struct msc01_pci_controller
*gt
= hose_to_msc01(hose
);
79 return msc01_config_access(gt
, PCI_ACCESS_WRITE
, dev
, where
, &data
);
82 void msc01_pci_init(void *base
, unsigned long sys_bus
, unsigned long sys_phys
,
83 unsigned long sys_size
, unsigned long mem_bus
,
84 unsigned long mem_phys
, unsigned long mem_size
,
85 unsigned long io_bus
, unsigned long io_phys
,
86 unsigned long io_size
)
88 static struct msc01_pci_controller global_msc01
;
89 struct msc01_pci_controller
*msc01
;
90 struct pci_controller
*hose
;
92 msc01
= &global_msc01
;
97 hose
->first_busno
= 0;
100 /* System memory space */
101 pci_set_region(&hose
->regions
[0], sys_bus
, sys_phys
, sys_size
,
102 PCI_REGION_MEM
| PCI_REGION_SYS_MEMORY
);
104 /* PCI memory space */
105 pci_set_region(&hose
->regions
[1], mem_bus
, mem_phys
, mem_size
,
109 pci_set_region(&hose
->regions
[2], io_bus
, io_phys
, io_size
,
112 hose
->region_count
= 3;
115 pci_hose_read_config_byte_via_dword
,
116 pci_hose_read_config_word_via_dword
,
117 msc01_read_config_dword
,
118 pci_hose_write_config_byte_via_dword
,
119 pci_hose_write_config_word_via_dword
,
120 msc01_write_config_dword
);
122 pci_register_hose(hose
);
123 hose
->last_busno
= pci_hose_scan(hose
);