1*baf37f06SPaul Burton /* 2*baf37f06SPaul Burton * Copyright (C) 2013 Imagination Technologies 3*baf37f06SPaul Burton * Author: Paul Burton <paul.burton@imgtec.com> 4*baf37f06SPaul Burton * 5*baf37f06SPaul Burton * SPDX-License-Identifier: GPL-2.0+ 6*baf37f06SPaul Burton */ 7*baf37f06SPaul Burton 8*baf37f06SPaul Burton #include <common.h> 9*baf37f06SPaul Burton #include <msc01.h> 10*baf37f06SPaul Burton #include <pci.h> 11*baf37f06SPaul Burton #include <pci_msc01.h> 12*baf37f06SPaul Burton #include <asm/io.h> 13*baf37f06SPaul Burton 14*baf37f06SPaul Burton #define PCI_ACCESS_READ 0 15*baf37f06SPaul Burton #define PCI_ACCESS_WRITE 1 16*baf37f06SPaul Burton 17*baf37f06SPaul Burton struct msc01_pci_controller { 18*baf37f06SPaul Burton struct pci_controller hose; 19*baf37f06SPaul Burton void *base; 20*baf37f06SPaul Burton }; 21*baf37f06SPaul Burton 22*baf37f06SPaul Burton static inline struct msc01_pci_controller * 23*baf37f06SPaul Burton hose_to_msc01(struct pci_controller *hose) 24*baf37f06SPaul Burton { 25*baf37f06SPaul Burton return container_of(hose, struct msc01_pci_controller, hose); 26*baf37f06SPaul Burton } 27*baf37f06SPaul Burton 28*baf37f06SPaul Burton static int msc01_config_access(struct msc01_pci_controller *msc01, 29*baf37f06SPaul Burton unsigned char access_type, pci_dev_t bdf, 30*baf37f06SPaul Burton int where, u32 *data) 31*baf37f06SPaul Burton { 32*baf37f06SPaul Burton const u32 aborts = MSC01_PCI_INTSTAT_MA_MSK | MSC01_PCI_INTSTAT_TA_MSK; 33*baf37f06SPaul Burton void *intstat = msc01->base + MSC01_PCI_INTSTAT_OFS; 34*baf37f06SPaul Burton void *cfgdata = msc01->base + MSC01_PCI_CFGDATA_OFS; 35*baf37f06SPaul Burton unsigned int bus = PCI_BUS(bdf); 36*baf37f06SPaul Burton unsigned int dev = PCI_DEV(bdf); 37*baf37f06SPaul Burton unsigned int devfn = PCI_DEV(bdf) << 3 | PCI_FUNC(bdf); 38*baf37f06SPaul Burton 39*baf37f06SPaul Burton /* clear abort status */ 40*baf37f06SPaul Burton __raw_writel(aborts, intstat); 41*baf37f06SPaul Burton 42*baf37f06SPaul Burton /* setup address */ 43*baf37f06SPaul Burton __raw_writel((bus << MSC01_PCI_CFGADDR_BNUM_SHF) | 44*baf37f06SPaul Burton (dev << MSC01_PCI_CFGADDR_DNUM_SHF) | 45*baf37f06SPaul Burton (devfn << MSC01_PCI_CFGADDR_FNUM_SHF) | 46*baf37f06SPaul Burton ((where / 4) << MSC01_PCI_CFGADDR_RNUM_SHF), 47*baf37f06SPaul Burton msc01->base + MSC01_PCI_CFGADDR_OFS); 48*baf37f06SPaul Burton 49*baf37f06SPaul Burton /* perform access */ 50*baf37f06SPaul Burton if (access_type == PCI_ACCESS_WRITE) 51*baf37f06SPaul Burton __raw_writel(*data, cfgdata); 52*baf37f06SPaul Burton else 53*baf37f06SPaul Burton *data = __raw_readl(cfgdata); 54*baf37f06SPaul Burton 55*baf37f06SPaul Burton /* check for aborts */ 56*baf37f06SPaul Burton if (__raw_readl(intstat) & aborts) { 57*baf37f06SPaul Burton /* clear abort status */ 58*baf37f06SPaul Burton __raw_writel(aborts, intstat); 59*baf37f06SPaul Burton return -1; 60*baf37f06SPaul Burton } 61*baf37f06SPaul Burton 62*baf37f06SPaul Burton return 0; 63*baf37f06SPaul Burton } 64*baf37f06SPaul Burton 65*baf37f06SPaul Burton static int msc01_read_config_dword(struct pci_controller *hose, pci_dev_t dev, 66*baf37f06SPaul Burton int where, u32 *value) 67*baf37f06SPaul Burton { 68*baf37f06SPaul Burton struct msc01_pci_controller *msc01 = hose_to_msc01(hose); 69*baf37f06SPaul Burton 70*baf37f06SPaul Burton *value = 0xffffffff; 71*baf37f06SPaul Burton return msc01_config_access(msc01, PCI_ACCESS_READ, dev, where, value); 72*baf37f06SPaul Burton } 73*baf37f06SPaul Burton 74*baf37f06SPaul Burton static int msc01_write_config_dword(struct pci_controller *hose, pci_dev_t dev, 75*baf37f06SPaul Burton int where, u32 value) 76*baf37f06SPaul Burton { 77*baf37f06SPaul Burton struct msc01_pci_controller *gt = hose_to_msc01(hose); 78*baf37f06SPaul Burton u32 data = value; 79*baf37f06SPaul Burton 80*baf37f06SPaul Burton return msc01_config_access(gt, PCI_ACCESS_WRITE, dev, where, &data); 81*baf37f06SPaul Burton } 82*baf37f06SPaul Burton 83*baf37f06SPaul Burton void msc01_pci_init(void *base, unsigned long sys_bus, unsigned long sys_phys, 84*baf37f06SPaul Burton unsigned long sys_size, unsigned long mem_bus, 85*baf37f06SPaul Burton unsigned long mem_phys, unsigned long mem_size, 86*baf37f06SPaul Burton unsigned long io_bus, unsigned long io_phys, 87*baf37f06SPaul Burton unsigned long io_size) 88*baf37f06SPaul Burton { 89*baf37f06SPaul Burton static struct msc01_pci_controller global_msc01; 90*baf37f06SPaul Burton struct msc01_pci_controller *msc01; 91*baf37f06SPaul Burton struct pci_controller *hose; 92*baf37f06SPaul Burton 93*baf37f06SPaul Burton msc01 = &global_msc01; 94*baf37f06SPaul Burton msc01->base = base; 95*baf37f06SPaul Burton 96*baf37f06SPaul Burton hose = &msc01->hose; 97*baf37f06SPaul Burton 98*baf37f06SPaul Burton hose->first_busno = 0; 99*baf37f06SPaul Burton hose->last_busno = 0; 100*baf37f06SPaul Burton 101*baf37f06SPaul Burton /* System memory space */ 102*baf37f06SPaul Burton pci_set_region(&hose->regions[0], sys_bus, sys_phys, sys_size, 103*baf37f06SPaul Burton PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); 104*baf37f06SPaul Burton 105*baf37f06SPaul Burton /* PCI memory space */ 106*baf37f06SPaul Burton pci_set_region(&hose->regions[1], mem_bus, mem_phys, mem_size, 107*baf37f06SPaul Burton PCI_REGION_MEM); 108*baf37f06SPaul Burton 109*baf37f06SPaul Burton /* PCI I/O space */ 110*baf37f06SPaul Burton pci_set_region(&hose->regions[2], io_bus, io_phys, io_size, 111*baf37f06SPaul Burton PCI_REGION_IO); 112*baf37f06SPaul Burton 113*baf37f06SPaul Burton hose->region_count = 3; 114*baf37f06SPaul Burton 115*baf37f06SPaul Burton pci_set_ops(hose, 116*baf37f06SPaul Burton pci_hose_read_config_byte_via_dword, 117*baf37f06SPaul Burton pci_hose_read_config_word_via_dword, 118*baf37f06SPaul Burton msc01_read_config_dword, 119*baf37f06SPaul Burton pci_hose_write_config_byte_via_dword, 120*baf37f06SPaul Burton pci_hose_write_config_word_via_dword, 121*baf37f06SPaul Burton msc01_write_config_dword); 122*baf37f06SPaul Burton 123*baf37f06SPaul Burton pci_register_hose(hose); 124*baf37f06SPaul Burton hose->last_busno = pci_hose_scan(hose); 125*baf37f06SPaul Burton } 126