112d14e0eSGabor Juhos /* 212d14e0eSGabor Juhos * Ralink RT3662/RT3883 SoC PCI support 312d14e0eSGabor Juhos * 412d14e0eSGabor Juhos * Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org> 512d14e0eSGabor Juhos * 612d14e0eSGabor Juhos * Parts of this file are based on Ralink's 2.6.21 BSP 712d14e0eSGabor Juhos * 812d14e0eSGabor Juhos * This program is free software; you can redistribute it and/or modify it 912d14e0eSGabor Juhos * under the terms of the GNU General Public License version 2 as published 1012d14e0eSGabor Juhos * by the Free Software Foundation. 1112d14e0eSGabor Juhos */ 1212d14e0eSGabor Juhos 1312d14e0eSGabor Juhos #include <linux/types.h> 1412d14e0eSGabor Juhos #include <linux/pci.h> 1512d14e0eSGabor Juhos #include <linux/io.h> 1612d14e0eSGabor Juhos #include <linux/init.h> 1712d14e0eSGabor Juhos #include <linux/delay.h> 1812d14e0eSGabor Juhos #include <linux/interrupt.h> 1912d14e0eSGabor Juhos #include <linux/module.h> 2012d14e0eSGabor Juhos #include <linux/of.h> 2112d14e0eSGabor Juhos #include <linux/of_irq.h> 2212d14e0eSGabor Juhos #include <linux/of_pci.h> 2312d14e0eSGabor Juhos #include <linux/platform_device.h> 2412d14e0eSGabor Juhos 2512d14e0eSGabor Juhos #include <asm/mach-ralink/rt3883.h> 2612d14e0eSGabor Juhos #include <asm/mach-ralink/ralink_regs.h> 2712d14e0eSGabor Juhos 2812d14e0eSGabor Juhos #define RT3883_MEMORY_BASE 0x00000000 2912d14e0eSGabor Juhos #define RT3883_MEMORY_SIZE 0x02000000 3012d14e0eSGabor Juhos 3112d14e0eSGabor Juhos #define RT3883_PCI_REG_PCICFG 0x00 3212d14e0eSGabor Juhos #define RT3883_PCICFG_P2P_BR_DEVNUM_M 0xf 3312d14e0eSGabor Juhos #define RT3883_PCICFG_P2P_BR_DEVNUM_S 16 3412d14e0eSGabor Juhos #define RT3883_PCICFG_PCIRST BIT(1) 3512d14e0eSGabor Juhos #define RT3883_PCI_REG_PCIRAW 0x04 3612d14e0eSGabor Juhos #define RT3883_PCI_REG_PCIINT 0x08 3712d14e0eSGabor Juhos #define RT3883_PCI_REG_PCIENA 0x0c 3812d14e0eSGabor Juhos 3912d14e0eSGabor Juhos #define RT3883_PCI_REG_CFGADDR 0x20 4012d14e0eSGabor Juhos #define RT3883_PCI_REG_CFGDATA 0x24 4112d14e0eSGabor Juhos #define RT3883_PCI_REG_MEMBASE 0x28 4212d14e0eSGabor Juhos #define RT3883_PCI_REG_IOBASE 0x2c 4312d14e0eSGabor Juhos #define RT3883_PCI_REG_ARBCTL 0x80 4412d14e0eSGabor Juhos 4512d14e0eSGabor Juhos #define RT3883_PCI_REG_BASE(_x) (0x1000 + (_x) * 0x1000) 4612d14e0eSGabor Juhos #define RT3883_PCI_REG_BAR0SETUP(_x) (RT3883_PCI_REG_BASE((_x)) + 0x10) 4712d14e0eSGabor Juhos #define RT3883_PCI_REG_IMBASEBAR0(_x) (RT3883_PCI_REG_BASE((_x)) + 0x18) 4812d14e0eSGabor Juhos #define RT3883_PCI_REG_ID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x30) 4912d14e0eSGabor Juhos #define RT3883_PCI_REG_CLASS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x34) 5012d14e0eSGabor Juhos #define RT3883_PCI_REG_SUBID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x38) 5112d14e0eSGabor Juhos #define RT3883_PCI_REG_STATUS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x50) 5212d14e0eSGabor Juhos 5312d14e0eSGabor Juhos #define RT3883_PCI_MODE_NONE 0 5412d14e0eSGabor Juhos #define RT3883_PCI_MODE_PCI BIT(0) 5512d14e0eSGabor Juhos #define RT3883_PCI_MODE_PCIE BIT(1) 5612d14e0eSGabor Juhos #define RT3883_PCI_MODE_BOTH (RT3883_PCI_MODE_PCI | RT3883_PCI_MODE_PCIE) 5712d14e0eSGabor Juhos 5812d14e0eSGabor Juhos #define RT3883_PCI_IRQ_COUNT 32 5912d14e0eSGabor Juhos 6012d14e0eSGabor Juhos #define RT3883_P2P_BR_DEVNUM 1 6112d14e0eSGabor Juhos 6212d14e0eSGabor Juhos struct rt3883_pci_controller { 6312d14e0eSGabor Juhos void __iomem *base; 6412d14e0eSGabor Juhos spinlock_t lock; 6512d14e0eSGabor Juhos 6612d14e0eSGabor Juhos struct device_node *intc_of_node; 6712d14e0eSGabor Juhos struct irq_domain *irq_domain; 6812d14e0eSGabor Juhos 6912d14e0eSGabor Juhos struct pci_controller pci_controller; 7012d14e0eSGabor Juhos struct resource io_res; 7112d14e0eSGabor Juhos struct resource mem_res; 7212d14e0eSGabor Juhos 7312d14e0eSGabor Juhos bool pcie_ready; 7412d14e0eSGabor Juhos }; 7512d14e0eSGabor Juhos 7612d14e0eSGabor Juhos static inline struct rt3883_pci_controller * 7712d14e0eSGabor Juhos pci_bus_to_rt3883_controller(struct pci_bus *bus) 7812d14e0eSGabor Juhos { 7912d14e0eSGabor Juhos struct pci_controller *hose; 8012d14e0eSGabor Juhos 8112d14e0eSGabor Juhos hose = (struct pci_controller *) bus->sysdata; 8212d14e0eSGabor Juhos return container_of(hose, struct rt3883_pci_controller, pci_controller); 8312d14e0eSGabor Juhos } 8412d14e0eSGabor Juhos 8512d14e0eSGabor Juhos static inline u32 rt3883_pci_r32(struct rt3883_pci_controller *rpc, 8612d14e0eSGabor Juhos unsigned reg) 8712d14e0eSGabor Juhos { 8812d14e0eSGabor Juhos return ioread32(rpc->base + reg); 8912d14e0eSGabor Juhos } 9012d14e0eSGabor Juhos 9112d14e0eSGabor Juhos static inline void rt3883_pci_w32(struct rt3883_pci_controller *rpc, 9212d14e0eSGabor Juhos u32 val, unsigned reg) 9312d14e0eSGabor Juhos { 9412d14e0eSGabor Juhos iowrite32(val, rpc->base + reg); 9512d14e0eSGabor Juhos } 9612d14e0eSGabor Juhos 9712d14e0eSGabor Juhos static inline u32 rt3883_pci_get_cfgaddr(unsigned int bus, unsigned int slot, 9812d14e0eSGabor Juhos unsigned int func, unsigned int where) 9912d14e0eSGabor Juhos { 10012d14e0eSGabor Juhos return (bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | 10112d14e0eSGabor Juhos 0x80000000; 10212d14e0eSGabor Juhos } 10312d14e0eSGabor Juhos 10412d14e0eSGabor Juhos static u32 rt3883_pci_read_cfg32(struct rt3883_pci_controller *rpc, 10512d14e0eSGabor Juhos unsigned bus, unsigned slot, 10612d14e0eSGabor Juhos unsigned func, unsigned reg) 10712d14e0eSGabor Juhos { 10812d14e0eSGabor Juhos unsigned long flags; 10912d14e0eSGabor Juhos u32 address; 11012d14e0eSGabor Juhos u32 ret; 11112d14e0eSGabor Juhos 11212d14e0eSGabor Juhos address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); 11312d14e0eSGabor Juhos 11412d14e0eSGabor Juhos spin_lock_irqsave(&rpc->lock, flags); 11512d14e0eSGabor Juhos rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); 11612d14e0eSGabor Juhos ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); 11712d14e0eSGabor Juhos spin_unlock_irqrestore(&rpc->lock, flags); 11812d14e0eSGabor Juhos 11912d14e0eSGabor Juhos return ret; 12012d14e0eSGabor Juhos } 12112d14e0eSGabor Juhos 12212d14e0eSGabor Juhos static void rt3883_pci_write_cfg32(struct rt3883_pci_controller *rpc, 12312d14e0eSGabor Juhos unsigned bus, unsigned slot, 12412d14e0eSGabor Juhos unsigned func, unsigned reg, u32 val) 12512d14e0eSGabor Juhos { 12612d14e0eSGabor Juhos unsigned long flags; 12712d14e0eSGabor Juhos u32 address; 12812d14e0eSGabor Juhos 12912d14e0eSGabor Juhos address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); 13012d14e0eSGabor Juhos 13112d14e0eSGabor Juhos spin_lock_irqsave(&rpc->lock, flags); 13212d14e0eSGabor Juhos rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); 13312d14e0eSGabor Juhos rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA); 13412d14e0eSGabor Juhos spin_unlock_irqrestore(&rpc->lock, flags); 13512d14e0eSGabor Juhos } 13612d14e0eSGabor Juhos 13712d14e0eSGabor Juhos static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) 13812d14e0eSGabor Juhos { 13912d14e0eSGabor Juhos struct rt3883_pci_controller *rpc; 14012d14e0eSGabor Juhos u32 pending; 14112d14e0eSGabor Juhos 14212d14e0eSGabor Juhos rpc = irq_get_handler_data(irq); 14312d14e0eSGabor Juhos 14412d14e0eSGabor Juhos pending = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIINT) & 14512d14e0eSGabor Juhos rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); 14612d14e0eSGabor Juhos 14712d14e0eSGabor Juhos if (!pending) { 14812d14e0eSGabor Juhos spurious_interrupt(); 14912d14e0eSGabor Juhos return; 15012d14e0eSGabor Juhos } 15112d14e0eSGabor Juhos 15212d14e0eSGabor Juhos while (pending) { 15312d14e0eSGabor Juhos unsigned bit = __ffs(pending); 15412d14e0eSGabor Juhos 15512d14e0eSGabor Juhos irq = irq_find_mapping(rpc->irq_domain, bit); 15612d14e0eSGabor Juhos generic_handle_irq(irq); 15712d14e0eSGabor Juhos 15812d14e0eSGabor Juhos pending &= ~BIT(bit); 15912d14e0eSGabor Juhos } 16012d14e0eSGabor Juhos } 16112d14e0eSGabor Juhos 16212d14e0eSGabor Juhos static void rt3883_pci_irq_unmask(struct irq_data *d) 16312d14e0eSGabor Juhos { 16412d14e0eSGabor Juhos struct rt3883_pci_controller *rpc; 16512d14e0eSGabor Juhos u32 t; 16612d14e0eSGabor Juhos 16712d14e0eSGabor Juhos rpc = irq_data_get_irq_chip_data(d); 16812d14e0eSGabor Juhos 16912d14e0eSGabor Juhos t = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); 17012d14e0eSGabor Juhos rt3883_pci_w32(rpc, t | BIT(d->hwirq), RT3883_PCI_REG_PCIENA); 17112d14e0eSGabor Juhos /* flush write */ 17212d14e0eSGabor Juhos rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); 17312d14e0eSGabor Juhos } 17412d14e0eSGabor Juhos 17512d14e0eSGabor Juhos static void rt3883_pci_irq_mask(struct irq_data *d) 17612d14e0eSGabor Juhos { 17712d14e0eSGabor Juhos struct rt3883_pci_controller *rpc; 17812d14e0eSGabor Juhos u32 t; 17912d14e0eSGabor Juhos 18012d14e0eSGabor Juhos rpc = irq_data_get_irq_chip_data(d); 18112d14e0eSGabor Juhos 18212d14e0eSGabor Juhos t = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); 18312d14e0eSGabor Juhos rt3883_pci_w32(rpc, t & ~BIT(d->hwirq), RT3883_PCI_REG_PCIENA); 18412d14e0eSGabor Juhos /* flush write */ 18512d14e0eSGabor Juhos rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); 18612d14e0eSGabor Juhos } 18712d14e0eSGabor Juhos 18812d14e0eSGabor Juhos static struct irq_chip rt3883_pci_irq_chip = { 18912d14e0eSGabor Juhos .name = "RT3883 PCI", 19012d14e0eSGabor Juhos .irq_mask = rt3883_pci_irq_mask, 19112d14e0eSGabor Juhos .irq_unmask = rt3883_pci_irq_unmask, 19212d14e0eSGabor Juhos .irq_mask_ack = rt3883_pci_irq_mask, 19312d14e0eSGabor Juhos }; 19412d14e0eSGabor Juhos 19512d14e0eSGabor Juhos static int rt3883_pci_irq_map(struct irq_domain *d, unsigned int irq, 19612d14e0eSGabor Juhos irq_hw_number_t hw) 19712d14e0eSGabor Juhos { 19812d14e0eSGabor Juhos irq_set_chip_and_handler(irq, &rt3883_pci_irq_chip, handle_level_irq); 19912d14e0eSGabor Juhos irq_set_chip_data(irq, d->host_data); 20012d14e0eSGabor Juhos 20112d14e0eSGabor Juhos return 0; 20212d14e0eSGabor Juhos } 20312d14e0eSGabor Juhos 20412d14e0eSGabor Juhos static const struct irq_domain_ops rt3883_pci_irq_domain_ops = { 20512d14e0eSGabor Juhos .map = rt3883_pci_irq_map, 20612d14e0eSGabor Juhos .xlate = irq_domain_xlate_onecell, 20712d14e0eSGabor Juhos }; 20812d14e0eSGabor Juhos 20912d14e0eSGabor Juhos static int rt3883_pci_irq_init(struct device *dev, 21012d14e0eSGabor Juhos struct rt3883_pci_controller *rpc) 21112d14e0eSGabor Juhos { 21212d14e0eSGabor Juhos int irq; 21312d14e0eSGabor Juhos 21412d14e0eSGabor Juhos irq = irq_of_parse_and_map(rpc->intc_of_node, 0); 21512d14e0eSGabor Juhos if (irq == 0) { 21612d14e0eSGabor Juhos dev_err(dev, "%s has no IRQ", 21712d14e0eSGabor Juhos of_node_full_name(rpc->intc_of_node)); 21812d14e0eSGabor Juhos return -EINVAL; 21912d14e0eSGabor Juhos } 22012d14e0eSGabor Juhos 22112d14e0eSGabor Juhos /* disable all interrupts */ 22212d14e0eSGabor Juhos rt3883_pci_w32(rpc, 0, RT3883_PCI_REG_PCIENA); 22312d14e0eSGabor Juhos 22412d14e0eSGabor Juhos rpc->irq_domain = 22512d14e0eSGabor Juhos irq_domain_add_linear(rpc->intc_of_node, RT3883_PCI_IRQ_COUNT, 22612d14e0eSGabor Juhos &rt3883_pci_irq_domain_ops, 22712d14e0eSGabor Juhos rpc); 22812d14e0eSGabor Juhos if (!rpc->irq_domain) { 22912d14e0eSGabor Juhos dev_err(dev, "unable to add IRQ domain\n"); 23012d14e0eSGabor Juhos return -ENODEV; 23112d14e0eSGabor Juhos } 23212d14e0eSGabor Juhos 23312d14e0eSGabor Juhos irq_set_handler_data(irq, rpc); 23412d14e0eSGabor Juhos irq_set_chained_handler(irq, rt3883_pci_irq_handler); 23512d14e0eSGabor Juhos 23612d14e0eSGabor Juhos return 0; 23712d14e0eSGabor Juhos } 23812d14e0eSGabor Juhos 23912d14e0eSGabor Juhos static int rt3883_pci_config_read(struct pci_bus *bus, unsigned int devfn, 24012d14e0eSGabor Juhos int where, int size, u32 *val) 24112d14e0eSGabor Juhos { 24212d14e0eSGabor Juhos struct rt3883_pci_controller *rpc; 24312d14e0eSGabor Juhos unsigned long flags; 24412d14e0eSGabor Juhos u32 address; 24512d14e0eSGabor Juhos u32 data; 24612d14e0eSGabor Juhos 24712d14e0eSGabor Juhos rpc = pci_bus_to_rt3883_controller(bus); 24812d14e0eSGabor Juhos 24912d14e0eSGabor Juhos if (!rpc->pcie_ready && bus->number == 1) 25012d14e0eSGabor Juhos return PCIBIOS_DEVICE_NOT_FOUND; 25112d14e0eSGabor Juhos 25212d14e0eSGabor Juhos address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), 25312d14e0eSGabor Juhos PCI_FUNC(devfn), where); 25412d14e0eSGabor Juhos 25512d14e0eSGabor Juhos spin_lock_irqsave(&rpc->lock, flags); 25612d14e0eSGabor Juhos rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); 25712d14e0eSGabor Juhos data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); 25812d14e0eSGabor Juhos spin_unlock_irqrestore(&rpc->lock, flags); 25912d14e0eSGabor Juhos 26012d14e0eSGabor Juhos switch (size) { 26112d14e0eSGabor Juhos case 1: 26212d14e0eSGabor Juhos *val = (data >> ((where & 3) << 3)) & 0xff; 26312d14e0eSGabor Juhos break; 26412d14e0eSGabor Juhos case 2: 26512d14e0eSGabor Juhos *val = (data >> ((where & 3) << 3)) & 0xffff; 26612d14e0eSGabor Juhos break; 26712d14e0eSGabor Juhos case 4: 26812d14e0eSGabor Juhos *val = data; 26912d14e0eSGabor Juhos break; 27012d14e0eSGabor Juhos } 27112d14e0eSGabor Juhos 27212d14e0eSGabor Juhos return PCIBIOS_SUCCESSFUL; 27312d14e0eSGabor Juhos } 27412d14e0eSGabor Juhos 27512d14e0eSGabor Juhos static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn, 27612d14e0eSGabor Juhos int where, int size, u32 val) 27712d14e0eSGabor Juhos { 27812d14e0eSGabor Juhos struct rt3883_pci_controller *rpc; 27912d14e0eSGabor Juhos unsigned long flags; 28012d14e0eSGabor Juhos u32 address; 28112d14e0eSGabor Juhos u32 data; 28212d14e0eSGabor Juhos 28312d14e0eSGabor Juhos rpc = pci_bus_to_rt3883_controller(bus); 28412d14e0eSGabor Juhos 28512d14e0eSGabor Juhos if (!rpc->pcie_ready && bus->number == 1) 28612d14e0eSGabor Juhos return PCIBIOS_DEVICE_NOT_FOUND; 28712d14e0eSGabor Juhos 28812d14e0eSGabor Juhos address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), 28912d14e0eSGabor Juhos PCI_FUNC(devfn), where); 29012d14e0eSGabor Juhos 29112d14e0eSGabor Juhos spin_lock_irqsave(&rpc->lock, flags); 29212d14e0eSGabor Juhos rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); 29312d14e0eSGabor Juhos data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); 29412d14e0eSGabor Juhos 29512d14e0eSGabor Juhos switch (size) { 29612d14e0eSGabor Juhos case 1: 29712d14e0eSGabor Juhos data = (data & ~(0xff << ((where & 3) << 3))) | 29812d14e0eSGabor Juhos (val << ((where & 3) << 3)); 29912d14e0eSGabor Juhos break; 30012d14e0eSGabor Juhos case 2: 30112d14e0eSGabor Juhos data = (data & ~(0xffff << ((where & 3) << 3))) | 30212d14e0eSGabor Juhos (val << ((where & 3) << 3)); 30312d14e0eSGabor Juhos break; 30412d14e0eSGabor Juhos case 4: 30512d14e0eSGabor Juhos data = val; 30612d14e0eSGabor Juhos break; 30712d14e0eSGabor Juhos } 30812d14e0eSGabor Juhos 30912d14e0eSGabor Juhos rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA); 31012d14e0eSGabor Juhos spin_unlock_irqrestore(&rpc->lock, flags); 31112d14e0eSGabor Juhos 31212d14e0eSGabor Juhos return PCIBIOS_SUCCESSFUL; 31312d14e0eSGabor Juhos } 31412d14e0eSGabor Juhos 31512d14e0eSGabor Juhos static struct pci_ops rt3883_pci_ops = { 31612d14e0eSGabor Juhos .read = rt3883_pci_config_read, 31712d14e0eSGabor Juhos .write = rt3883_pci_config_write, 31812d14e0eSGabor Juhos }; 31912d14e0eSGabor Juhos 32012d14e0eSGabor Juhos static void rt3883_pci_preinit(struct rt3883_pci_controller *rpc, unsigned mode) 32112d14e0eSGabor Juhos { 32212d14e0eSGabor Juhos u32 syscfg1; 32312d14e0eSGabor Juhos u32 rstctrl; 32412d14e0eSGabor Juhos u32 clkcfg1; 32512d14e0eSGabor Juhos u32 t; 32612d14e0eSGabor Juhos 32712d14e0eSGabor Juhos rstctrl = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL); 32812d14e0eSGabor Juhos syscfg1 = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1); 32912d14e0eSGabor Juhos clkcfg1 = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1); 33012d14e0eSGabor Juhos 33112d14e0eSGabor Juhos if (mode & RT3883_PCI_MODE_PCIE) { 33212d14e0eSGabor Juhos rstctrl |= RT3883_RSTCTRL_PCIE; 33312d14e0eSGabor Juhos rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL); 33412d14e0eSGabor Juhos 33512d14e0eSGabor Juhos /* setup PCI PAD drive mode */ 33612d14e0eSGabor Juhos syscfg1 &= ~(0x30); 33712d14e0eSGabor Juhos syscfg1 |= (2 << 4); 33812d14e0eSGabor Juhos rt_sysc_w32(syscfg1, RT3883_SYSC_REG_SYSCFG1); 33912d14e0eSGabor Juhos 34012d14e0eSGabor Juhos t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0); 34112d14e0eSGabor Juhos t &= ~BIT(31); 34212d14e0eSGabor Juhos rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0); 34312d14e0eSGabor Juhos 34412d14e0eSGabor Juhos t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN1); 34512d14e0eSGabor Juhos t &= 0x80ffffff; 34612d14e0eSGabor Juhos rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN1); 34712d14e0eSGabor Juhos 34812d14e0eSGabor Juhos t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN1); 34912d14e0eSGabor Juhos t |= 0xa << 24; 35012d14e0eSGabor Juhos rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN1); 35112d14e0eSGabor Juhos 35212d14e0eSGabor Juhos t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0); 35312d14e0eSGabor Juhos t |= BIT(31); 35412d14e0eSGabor Juhos rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0); 35512d14e0eSGabor Juhos 35612d14e0eSGabor Juhos msleep(50); 35712d14e0eSGabor Juhos 35812d14e0eSGabor Juhos rstctrl &= ~RT3883_RSTCTRL_PCIE; 35912d14e0eSGabor Juhos rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL); 36012d14e0eSGabor Juhos } 36112d14e0eSGabor Juhos 36212d14e0eSGabor Juhos syscfg1 |= (RT3883_SYSCFG1_PCIE_RC_MODE | RT3883_SYSCFG1_PCI_HOST_MODE); 36312d14e0eSGabor Juhos 36412d14e0eSGabor Juhos clkcfg1 &= ~(RT3883_CLKCFG1_PCI_CLK_EN | RT3883_CLKCFG1_PCIE_CLK_EN); 36512d14e0eSGabor Juhos 36612d14e0eSGabor Juhos if (mode & RT3883_PCI_MODE_PCI) { 36712d14e0eSGabor Juhos clkcfg1 |= RT3883_CLKCFG1_PCI_CLK_EN; 36812d14e0eSGabor Juhos rstctrl &= ~RT3883_RSTCTRL_PCI; 36912d14e0eSGabor Juhos } 37012d14e0eSGabor Juhos 37112d14e0eSGabor Juhos if (mode & RT3883_PCI_MODE_PCIE) { 37212d14e0eSGabor Juhos clkcfg1 |= RT3883_CLKCFG1_PCIE_CLK_EN; 37312d14e0eSGabor Juhos rstctrl &= ~RT3883_RSTCTRL_PCIE; 37412d14e0eSGabor Juhos } 37512d14e0eSGabor Juhos 37612d14e0eSGabor Juhos rt_sysc_w32(syscfg1, RT3883_SYSC_REG_SYSCFG1); 37712d14e0eSGabor Juhos rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL); 37812d14e0eSGabor Juhos rt_sysc_w32(clkcfg1, RT3883_SYSC_REG_CLKCFG1); 37912d14e0eSGabor Juhos 38012d14e0eSGabor Juhos msleep(500); 38112d14e0eSGabor Juhos 38212d14e0eSGabor Juhos /* 38312d14e0eSGabor Juhos * setup the device number of the P2P bridge 38412d14e0eSGabor Juhos * and de-assert the reset line 38512d14e0eSGabor Juhos */ 38612d14e0eSGabor Juhos t = (RT3883_P2P_BR_DEVNUM << RT3883_PCICFG_P2P_BR_DEVNUM_S); 38712d14e0eSGabor Juhos rt3883_pci_w32(rpc, t, RT3883_PCI_REG_PCICFG); 38812d14e0eSGabor Juhos 38912d14e0eSGabor Juhos /* flush write */ 39012d14e0eSGabor Juhos rt3883_pci_r32(rpc, RT3883_PCI_REG_PCICFG); 39112d14e0eSGabor Juhos msleep(500); 39212d14e0eSGabor Juhos 39312d14e0eSGabor Juhos if (mode & RT3883_PCI_MODE_PCIE) { 39412d14e0eSGabor Juhos msleep(500); 39512d14e0eSGabor Juhos 39612d14e0eSGabor Juhos t = rt3883_pci_r32(rpc, RT3883_PCI_REG_STATUS(1)); 39712d14e0eSGabor Juhos 39812d14e0eSGabor Juhos rpc->pcie_ready = t & BIT(0); 39912d14e0eSGabor Juhos 40012d14e0eSGabor Juhos if (!rpc->pcie_ready) { 40112d14e0eSGabor Juhos /* reset the PCIe block */ 40212d14e0eSGabor Juhos t = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL); 40312d14e0eSGabor Juhos t |= RT3883_RSTCTRL_PCIE; 40412d14e0eSGabor Juhos rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL); 40512d14e0eSGabor Juhos t &= ~RT3883_RSTCTRL_PCIE; 40612d14e0eSGabor Juhos rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL); 40712d14e0eSGabor Juhos 40812d14e0eSGabor Juhos /* turn off PCIe clock */ 40912d14e0eSGabor Juhos t = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1); 41012d14e0eSGabor Juhos t &= ~RT3883_CLKCFG1_PCIE_CLK_EN; 41112d14e0eSGabor Juhos rt_sysc_w32(t, RT3883_SYSC_REG_CLKCFG1); 41212d14e0eSGabor Juhos 41312d14e0eSGabor Juhos t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0); 41412d14e0eSGabor Juhos t &= ~0xf000c080; 41512d14e0eSGabor Juhos rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0); 41612d14e0eSGabor Juhos } 41712d14e0eSGabor Juhos } 41812d14e0eSGabor Juhos 41912d14e0eSGabor Juhos /* enable PCI arbiter */ 42012d14e0eSGabor Juhos rt3883_pci_w32(rpc, 0x79, RT3883_PCI_REG_ARBCTL); 42112d14e0eSGabor Juhos } 42212d14e0eSGabor Juhos 42312d14e0eSGabor Juhos static int rt3883_pci_probe(struct platform_device *pdev) 42412d14e0eSGabor Juhos { 42512d14e0eSGabor Juhos struct rt3883_pci_controller *rpc; 42612d14e0eSGabor Juhos struct device *dev = &pdev->dev; 42712d14e0eSGabor Juhos struct device_node *np = dev->of_node; 42812d14e0eSGabor Juhos struct resource *res; 42912d14e0eSGabor Juhos struct device_node *child; 43012d14e0eSGabor Juhos u32 val; 43112d14e0eSGabor Juhos int err; 43212d14e0eSGabor Juhos int mode; 43312d14e0eSGabor Juhos 43412d14e0eSGabor Juhos rpc = devm_kzalloc(dev, sizeof(*rpc), GFP_KERNEL); 43512d14e0eSGabor Juhos if (!rpc) 43612d14e0eSGabor Juhos return -ENOMEM; 43712d14e0eSGabor Juhos 43812d14e0eSGabor Juhos res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 43912d14e0eSGabor Juhos if (!res) 44012d14e0eSGabor Juhos return -EINVAL; 44112d14e0eSGabor Juhos 44212d14e0eSGabor Juhos rpc->base = devm_ioremap_resource(dev, res); 44312d14e0eSGabor Juhos if (IS_ERR(rpc->base)) 44412d14e0eSGabor Juhos return PTR_ERR(rpc->base); 44512d14e0eSGabor Juhos 44612d14e0eSGabor Juhos /* find the interrupt controller child node */ 44712d14e0eSGabor Juhos for_each_child_of_node(np, child) { 44812d14e0eSGabor Juhos if (of_get_property(child, "interrupt-controller", NULL) && 44912d14e0eSGabor Juhos of_node_get(child)) { 45012d14e0eSGabor Juhos rpc->intc_of_node = child; 45112d14e0eSGabor Juhos break; 45212d14e0eSGabor Juhos } 45312d14e0eSGabor Juhos } 45412d14e0eSGabor Juhos 45512d14e0eSGabor Juhos if (!rpc->intc_of_node) { 45612d14e0eSGabor Juhos dev_err(dev, "%s has no %s child node", 45712d14e0eSGabor Juhos of_node_full_name(rpc->intc_of_node), 45812d14e0eSGabor Juhos "interrupt controller"); 45912d14e0eSGabor Juhos return -EINVAL; 46012d14e0eSGabor Juhos } 46112d14e0eSGabor Juhos 46212d14e0eSGabor Juhos /* find the PCI host bridge child node */ 46312d14e0eSGabor Juhos for_each_child_of_node(np, child) { 46412d14e0eSGabor Juhos if (child->type && 46512d14e0eSGabor Juhos of_node_cmp(child->type, "pci") == 0 && 46612d14e0eSGabor Juhos of_node_get(child)) { 46712d14e0eSGabor Juhos rpc->pci_controller.of_node = child; 46812d14e0eSGabor Juhos break; 46912d14e0eSGabor Juhos } 47012d14e0eSGabor Juhos } 47112d14e0eSGabor Juhos 47212d14e0eSGabor Juhos if (!rpc->pci_controller.of_node) { 47312d14e0eSGabor Juhos dev_err(dev, "%s has no %s child node", 47412d14e0eSGabor Juhos of_node_full_name(rpc->intc_of_node), 47512d14e0eSGabor Juhos "PCI host bridge"); 47612d14e0eSGabor Juhos err = -EINVAL; 47712d14e0eSGabor Juhos goto err_put_intc_node; 47812d14e0eSGabor Juhos } 47912d14e0eSGabor Juhos 48012d14e0eSGabor Juhos mode = RT3883_PCI_MODE_NONE; 48112d14e0eSGabor Juhos for_each_available_child_of_node(rpc->pci_controller.of_node, child) { 48212d14e0eSGabor Juhos int devfn; 48312d14e0eSGabor Juhos 48412d14e0eSGabor Juhos if (!child->type || 48512d14e0eSGabor Juhos of_node_cmp(child->type, "pci") != 0) 48612d14e0eSGabor Juhos continue; 48712d14e0eSGabor Juhos 48812d14e0eSGabor Juhos devfn = of_pci_get_devfn(child); 48912d14e0eSGabor Juhos if (devfn < 0) 49012d14e0eSGabor Juhos continue; 49112d14e0eSGabor Juhos 49212d14e0eSGabor Juhos switch (PCI_SLOT(devfn)) { 49312d14e0eSGabor Juhos case 1: 49412d14e0eSGabor Juhos mode |= RT3883_PCI_MODE_PCIE; 49512d14e0eSGabor Juhos break; 49612d14e0eSGabor Juhos 49712d14e0eSGabor Juhos case 17: 49812d14e0eSGabor Juhos case 18: 49912d14e0eSGabor Juhos mode |= RT3883_PCI_MODE_PCI; 50012d14e0eSGabor Juhos break; 50112d14e0eSGabor Juhos } 50212d14e0eSGabor Juhos } 50312d14e0eSGabor Juhos 50412d14e0eSGabor Juhos if (mode == RT3883_PCI_MODE_NONE) { 50512d14e0eSGabor Juhos dev_err(dev, "unable to determine PCI mode\n"); 50612d14e0eSGabor Juhos err = -EINVAL; 50712d14e0eSGabor Juhos goto err_put_hb_node; 50812d14e0eSGabor Juhos } 50912d14e0eSGabor Juhos 51012d14e0eSGabor Juhos dev_info(dev, "mode:%s%s\n", 51112d14e0eSGabor Juhos (mode & RT3883_PCI_MODE_PCI) ? " PCI" : "", 51212d14e0eSGabor Juhos (mode & RT3883_PCI_MODE_PCIE) ? " PCIe" : ""); 51312d14e0eSGabor Juhos 51412d14e0eSGabor Juhos rt3883_pci_preinit(rpc, mode); 51512d14e0eSGabor Juhos 51612d14e0eSGabor Juhos rpc->pci_controller.pci_ops = &rt3883_pci_ops; 51712d14e0eSGabor Juhos rpc->pci_controller.io_resource = &rpc->io_res; 51812d14e0eSGabor Juhos rpc->pci_controller.mem_resource = &rpc->mem_res; 51912d14e0eSGabor Juhos 52012d14e0eSGabor Juhos /* Load PCI I/O and memory resources from DT */ 52112d14e0eSGabor Juhos pci_load_of_ranges(&rpc->pci_controller, 52212d14e0eSGabor Juhos rpc->pci_controller.of_node); 52312d14e0eSGabor Juhos 52412d14e0eSGabor Juhos rt3883_pci_w32(rpc, rpc->mem_res.start, RT3883_PCI_REG_MEMBASE); 52512d14e0eSGabor Juhos rt3883_pci_w32(rpc, rpc->io_res.start, RT3883_PCI_REG_IOBASE); 52612d14e0eSGabor Juhos 52712d14e0eSGabor Juhos ioport_resource.start = rpc->io_res.start; 52812d14e0eSGabor Juhos ioport_resource.end = rpc->io_res.end; 52912d14e0eSGabor Juhos 53012d14e0eSGabor Juhos /* PCI */ 53112d14e0eSGabor Juhos rt3883_pci_w32(rpc, 0x03ff0000, RT3883_PCI_REG_BAR0SETUP(0)); 53212d14e0eSGabor Juhos rt3883_pci_w32(rpc, RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0(0)); 53312d14e0eSGabor Juhos rt3883_pci_w32(rpc, 0x08021814, RT3883_PCI_REG_ID(0)); 53412d14e0eSGabor Juhos rt3883_pci_w32(rpc, 0x00800001, RT3883_PCI_REG_CLASS(0)); 53512d14e0eSGabor Juhos rt3883_pci_w32(rpc, 0x28801814, RT3883_PCI_REG_SUBID(0)); 53612d14e0eSGabor Juhos 53712d14e0eSGabor Juhos /* PCIe */ 53812d14e0eSGabor Juhos rt3883_pci_w32(rpc, 0x03ff0000, RT3883_PCI_REG_BAR0SETUP(1)); 53912d14e0eSGabor Juhos rt3883_pci_w32(rpc, RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0(1)); 54012d14e0eSGabor Juhos rt3883_pci_w32(rpc, 0x08021814, RT3883_PCI_REG_ID(1)); 54112d14e0eSGabor Juhos rt3883_pci_w32(rpc, 0x06040001, RT3883_PCI_REG_CLASS(1)); 54212d14e0eSGabor Juhos rt3883_pci_w32(rpc, 0x28801814, RT3883_PCI_REG_SUBID(1)); 54312d14e0eSGabor Juhos 54412d14e0eSGabor Juhos err = rt3883_pci_irq_init(dev, rpc); 54512d14e0eSGabor Juhos if (err) 54612d14e0eSGabor Juhos goto err_put_hb_node; 54712d14e0eSGabor Juhos 54812d14e0eSGabor Juhos /* PCIe */ 54912d14e0eSGabor Juhos val = rt3883_pci_read_cfg32(rpc, 0, 0x01, 0, PCI_COMMAND); 55012d14e0eSGabor Juhos val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; 55112d14e0eSGabor Juhos rt3883_pci_write_cfg32(rpc, 0, 0x01, 0, PCI_COMMAND, val); 55212d14e0eSGabor Juhos 55312d14e0eSGabor Juhos /* PCI */ 55412d14e0eSGabor Juhos val = rt3883_pci_read_cfg32(rpc, 0, 0x00, 0, PCI_COMMAND); 55512d14e0eSGabor Juhos val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; 55612d14e0eSGabor Juhos rt3883_pci_write_cfg32(rpc, 0, 0x00, 0, PCI_COMMAND, val); 55712d14e0eSGabor Juhos 55812d14e0eSGabor Juhos if (mode == RT3883_PCI_MODE_PCIE) { 55912d14e0eSGabor Juhos rt3883_pci_w32(rpc, 0x03ff0001, RT3883_PCI_REG_BAR0SETUP(0)); 56012d14e0eSGabor Juhos rt3883_pci_w32(rpc, 0x03ff0001, RT3883_PCI_REG_BAR0SETUP(1)); 56112d14e0eSGabor Juhos 56212d14e0eSGabor Juhos rt3883_pci_write_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0, 56312d14e0eSGabor Juhos PCI_BASE_ADDRESS_0, 56412d14e0eSGabor Juhos RT3883_MEMORY_BASE); 56512d14e0eSGabor Juhos /* flush write */ 56612d14e0eSGabor Juhos rt3883_pci_read_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0, 56712d14e0eSGabor Juhos PCI_BASE_ADDRESS_0); 56812d14e0eSGabor Juhos } else { 56912d14e0eSGabor Juhos rt3883_pci_write_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0, 57012d14e0eSGabor Juhos PCI_IO_BASE, 0x00000101); 57112d14e0eSGabor Juhos } 57212d14e0eSGabor Juhos 57312d14e0eSGabor Juhos register_pci_controller(&rpc->pci_controller); 57412d14e0eSGabor Juhos 57512d14e0eSGabor Juhos return 0; 57612d14e0eSGabor Juhos 57712d14e0eSGabor Juhos err_put_hb_node: 57812d14e0eSGabor Juhos of_node_put(rpc->pci_controller.of_node); 57912d14e0eSGabor Juhos err_put_intc_node: 58012d14e0eSGabor Juhos of_node_put(rpc->intc_of_node); 58112d14e0eSGabor Juhos return err; 58212d14e0eSGabor Juhos } 58312d14e0eSGabor Juhos 58412d14e0eSGabor Juhos int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 58512d14e0eSGabor Juhos { 586*16b84e5aSGrant Likely return of_irq_parse_and_map_pci(dev, slot, pin); 58712d14e0eSGabor Juhos } 58812d14e0eSGabor Juhos 58912d14e0eSGabor Juhos int pcibios_plat_dev_init(struct pci_dev *dev) 59012d14e0eSGabor Juhos { 59112d14e0eSGabor Juhos return 0; 59212d14e0eSGabor Juhos } 59312d14e0eSGabor Juhos 59412d14e0eSGabor Juhos static const struct of_device_id rt3883_pci_ids[] = { 59512d14e0eSGabor Juhos { .compatible = "ralink,rt3883-pci" }, 59612d14e0eSGabor Juhos {}, 59712d14e0eSGabor Juhos }; 59812d14e0eSGabor Juhos MODULE_DEVICE_TABLE(of, rt3883_pci_ids); 59912d14e0eSGabor Juhos 60012d14e0eSGabor Juhos static struct platform_driver rt3883_pci_driver = { 60112d14e0eSGabor Juhos .probe = rt3883_pci_probe, 60212d14e0eSGabor Juhos .driver = { 60312d14e0eSGabor Juhos .name = "rt3883-pci", 60412d14e0eSGabor Juhos .owner = THIS_MODULE, 60512d14e0eSGabor Juhos .of_match_table = of_match_ptr(rt3883_pci_ids), 60612d14e0eSGabor Juhos }, 60712d14e0eSGabor Juhos }; 60812d14e0eSGabor Juhos 60912d14e0eSGabor Juhos static int __init rt3883_pci_init(void) 61012d14e0eSGabor Juhos { 61112d14e0eSGabor Juhos return platform_driver_register(&rt3883_pci_driver); 61212d14e0eSGabor Juhos } 61312d14e0eSGabor Juhos 61412d14e0eSGabor Juhos postcore_initcall(rt3883_pci_init); 615