1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2013 Gabor Juhos <juhosg@openwrt.org> 4 * 5 * Based on the Linux implementation. 6 * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc. 7 * Authors: Carsten Langgaard <carstenl@mips.com> 8 * Maciej W. Rozycki <macro@mips.com> 9 */ 10 11 #include <common.h> 12 #include <gt64120.h> 13 #include <pci.h> 14 #include <pci_gt64120.h> 15 16 #include <asm/io.h> 17 18 #define PCI_ACCESS_READ 0 19 #define PCI_ACCESS_WRITE 1 20 21 struct gt64120_regs { 22 u8 unused_000[0xc18]; 23 u32 intrcause; 24 u8 unused_c1c[0x0dc]; 25 u32 pci0_cfgaddr; 26 u32 pci0_cfgdata; 27 }; 28 29 struct gt64120_pci_controller { 30 struct pci_controller hose; 31 struct gt64120_regs *regs; 32 }; 33 34 static inline struct gt64120_pci_controller * 35 hose_to_gt64120(struct pci_controller *hose) 36 { 37 return container_of(hose, struct gt64120_pci_controller, hose); 38 } 39 40 #define GT_INTRCAUSE_ABORT_BITS \ 41 (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT) 42 43 static int gt_config_access(struct gt64120_pci_controller *gt, 44 unsigned char access_type, pci_dev_t bdf, 45 int where, u32 *data) 46 { 47 unsigned int bus = PCI_BUS(bdf); 48 unsigned int dev = PCI_DEV(bdf); 49 unsigned int devfn = PCI_DEV(bdf) << 3 | PCI_FUNC(bdf); 50 u32 intr; 51 u32 addr; 52 u32 val; 53 54 if (bus == 0 && dev >= 31) { 55 /* Because of a bug in the galileo (for slot 31). */ 56 return -1; 57 } 58 59 if (access_type == PCI_ACCESS_WRITE) 60 debug("PCI WR %02x:%02x.%x reg:%02d data:%08x\n", 61 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), where, *data); 62 63 /* Clear cause register bits */ 64 writel(~GT_INTRCAUSE_ABORT_BITS, >->regs->intrcause); 65 66 addr = GT_PCI0_CFGADDR_CONFIGEN_BIT; 67 addr |= bus << GT_PCI0_CFGADDR_BUSNUM_SHF; 68 addr |= devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF; 69 addr |= (where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF; 70 71 /* Setup address */ 72 writel(addr, >->regs->pci0_cfgaddr); 73 74 if (access_type == PCI_ACCESS_WRITE) { 75 if (bus == 0 && dev == 0) { 76 /* 77 * The Galileo system controller is acting 78 * differently than other devices. 79 */ 80 val = *data; 81 } else { 82 val = cpu_to_le32(*data); 83 } 84 85 writel(val, >->regs->pci0_cfgdata); 86 } else { 87 val = readl(>->regs->pci0_cfgdata); 88 89 if (bus == 0 && dev == 0) { 90 /* 91 * The Galileo system controller is acting 92 * differently than other devices. 93 */ 94 *data = val; 95 } else { 96 *data = le32_to_cpu(val); 97 } 98 } 99 100 /* Check for master or target abort */ 101 intr = readl(>->regs->intrcause); 102 if (intr & GT_INTRCAUSE_ABORT_BITS) { 103 /* Error occurred, clear abort bits */ 104 writel(~GT_INTRCAUSE_ABORT_BITS, >->regs->intrcause); 105 return -1; 106 } 107 108 if (access_type == PCI_ACCESS_READ) 109 debug("PCI RD %02x:%02x.%x reg:%02d data:%08x\n", 110 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), where, *data); 111 112 return 0; 113 } 114 115 static int gt_read_config_dword(struct pci_controller *hose, pci_dev_t dev, 116 int where, u32 *value) 117 { 118 struct gt64120_pci_controller *gt = hose_to_gt64120(hose); 119 120 *value = 0xffffffff; 121 return gt_config_access(gt, PCI_ACCESS_READ, dev, where, value); 122 } 123 124 static int gt_write_config_dword(struct pci_controller *hose, pci_dev_t dev, 125 int where, u32 value) 126 { 127 struct gt64120_pci_controller *gt = hose_to_gt64120(hose); 128 u32 data = value; 129 130 return gt_config_access(gt, PCI_ACCESS_WRITE, dev, where, &data); 131 } 132 133 void gt64120_pci_init(void *regs, unsigned long sys_bus, unsigned long sys_phys, 134 unsigned long sys_size, unsigned long mem_bus, 135 unsigned long mem_phys, unsigned long mem_size, 136 unsigned long io_bus, unsigned long io_phys, 137 unsigned long io_size) 138 { 139 static struct gt64120_pci_controller global_gt; 140 struct gt64120_pci_controller *gt; 141 struct pci_controller *hose; 142 143 gt = &global_gt; 144 gt->regs = regs; 145 146 hose = >->hose; 147 148 hose->first_busno = 0; 149 hose->last_busno = 0; 150 151 /* System memory space */ 152 pci_set_region(&hose->regions[0], sys_bus, sys_phys, sys_size, 153 PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); 154 155 /* PCI memory space */ 156 pci_set_region(&hose->regions[1], mem_bus, mem_phys, mem_size, 157 PCI_REGION_MEM); 158 159 /* PCI I/O space */ 160 pci_set_region(&hose->regions[2], io_bus, io_phys, io_size, 161 PCI_REGION_IO); 162 163 hose->region_count = 3; 164 165 pci_set_ops(hose, 166 pci_hose_read_config_byte_via_dword, 167 pci_hose_read_config_word_via_dword, 168 gt_read_config_dword, 169 pci_hose_write_config_byte_via_dword, 170 pci_hose_write_config_word_via_dword, 171 gt_write_config_dword); 172 173 pci_register_hose(hose); 174 hose->last_busno = pci_hose_scan(hose); 175 } 176