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

MIPS: ralink: add rt2880 pci driver

Signed-off-by: John Crispin <blogic@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/8034/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

John Crispin and committed by
Ralf Baechle
187c26dd b96e6e9f

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