Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.8-rc2 280 lines 7.4 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Ralink RT288x SoC PCI register definitions 4 * 5 * Copyright (C) 2009 John Crispin <john@phrozen.org> 6 * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> 7 * 8 * Parts of this file are based on Ralink's 2.6.21 BSP 9 */ 10 11#include <linux/delay.h> 12#include <linux/types.h> 13#include <linux/pci.h> 14#include <linux/io.h> 15#include <linux/init.h> 16#include <linux/of_platform.h> 17#include <linux/of_irq.h> 18#include <linux/of_pci.h> 19 20#include <asm/mach-ralink/rt288x.h> 21 22#define RT2880_PCI_BASE 0x00440000 23#define RT288X_CPU_IRQ_PCI 4 24 25#define RT2880_PCI_MEM_BASE 0x20000000 26#define RT2880_PCI_MEM_SIZE 0x10000000 27#define RT2880_PCI_IO_BASE 0x00460000 28#define RT2880_PCI_IO_SIZE 0x00010000 29 30#define RT2880_PCI_REG_PCICFG_ADDR 0x00 31#define RT2880_PCI_REG_PCIMSK_ADDR 0x0c 32#define RT2880_PCI_REG_BAR0SETUP_ADDR 0x10 33#define RT2880_PCI_REG_IMBASEBAR0_ADDR 0x18 34#define RT2880_PCI_REG_CONFIG_ADDR 0x20 35#define RT2880_PCI_REG_CONFIG_DATA 0x24 36#define RT2880_PCI_REG_MEMBASE 0x28 37#define RT2880_PCI_REG_IOBASE 0x2c 38#define RT2880_PCI_REG_ID 0x30 39#define RT2880_PCI_REG_CLASS 0x34 40#define RT2880_PCI_REG_SUBID 0x38 41#define RT2880_PCI_REG_ARBCTL 0x80 42 43static void __iomem *rt2880_pci_base; 44static DEFINE_SPINLOCK(rt2880_pci_lock); 45 46static u32 rt2880_pci_reg_read(u32 reg) 47{ 48 return readl(rt2880_pci_base + reg); 49} 50 51static void rt2880_pci_reg_write(u32 val, u32 reg) 52{ 53 writel(val, rt2880_pci_base + reg); 54} 55 56static inline u32 rt2880_pci_get_cfgaddr(unsigned int bus, unsigned int slot, 57 unsigned int func, unsigned int where) 58{ 59 return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | 60 0x80000000); 61} 62 63static int rt2880_pci_config_read(struct pci_bus *bus, unsigned int devfn, 64 int where, int size, u32 *val) 65{ 66 unsigned long flags; 67 u32 address; 68 u32 data; 69 70 address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), 71 PCI_FUNC(devfn), where); 72 73 spin_lock_irqsave(&rt2880_pci_lock, flags); 74 rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); 75 data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); 76 spin_unlock_irqrestore(&rt2880_pci_lock, flags); 77 78 switch (size) { 79 case 1: 80 *val = (data >> ((where & 3) << 3)) & 0xff; 81 break; 82 case 2: 83 *val = (data >> ((where & 3) << 3)) & 0xffff; 84 break; 85 case 4: 86 *val = data; 87 break; 88 } 89 90 return PCIBIOS_SUCCESSFUL; 91} 92 93static int rt2880_pci_config_write(struct pci_bus *bus, unsigned int devfn, 94 int where, int size, u32 val) 95{ 96 unsigned long flags; 97 u32 address; 98 u32 data; 99 100 address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), 101 PCI_FUNC(devfn), where); 102 103 spin_lock_irqsave(&rt2880_pci_lock, flags); 104 rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); 105 data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); 106 107 switch (size) { 108 case 1: 109 data = (data & ~(0xff << ((where & 3) << 3))) | 110 (val << ((where & 3) << 3)); 111 break; 112 case 2: 113 data = (data & ~(0xffff << ((where & 3) << 3))) | 114 (val << ((where & 3) << 3)); 115 break; 116 case 4: 117 data = val; 118 break; 119 } 120 121 rt2880_pci_reg_write(data, RT2880_PCI_REG_CONFIG_DATA); 122 spin_unlock_irqrestore(&rt2880_pci_lock, flags); 123 124 return PCIBIOS_SUCCESSFUL; 125} 126 127static struct pci_ops rt2880_pci_ops = { 128 .read = rt2880_pci_config_read, 129 .write = rt2880_pci_config_write, 130}; 131 132static struct resource rt2880_pci_mem_resource = { 133 .name = "PCI MEM space", 134 .start = RT2880_PCI_MEM_BASE, 135 .end = RT2880_PCI_MEM_BASE + RT2880_PCI_MEM_SIZE - 1, 136 .flags = IORESOURCE_MEM, 137}; 138 139static struct resource rt2880_pci_io_resource = { 140 .name = "PCI IO space", 141 .start = RT2880_PCI_IO_BASE, 142 .end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1, 143 .flags = IORESOURCE_IO, 144}; 145 146static struct pci_controller rt2880_pci_controller = { 147 .pci_ops = &rt2880_pci_ops, 148 .mem_resource = &rt2880_pci_mem_resource, 149 .io_resource = &rt2880_pci_io_resource, 150}; 151 152static inline u32 rt2880_pci_read_u32(unsigned long reg) 153{ 154 unsigned long flags; 155 u32 address; 156 u32 ret; 157 158 address = rt2880_pci_get_cfgaddr(0, 0, 0, reg); 159 160 spin_lock_irqsave(&rt2880_pci_lock, flags); 161 rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); 162 ret = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); 163 spin_unlock_irqrestore(&rt2880_pci_lock, flags); 164 165 return ret; 166} 167 168static inline void rt2880_pci_write_u32(unsigned long reg, u32 val) 169{ 170 unsigned long flags; 171 u32 address; 172 173 address = rt2880_pci_get_cfgaddr(0, 0, 0, reg); 174 175 spin_lock_irqsave(&rt2880_pci_lock, flags); 176 rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); 177 rt2880_pci_reg_write(val, RT2880_PCI_REG_CONFIG_DATA); 178 spin_unlock_irqrestore(&rt2880_pci_lock, flags); 179} 180 181int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 182{ 183 u16 cmd; 184 int irq = -1; 185 186 if (dev->bus->number != 0) 187 return irq; 188 189 switch (PCI_SLOT(dev->devfn)) { 190 case 0x00: 191 rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); 192 (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); 193 break; 194 case 0x11: 195 irq = RT288X_CPU_IRQ_PCI; 196 break; 197 default: 198 pr_err("%s:%s[%d] trying to alloc unknown pci irq\n", 199 __FILE__, __func__, __LINE__); 200 BUG(); 201 break; 202 } 203 204 pci_write_config_byte((struct pci_dev *) dev, 205 PCI_CACHE_LINE_SIZE, 0x14); 206 pci_write_config_byte((struct pci_dev *) dev, PCI_LATENCY_TIMER, 0xFF); 207 pci_read_config_word((struct pci_dev *) dev, PCI_COMMAND, &cmd); 208 cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | 209 PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK | 210 PCI_COMMAND_SERR | PCI_COMMAND_WAIT | PCI_COMMAND_PARITY; 211 pci_write_config_word((struct pci_dev *) dev, PCI_COMMAND, cmd); 212 pci_write_config_byte((struct pci_dev *) dev, PCI_INTERRUPT_LINE, 213 dev->irq); 214 return irq; 215} 216 217static int rt288x_pci_probe(struct platform_device *pdev) 218{ 219 void __iomem *io_map_base; 220 221 rt2880_pci_base = ioremap(RT2880_PCI_BASE, PAGE_SIZE); 222 223 io_map_base = ioremap(RT2880_PCI_IO_BASE, RT2880_PCI_IO_SIZE); 224 rt2880_pci_controller.io_map_base = (unsigned long) io_map_base; 225 set_io_port_base((unsigned long) io_map_base); 226 227 ioport_resource.start = RT2880_PCI_IO_BASE; 228 ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1; 229 230 rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR); 231 udelay(1); 232 233 rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL); 234 rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR); 235 rt2880_pci_reg_write(RT2880_PCI_MEM_BASE, RT2880_PCI_REG_MEMBASE); 236 rt2880_pci_reg_write(RT2880_PCI_IO_BASE, RT2880_PCI_REG_IOBASE); 237 rt2880_pci_reg_write(0x08000000, RT2880_PCI_REG_IMBASEBAR0_ADDR); 238 rt2880_pci_reg_write(0x08021814, RT2880_PCI_REG_ID); 239 rt2880_pci_reg_write(0x00800001, RT2880_PCI_REG_CLASS); 240 rt2880_pci_reg_write(0x28801814, RT2880_PCI_REG_SUBID); 241 rt2880_pci_reg_write(0x000c0000, RT2880_PCI_REG_PCIMSK_ADDR); 242 243 rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); 244 (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); 245 246 rt2880_pci_controller.of_node = pdev->dev.of_node; 247 248 register_pci_controller(&rt2880_pci_controller); 249 return 0; 250} 251 252int pcibios_plat_dev_init(struct pci_dev *dev) 253{ 254 return 0; 255} 256 257static const struct of_device_id rt288x_pci_match[] = { 258 { .compatible = "ralink,rt288x-pci" }, 259 {}, 260}; 261 262static struct platform_driver rt288x_pci_driver = { 263 .probe = rt288x_pci_probe, 264 .driver = { 265 .name = "rt288x-pci", 266 .of_match_table = rt288x_pci_match, 267 }, 268}; 269 270int __init pcibios_init(void) 271{ 272 int ret = platform_driver_register(&rt288x_pci_driver); 273 274 if (ret) 275 pr_info("rt288x-pci: Error registering platform driver!"); 276 277 return ret; 278} 279 280arch_initcall(pcibios_init);