From d19648d7f3b047bac9922fe097f62afbb48fee62 Mon Sep 17 00:00:00 2001 From: Eunbong Song Date: Fri, 11 Apr 2014 08:32:54 +0000 Subject: MIPS: Octeon: Add PCIe2 support in arch_setup_msi_irq() In arch_setup_msi_irq(), there is no case for PCIe2. So board which have PCIe2 functionality fails to boot with "Kernel panic - not syncing: arch_setup_msi_irq: Invalid octeon_dma_bar_type" message. This patch solve this problem. Signed-off-by: Eunbong Song Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/6747/ Signed-off-by: Ralf Baechle --- arch/mips/pci/msi-octeon.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/mips/pci') diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c index 2b91b0e61566..ab0c5d14c6f7 100644 --- a/arch/mips/pci/msi-octeon.c +++ b/arch/mips/pci/msi-octeon.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -162,6 +163,11 @@ msi_irq_allocated: msg.address_lo = (0 + CVMX_NPEI_PCIE_MSI_RCV) & 0xffffffff; msg.address_hi = (0 + CVMX_NPEI_PCIE_MSI_RCV) >> 32; break; + case OCTEON_DMA_BAR_TYPE_PCIE2: + /* When using PCIe2, Bar 0 is based at 0 */ + msg.address_lo = (0 + CVMX_SLI_PCIE_MSI_RCV) & 0xffffffff; + msg.address_hi = (0 + CVMX_SLI_PCIE_MSI_RCV) >> 32; + break; default: panic("arch_setup_msi_irq: Invalid octeon_dma_bar_type"); } -- cgit v1.2.3 From d66f3f0e10b49df8d0cc0d8eb5bf2ef9863a33cf Mon Sep 17 00:00:00 2001 From: Ganesan Ramalingam Date: Fri, 9 May 2014 16:35:49 +0530 Subject: MIPS: Add MSI support for XLP9XX In XLP9XX, the interrupt routing table for MSI-X has been moved to the PCIe controller's config space from PIC. There are also 32 MSI-X interrupts available per link on XLP9XX. Update XLP MSI/MSI-X code to handle this. Signed-off-by: Ganesan Ramalingam Signed-off-by: Jayachandran C Cc: g@linux-mips.org Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6912/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/netlogic/xlp-hal/pcibus.h | 14 ++ arch/mips/include/asm/netlogic/xlp-hal/pic.h | 4 + arch/mips/include/asm/netlogic/xlp-hal/xlp.h | 5 +- arch/mips/pci/msi-xlp.c | 184 +++++++++++++++++------- 4 files changed, 156 insertions(+), 51 deletions(-) (limited to 'arch/mips/pci') diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h b/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h index d4deb87ad069..91540f41e1e4 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h @@ -69,6 +69,20 @@ #define PCIE_9XX_BYTE_SWAP_IO_BASE 0x25e #define PCIE_9XX_BYTE_SWAP_IO_LIM 0x25f +#define PCIE_9XX_BRIDGE_MSIX_ADDR_BASE 0x264 +#define PCIE_9XX_BRIDGE_MSIX_ADDR_LIMIT 0x265 +#define PCIE_9XX_MSI_STATUS 0x283 +#define PCIE_9XX_MSI_EN 0x284 +/* 128 MSIX vectors available in 9xx */ +#define PCIE_9XX_MSIX_STATUS0 0x286 +#define PCIE_9XX_MSIX_STATUSX(n) (n + 0x286) +#define PCIE_9XX_MSIX_VEC 0x296 +#define PCIE_9XX_MSIX_VECX(n) (n + 0x296) +#define PCIE_9XX_INT_STATUS0 0x397 +#define PCIE_9XX_INT_STATUS1 0x398 +#define PCIE_9XX_INT_EN0 0x399 +#define PCIE_9XX_INT_EN1 0x39a + /* other */ #define PCIE_NLINKS 4 diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pic.h b/arch/mips/include/asm/netlogic/xlp-hal/pic.h index f10bf3bba58f..41cefe94f0c9 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/pic.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/pic.h @@ -199,6 +199,10 @@ #define PIC_IRT_PCIE_LINK_3_INDEX 81 #define PIC_IRT_PCIE_LINK_INDEX(num) ((num) + PIC_IRT_PCIE_LINK_0_INDEX) +#define PIC_9XX_IRT_PCIE_LINK_0_INDEX 191 +#define PIC_9XX_IRT_PCIE_LINK_INDEX(num) \ + ((num) + PIC_9XX_IRT_PCIE_LINK_0_INDEX) + #define PIC_CLOCK_TIMER 7 #if !defined(LOCORE) && !defined(__ASSEMBLY__) diff --git a/arch/mips/include/asm/netlogic/xlp-hal/xlp.h b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h index 62d19871b983..a862b93223cc 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/xlp.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h @@ -70,8 +70,9 @@ #define PIC_PCIE_MSIX_IRQ_BASE 48 /* 48 - 51 MSI-X IRQ */ #define PIC_PCIE_MSIX_IRQ(i) (48 + (i)) -#define NLM_MSIX_VEC_BASE 96 /* 96 - 127 - MSIX mapped */ -#define NLM_MSI_VEC_BASE 128 /* 128 -255 - MSI mapped */ +/* XLP9xx and XLP8xx has 128 and 32 MSIX vectors respectively */ +#define NLM_MSIX_VEC_BASE 96 /* 96 - 223 - MSIX mapped */ +#define NLM_MSI_VEC_BASE 224 /* 224 -351 - MSI mapped */ #define NLM_PIC_INDIRECT_VEC_BASE 512 #define NLM_GPIO_VEC_BASE 768 diff --git a/arch/mips/pci/msi-xlp.c b/arch/mips/pci/msi-xlp.c index afd8405e0188..1ef3ed607f47 100644 --- a/arch/mips/pci/msi-xlp.c +++ b/arch/mips/pci/msi-xlp.c @@ -56,8 +56,8 @@ #include #define XLP_MSIVEC_PER_LINK 32 -#define XLP_MSIXVEC_TOTAL 32 -#define XLP_MSIXVEC_PER_LINK 8 +#define XLP_MSIXVEC_TOTAL (cpu_is_xlp9xx() ? 128 : 32) +#define XLP_MSIXVEC_PER_LINK (cpu_is_xlp9xx() ? 32 : 8) /* 128 MSI irqs per node, mapped starting at NLM_MSI_VEC_BASE */ static inline int nlm_link_msiirq(int link, int msivec) @@ -65,35 +65,44 @@ static inline int nlm_link_msiirq(int link, int msivec) return NLM_MSI_VEC_BASE + link * XLP_MSIVEC_PER_LINK + msivec; } +/* get the link MSI vector from irq number */ static inline int nlm_irq_msivec(int irq) { - return irq % XLP_MSIVEC_PER_LINK; + return (irq - NLM_MSI_VEC_BASE) % XLP_MSIVEC_PER_LINK; } +/* get the link from the irq number */ static inline int nlm_irq_msilink(int irq) { - return (irq % (XLP_MSIVEC_PER_LINK * PCIE_NLINKS)) / - XLP_MSIVEC_PER_LINK; + int total_msivec = XLP_MSIVEC_PER_LINK * PCIE_NLINKS; + + return ((irq - NLM_MSI_VEC_BASE) % total_msivec) / + XLP_MSIVEC_PER_LINK; } /* - * Only 32 MSI-X vectors are possible because there are only 32 PIC - * interrupts for MSI. We split them statically and use 8 MSI-X vectors - * per link - this keeps the allocation and lookup simple. + * For XLP 8xx/4xx/3xx/2xx, only 32 MSI-X vectors are possible because + * there are only 32 PIC interrupts for MSI. We split them statically + * and use 8 MSI-X vectors per link - this keeps the allocation and + * lookup simple. + * On XLP 9xx, there are 32 vectors per link, and the interrupts are + * not routed thru PIC, so we can use all 128 MSI-X vectors. */ static inline int nlm_link_msixirq(int link, int bit) { return NLM_MSIX_VEC_BASE + link * XLP_MSIXVEC_PER_LINK + bit; } +/* get the link MSI vector from irq number */ static inline int nlm_irq_msixvec(int irq) { - return irq % XLP_MSIXVEC_TOTAL; /* works when given xirq */ + return (irq - NLM_MSIX_VEC_BASE) % XLP_MSIXVEC_TOTAL; } -static inline int nlm_irq_msixlink(int irq) +/* get the link from MSIX vec */ +static inline int nlm_irq_msixlink(int msixvec) { - return nlm_irq_msixvec(irq) / XLP_MSIXVEC_PER_LINK; + return msixvec / XLP_MSIXVEC_PER_LINK; } /* @@ -129,7 +138,11 @@ static void xlp_msi_enable(struct irq_data *d) vec = nlm_irq_msivec(d->irq); spin_lock_irqsave(&md->msi_lock, flags); md->msi_enabled_mask |= 1u << vec; - nlm_write_reg(md->lnkbase, PCIE_MSI_EN, md->msi_enabled_mask); + if (cpu_is_xlp9xx()) + nlm_write_reg(md->lnkbase, PCIE_9XX_MSI_EN, + md->msi_enabled_mask); + else + nlm_write_reg(md->lnkbase, PCIE_MSI_EN, md->msi_enabled_mask); spin_unlock_irqrestore(&md->msi_lock, flags); } @@ -142,7 +155,11 @@ static void xlp_msi_disable(struct irq_data *d) vec = nlm_irq_msivec(d->irq); spin_lock_irqsave(&md->msi_lock, flags); md->msi_enabled_mask &= ~(1u << vec); - nlm_write_reg(md->lnkbase, PCIE_MSI_EN, md->msi_enabled_mask); + if (cpu_is_xlp9xx()) + nlm_write_reg(md->lnkbase, PCIE_9XX_MSI_EN, + md->msi_enabled_mask); + else + nlm_write_reg(md->lnkbase, PCIE_MSI_EN, md->msi_enabled_mask); spin_unlock_irqrestore(&md->msi_lock, flags); } @@ -156,11 +173,18 @@ static void xlp_msi_mask_ack(struct irq_data *d) xlp_msi_disable(d); /* Ack MSI on bridge */ - nlm_write_reg(md->lnkbase, PCIE_MSI_STATUS, 1u << vec); + if (cpu_is_xlp9xx()) + nlm_write_reg(md->lnkbase, PCIE_9XX_MSI_STATUS, 1u << vec); + else + nlm_write_reg(md->lnkbase, PCIE_MSI_STATUS, 1u << vec); /* Ack at eirr and PIC */ ack_c0_eirr(PIC_PCIE_LINK_MSI_IRQ(link)); - nlm_pic_ack(md->node->picbase, PIC_IRT_PCIE_LINK_INDEX(link)); + if (cpu_is_xlp9xx()) + nlm_pic_ack(md->node->picbase, + PIC_9XX_IRT_PCIE_LINK_INDEX(link)); + else + nlm_pic_ack(md->node->picbase, PIC_IRT_PCIE_LINK_INDEX(link)); } static struct irq_chip xlp_msi_chip = { @@ -172,30 +196,45 @@ static struct irq_chip xlp_msi_chip = { }; /* - * The MSI-X interrupt handling is different from MSI, there are 32 - * MSI-X interrupts generated by the PIC and each of these correspond - * to a MSI-X vector (0-31) that can be assigned. + * XLP8XX/4XX/3XX/2XX: + * The MSI-X interrupt handling is different from MSI, there are 32 MSI-X + * interrupts generated by the PIC and each of these correspond to a MSI-X + * vector (0-31) that can be assigned. * - * We divide the MSI-X vectors to 8 per link and do a per-link - * allocation + * We divide the MSI-X vectors to 8 per link and do a per-link allocation + * + * XLP9XX: + * 32 MSI-X vectors are available per link, and the interrupts are not routed + * thru the PIC. PIC ack not needed. * * Enable and disable done using standard MSI functions. */ static void xlp_msix_mask_ack(struct irq_data *d) { - struct xlp_msi_data *md = irq_data_get_irq_handler_data(d); + struct xlp_msi_data *md; int link, msixvec; + uint32_t status_reg, bit; msixvec = nlm_irq_msixvec(d->irq); - link = nlm_irq_msixlink(d->irq); + link = nlm_irq_msixlink(msixvec); mask_msi_irq(d); + md = irq_data_get_irq_handler_data(d); /* Ack MSI on bridge */ - nlm_write_reg(md->lnkbase, PCIE_MSIX_STATUS, 1u << msixvec); + if (cpu_is_xlp9xx()) { + status_reg = PCIE_9XX_MSIX_STATUSX(link); + bit = msixvec % XLP_MSIXVEC_PER_LINK; + } else { + status_reg = PCIE_MSIX_STATUS; + bit = msixvec; + } + nlm_write_reg(md->lnkbase, status_reg, 1u << bit); /* Ack at eirr and PIC */ ack_c0_eirr(PIC_PCIE_MSIX_IRQ(link)); - nlm_pic_ack(md->node->picbase, PIC_IRT_PCIE_MSIX_INDEX(msixvec)); + if (!cpu_is_xlp9xx()) + nlm_pic_ack(md->node->picbase, + PIC_IRT_PCIE_MSIX_INDEX(msixvec)); } static struct irq_chip xlp_msix_chip = { @@ -225,10 +264,18 @@ static void xlp_config_link_msi(uint64_t lnkbase, int lirq, uint64_t msiaddr) { u32 val; - val = nlm_read_reg(lnkbase, PCIE_INT_EN0); - if ((val & 0x200) == 0) { - val |= 0x200; /* MSI Interrupt enable */ - nlm_write_reg(lnkbase, PCIE_INT_EN0, val); + if (cpu_is_xlp9xx()) { + val = nlm_read_reg(lnkbase, PCIE_9XX_INT_EN0); + if ((val & 0x200) == 0) { + val |= 0x200; /* MSI Interrupt enable */ + nlm_write_reg(lnkbase, PCIE_9XX_INT_EN0, val); + } + } else { + val = nlm_read_reg(lnkbase, PCIE_INT_EN0); + if ((val & 0x200) == 0) { + val |= 0x200; + nlm_write_reg(lnkbase, PCIE_INT_EN0, val); + } } val = nlm_read_reg(lnkbase, 0x1); /* CMD */ @@ -275,9 +322,12 @@ static int xlp_setup_msi(uint64_t lnkbase, int node, int link, spin_lock_irqsave(&md->msi_lock, flags); if (md->msi_alloc_mask == 0) { - /* switch the link IRQ to MSI range */ xlp_config_link_msi(lnkbase, lirq, msiaddr); - irt = PIC_IRT_PCIE_LINK_INDEX(link); + /* switch the link IRQ to MSI range */ + if (cpu_is_xlp9xx()) + irt = PIC_9XX_IRT_PCIE_LINK_INDEX(link); + else + irt = PIC_IRT_PCIE_LINK_INDEX(link); nlm_setup_pic_irq(node, lirq, lirq, irt); nlm_pic_init_irt(nlm_get_node(node)->picbase, irt, lirq, node * nlm_threads_per_node(), 1 /*en */); @@ -319,10 +369,19 @@ static void xlp_config_link_msix(uint64_t lnkbase, int lirq, uint64_t msixaddr) val |= 0x80000000U; nlm_write_reg(lnkbase, 0x2C, val); } - val = nlm_read_reg(lnkbase, PCIE_INT_EN0); - if ((val & 0x200) == 0) { - val |= 0x200; /* MSI Interrupt enable */ - nlm_write_reg(lnkbase, PCIE_INT_EN0, val); + + if (cpu_is_xlp9xx()) { + val = nlm_read_reg(lnkbase, PCIE_9XX_INT_EN0); + if ((val & 0x200) == 0) { + val |= 0x200; /* MSI Interrupt enable */ + nlm_write_reg(lnkbase, PCIE_9XX_INT_EN0, val); + } + } else { + val = nlm_read_reg(lnkbase, PCIE_INT_EN0); + if ((val & 0x200) == 0) { + val |= 0x200; /* MSI Interrupt enable */ + nlm_write_reg(lnkbase, PCIE_INT_EN0, val); + } } val = nlm_read_reg(lnkbase, 0x1); /* CMD */ @@ -337,10 +396,19 @@ static void xlp_config_link_msix(uint64_t lnkbase, int lirq, uint64_t msixaddr) val |= (1 << 8) | lirq; nlm_write_pci_reg(lnkbase, 0xf, val); - /* MSI-X addresses */ - nlm_write_reg(lnkbase, PCIE_BRIDGE_MSIX_ADDR_BASE, msixaddr >> 8); - nlm_write_reg(lnkbase, PCIE_BRIDGE_MSIX_ADDR_LIMIT, - (msixaddr + MSI_ADDR_SZ) >> 8); + if (cpu_is_xlp9xx()) { + /* MSI-X addresses */ + nlm_write_reg(lnkbase, PCIE_9XX_BRIDGE_MSIX_ADDR_BASE, + msixaddr >> 8); + nlm_write_reg(lnkbase, PCIE_9XX_BRIDGE_MSIX_ADDR_LIMIT, + (msixaddr + MSI_ADDR_SZ) >> 8); + } else { + /* MSI-X addresses */ + nlm_write_reg(lnkbase, PCIE_BRIDGE_MSIX_ADDR_BASE, + msixaddr >> 8); + nlm_write_reg(lnkbase, PCIE_BRIDGE_MSIX_ADDR_LIMIT, + (msixaddr + MSI_ADDR_SZ) >> 8); + } } /* @@ -377,6 +445,7 @@ static int xlp_setup_msix(uint64_t lnkbase, int node, int link, xirq += t; msixvec = nlm_irq_msixvec(xirq); + msg.address_hi = msixaddr >> 32; msg.address_lo = msixaddr & 0xffffffff; msg.data = 0xc00 | msixvec; @@ -417,7 +486,7 @@ void __init xlp_init_node_msi_irqs(int node, int link) { struct nlm_soc_info *nodep; struct xlp_msi_data *md; - int irq, i, irt, msixvec; + int irq, i, irt, msixvec, val; pr_info("[%d %d] Init node PCI IRT\n", node, link); nodep = nlm_get_node(node); @@ -438,19 +507,28 @@ void __init xlp_init_node_msi_irqs(int node, int link) irq_set_handler_data(i, md); } - for (i = 0; i < XLP_MSIXVEC_PER_LINK; i++) { - /* Initialize MSI-X irts to generate one interrupt per link */ - msixvec = link * XLP_MSIXVEC_PER_LINK + i; - irt = PIC_IRT_PCIE_MSIX_INDEX(msixvec); - nlm_pic_init_irt(nodep->picbase, irt, PIC_PCIE_MSIX_IRQ(link), - node * nlm_threads_per_node(), 1 /* enable */); + for (i = 0; i < XLP_MSIXVEC_PER_LINK ; i++) { + if (cpu_is_xlp9xx()) { + val = ((node * nlm_threads_per_node()) << 7 | + PIC_PCIE_MSIX_IRQ(link) << 1 | 0 << 0); + nlm_write_pcie_reg(md->lnkbase, PCIE_9XX_MSIX_VECX(i + + (link * XLP_MSIXVEC_PER_LINK)), val); + } else { + /* Initialize MSI-X irts to generate one interrupt + * per link + */ + msixvec = link * XLP_MSIXVEC_PER_LINK + i; + irt = PIC_IRT_PCIE_MSIX_INDEX(msixvec); + nlm_pic_init_irt(nodep->picbase, irt, + PIC_PCIE_MSIX_IRQ(link), + node * nlm_threads_per_node(), 1); + } /* Initialize MSI-X extended irq space for the link */ irq = nlm_irq_to_xirq(node, nlm_link_msixirq(link, i)); irq_set_chip_and_handler(irq, &xlp_msix_chip, handle_level_irq); irq_set_handler_data(irq, md); } - } void nlm_dispatch_msi(int node, int lirq) @@ -462,7 +540,11 @@ void nlm_dispatch_msi(int node, int lirq) link = lirq - PIC_PCIE_LINK_MSI_IRQ_BASE; irqbase = nlm_irq_to_xirq(node, nlm_link_msiirq(link, 0)); md = irq_get_handler_data(irqbase); - status = nlm_read_reg(md->lnkbase, PCIE_MSI_STATUS) & + if (cpu_is_xlp9xx()) + status = nlm_read_reg(md->lnkbase, PCIE_9XX_MSI_STATUS) & + md->msi_enabled_mask; + else + status = nlm_read_reg(md->lnkbase, PCIE_MSI_STATUS) & md->msi_enabled_mask; while (status) { i = __ffs(status); @@ -480,10 +562,14 @@ void nlm_dispatch_msix(int node, int lirq) link = lirq - PIC_PCIE_MSIX_IRQ_BASE; irqbase = nlm_irq_to_xirq(node, nlm_link_msixirq(link, 0)); md = irq_get_handler_data(irqbase); - status = nlm_read_reg(md->lnkbase, PCIE_MSIX_STATUS); + if (cpu_is_xlp9xx()) + status = nlm_read_reg(md->lnkbase, PCIE_9XX_MSIX_STATUSX(link)); + else + status = nlm_read_reg(md->lnkbase, PCIE_MSIX_STATUS); /* narrow it down to the MSI-x vectors for our link */ - status = (status >> (link * XLP_MSIXVEC_PER_LINK)) & + if (!cpu_is_xlp9xx()) + status = (status >> (link * XLP_MSIXVEC_PER_LINK)) & ((1 << XLP_MSIXVEC_PER_LINK) - 1); while (status) { -- cgit v1.2.3 From 9e53481eea26891011ef7aa28e7990769fb6cf50 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 7 May 2014 12:20:58 +0100 Subject: MIPS: Malta: Let PIIX4 respond to PCI special cycles This patch enables the PIIX4 to respond to special cycles on the PCI bus. One such special cycle must be used in order to enter a suspend state, and if response to it is not enabled then the suspend state will never be entered. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6904/ Signed-off-by: Ralf Baechle --- arch/mips/pci/fixup-malta.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/mips/pci') diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c index 2f9e52a1a750..40e920c653cc 100644 --- a/arch/mips/pci/fixup-malta.c +++ b/arch/mips/pci/fixup-malta.c @@ -68,6 +68,7 @@ static void malta_piix_func0_fixup(struct pci_dev *pdev) { unsigned char reg_val; u32 reg_val32; + u16 reg_val16; /* PIIX PIRQC[A:D] irq mappings */ static int piixirqmap[PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_MAX] = { 0, 0, 0, 3, @@ -107,6 +108,11 @@ static void malta_piix_func0_fixup(struct pci_dev *pdev) pci_read_config_byte(pdev, PIIX4_FUNC0_SERIRQC, ®_val); reg_val |= PIIX4_FUNC0_SERIRQC_EN | PIIX4_FUNC0_SERIRQC_CONT; pci_write_config_byte(pdev, PIIX4_FUNC0_SERIRQC, reg_val); + + /* Enable response to special cycles */ + pci_read_config_word(pdev, PCI_COMMAND, ®_val16); + pci_write_config_word(pdev, PCI_COMMAND, + reg_val16 | PCI_COMMAND_SPECIAL); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, -- cgit v1.2.3 From ae6e7e635c2c9aa5aa5c03f5ac39e9d84fc0ee09 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 28 May 2014 23:52:14 +0200 Subject: MIPS: paravirt: Add pci controller for virtio Signed-off-by: David Daney Signed-off-by: Andreas Herrmann Cc: linux-mips@linux-mips.org Cc: James Hogan Cc: kvm@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7011/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + arch/mips/paravirt/Kconfig | 6 ++ arch/mips/pci/Makefile | 2 +- arch/mips/pci/pci-virtio-guest.c | 131 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 arch/mips/paravirt/Kconfig create mode 100644 arch/mips/pci/pci-virtio-guest.c (limited to 'arch/mips/pci') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 78b558f77f5c..e41f32b890fc 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -825,6 +825,7 @@ source "arch/mips/cavium-octeon/Kconfig" source "arch/mips/loongson/Kconfig" source "arch/mips/loongson1/Kconfig" source "arch/mips/netlogic/Kconfig" +source "arch/mips/paravirt/Kconfig" endmenu diff --git a/arch/mips/paravirt/Kconfig b/arch/mips/paravirt/Kconfig new file mode 100644 index 000000000000..ecae5861b601 --- /dev/null +++ b/arch/mips/paravirt/Kconfig @@ -0,0 +1,6 @@ +if MIPS_PARAVIRT + +config MIPS_PCI_VIRTIO + def_bool y + +endif # MIPS_PARAVIRT diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index d61138a177cc..ff8a5539b363 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -21,7 +21,7 @@ obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o - +obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o # # These are still pretty much in the old state, watch, go blind. # diff --git a/arch/mips/pci/pci-virtio-guest.c b/arch/mips/pci/pci-virtio-guest.c new file mode 100644 index 000000000000..40a078bc4617 --- /dev/null +++ b/arch/mips/pci/pci-virtio-guest.c @@ -0,0 +1,131 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2013 Cavium, Inc. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#define PCI_CONFIG_ADDRESS 0xcf8 +#define PCI_CONFIG_DATA 0xcfc + +union pci_config_address { + struct { + __BITFIELD_FIELD(unsigned enable_bit : 1, /* 31 */ + __BITFIELD_FIELD(unsigned reserved : 7, /* 30 .. 24 */ + __BITFIELD_FIELD(unsigned bus_number : 8, /* 23 .. 16 */ + __BITFIELD_FIELD(unsigned devfn_number : 8, /* 15 .. 8 */ + __BITFIELD_FIELD(unsigned register_number : 8, /* 7 .. 0 */ + ))))); + }; + u32 w; +}; + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + return ((pin + slot) % 4)+ MIPS_IRQ_PCIA; +} + +static void pci_virtio_guest_write_config_addr(struct pci_bus *bus, + unsigned int devfn, int reg) +{ + union pci_config_address pca = { .w = 0 }; + + pca.register_number = reg; + pca.devfn_number = devfn; + pca.bus_number = bus->number; + pca.enable_bit = 1; + + outl(pca.w, PCI_CONFIG_ADDRESS); +} + +static int pci_virtio_guest_write_config(struct pci_bus *bus, + unsigned int devfn, int reg, int size, u32 val) +{ + pci_virtio_guest_write_config_addr(bus, devfn, reg); + + switch (size) { + case 1: + outb(val, PCI_CONFIG_DATA + (reg & 3)); + break; + case 2: + outw(val, PCI_CONFIG_DATA + (reg & 2)); + break; + case 4: + outl(val, PCI_CONFIG_DATA); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int pci_virtio_guest_read_config(struct pci_bus *bus, unsigned int devfn, + int reg, int size, u32 *val) +{ + pci_virtio_guest_write_config_addr(bus, devfn, reg); + + switch (size) { + case 1: + *val = inb(PCI_CONFIG_DATA + (reg & 3)); + break; + case 2: + *val = inw(PCI_CONFIG_DATA + (reg & 2)); + break; + case 4: + *val = inl(PCI_CONFIG_DATA); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops pci_virtio_guest_ops = { + .read = pci_virtio_guest_read_config, + .write = pci_virtio_guest_write_config, +}; + +static struct resource pci_virtio_guest_mem_resource = { + .name = "Virtio MEM", + .flags = IORESOURCE_MEM, + .start = 0x10000000, + .end = 0x1dffffff +}; + +static struct resource pci_virtio_guest_io_resource = { + .name = "Virtio IO", + .flags = IORESOURCE_IO, + .start = 0, + .end = 0xffff +}; + +static struct pci_controller pci_virtio_guest_controller = { + .pci_ops = &pci_virtio_guest_ops, + .mem_resource = &pci_virtio_guest_mem_resource, + .io_resource = &pci_virtio_guest_io_resource, +}; + +static int __init pci_virtio_guest_setup(void) +{ + pr_err("pci_virtio_guest_setup\n"); + + /* Virtio comes pre-assigned */ + pci_set_flags(PCI_PROBE_ONLY); + + pci_virtio_guest_controller.io_map_base = mips_io_port_base; + register_pci_controller(&pci_virtio_guest_controller); + return 0; +} +arch_initcall(pci_virtio_guest_setup); -- cgit v1.2.3 From 5e888e8fb55cf3da870b85d04fef6bfe0d57c974 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 22 Apr 2014 12:51:13 +0200 Subject: mips: Update the email address of Geert Uytterhoeven All my Sony addresses are defunct. Signed-off-by: Geert Uytterhoeven Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6817/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/nile4.h | 2 +- arch/mips/paravirt/paravirt-smp.c | 5 ----- arch/mips/pci/ops-pmcmsp.c | 2 +- arch/mips/pci/ops-tx3927.c | 2 +- 4 files changed, 3 insertions(+), 8 deletions(-) (limited to 'arch/mips/pci') diff --git a/arch/mips/include/asm/nile4.h b/arch/mips/include/asm/nile4.h index 2e2436d0e94e..99e97f8bfbca 100644 --- a/arch/mips/include/asm/nile4.h +++ b/arch/mips/include/asm/nile4.h @@ -1,7 +1,7 @@ /* * asm-mips/nile4.h -- NEC Vrc-5074 Nile 4 definitions * - * Copyright (C) 2000 Geert Uytterhoeven + * Copyright (C) 2000 Geert Uytterhoeven * Sony Software Development Center Europe (SDCE), Brussels * * This file is based on the following documentation: diff --git a/arch/mips/paravirt/paravirt-smp.c b/arch/mips/paravirt/paravirt-smp.c index 73a123e08c28..0164b0c48352 100644 --- a/arch/mips/paravirt/paravirt-smp.c +++ b/arch/mips/paravirt/paravirt-smp.c @@ -99,10 +99,6 @@ static void paravirt_smp_finish(void) local_irq_enable(); } -static void paravirt_cpus_done(void) -{ -} - static void paravirt_boot_secondary(int cpu, struct task_struct *idle) { paravirt_smp_gp[cpu] = (unsigned long)task_thread_info(idle); @@ -141,7 +137,6 @@ struct plat_smp_ops paravirt_smp_ops = { .send_ipi_mask = paravirt_send_ipi_mask, .init_secondary = paravirt_init_secondary, .smp_finish = paravirt_smp_finish, - .cpus_done = paravirt_cpus_done, .boot_secondary = paravirt_boot_secondary, .smp_setup = paravirt_smp_setup, .prepare_cpus = paravirt_prepare_cpus, diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c index 3d27800edba2..50034f985be1 100644 --- a/arch/mips/pci/ops-pmcmsp.c +++ b/arch/mips/pci/ops-pmcmsp.c @@ -7,7 +7,7 @@ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net * * Much of the code is derived from the original DDB5074 port by - * Geert Uytterhoeven + * Geert Uytterhoeven * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c index 02d64f77e967..d35dc9c9ab9d 100644 --- a/arch/mips/pci/ops-tx3927.c +++ b/arch/mips/pci/ops-tx3927.c @@ -11,7 +11,7 @@ * Define the pci_ops for TX3927. * * Much of the code is derived from the original DDB5074 port by - * Geert Uytterhoeven + * Geert Uytterhoeven * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the -- cgit v1.2.3 From 8e9ecbc5e21bf82693e52ec75b1f45c1245a9bea Mon Sep 17 00:00:00 2001 From: Daniel Walter Date: Tue, 3 Jun 2014 16:22:08 +0100 Subject: MIPS: Replace calls to obsolete strict_strto call with kstrto* equivalents. Signed-off-by: Daniel Walter Cc: linux-kernel@vger.kernel.org Cc: richard@nod.at Cc: akpm@linux-foundation.org Signed-off-by: Ralf Baechle --- arch/mips/pci/ops-tx4927.c | 9 ++++++--- arch/mips/txx9/generic/setup.c | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'arch/mips/pci') diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c index 3d5df514d024..0e046d82e4e3 100644 --- a/arch/mips/pci/ops-tx4927.c +++ b/arch/mips/pci/ops-tx4927.c @@ -202,17 +202,20 @@ char *tx4927_pcibios_setup(char *str) unsigned long val; if (!strncmp(str, "trdyto=", 7)) { - if (strict_strtoul(str + 7, 0, &val) == 0) + u8 val = 0; + if (kstrtou8(str + 7, 0, &val) == 0) tx4927_pci_opts.trdyto = val; return NULL; } if (!strncmp(str, "retryto=", 8)) { - if (strict_strtoul(str + 8, 0, &val) == 0) + u8 val = 0; + if (kstrtou8(str + 8, 0, &val) == 0) tx4927_pci_opts.retryto = val; return NULL; } if (!strncmp(str, "gbwc=", 5)) { - if (strict_strtoul(str + 5, 0, &val) == 0) + u16 val; + if (kstrtou16(str + 5, 0, &val) == 0) tx4927_pci_opts.gbwc = val; return NULL; } diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 2b0b83c171e0..dd2cf25b5ae5 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -309,8 +309,8 @@ static void __init preprocess_cmdline(void) txx9_board_vec = find_board_byname(str + 6); continue; } else if (strncmp(str, "masterclk=", 10) == 0) { - unsigned long val; - if (strict_strtoul(str + 10, 10, &val) == 0) + unsigned int val; + if (kstrtouint(str + 10, 10, &val) == 0) txx9_master_clock = val; continue; } else if (strcmp(str, "icdisable") == 0) { -- cgit v1.2.3