^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Support for Faraday Technology FTPC100 PCI Controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on the out-of-tree OpenWRT patch for Cortina Gemini:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2009 Janos Laube <janos.dev@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Based on SL2312 PCI controller code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Storlink (C) 2003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of_pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/irqchip/chained_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "../pci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Special configuration registers directly in the first few words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * in I/O space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define FTPCI_IOSIZE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define FTPCI_PROT 0x04 /* AHB protection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define FTPCI_CTRL 0x08 /* PCI control signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define FTPCI_SOFTRST 0x10 /* Soft reset counter and response error enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define FTPCI_CONFIG 0x28 /* PCI configuration command register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define FTPCI_DATA 0x2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define FARADAY_PCI_STATUS_CMD 0x04 /* Status and command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define FARADAY_PCI_PMC 0x40 /* Power management control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define FARADAY_PCI_PMCSR 0x44 /* Power management status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define FARADAY_PCI_CTRL1 0x48 /* Control register 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define FARADAY_PCI_CTRL2 0x4C /* Control register 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define FARADAY_PCI_MEM1_BASE_SIZE 0x50 /* Memory base and size #1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define FARADAY_PCI_MEM2_BASE_SIZE 0x54 /* Memory base and size #2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define FARADAY_PCI_MEM3_BASE_SIZE 0x58 /* Memory base and size #3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define PCI_STATUS_66MHZ_CAPABLE BIT(21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* Bits 31..28 gives INTD..INTA status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define PCI_CTRL2_INTSTS_SHIFT 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define PCI_CTRL2_INTMASK_CMDERR BIT(27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define PCI_CTRL2_INTMASK_PARERR BIT(26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* Bits 25..22 masks INTD..INTA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define PCI_CTRL2_INTMASK_SHIFT 22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define PCI_CTRL2_INTMASK_MABRT_RX BIT(21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define PCI_CTRL2_INTMASK_TABRT_RX BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define PCI_CTRL2_INTMASK_TABRT_TX BIT(19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define PCI_CTRL2_INTMASK_RETRY4 BIT(18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define PCI_CTRL2_INTMASK_SERR_RX BIT(17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define PCI_CTRL2_INTMASK_PERR_RX BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* Bit 15 reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define PCI_CTRL2_MSTPRI_REQ6 BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define PCI_CTRL2_MSTPRI_REQ5 BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define PCI_CTRL2_MSTPRI_REQ4 BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define PCI_CTRL2_MSTPRI_REQ3 BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define PCI_CTRL2_MSTPRI_REQ2 BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define PCI_CTRL2_MSTPRI_REQ1 BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define PCI_CTRL2_MSTPRI_REQ0 BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* Bits 7..4 reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* Bits 3..0 TRDYW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * Memory configs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * Bit 31..20 defines the PCI side memory base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Bit 19..16 (4 bits) defines the size per below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define FARADAY_PCI_MEMBASE_MASK 0xfff00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define FARADAY_PCI_MEMSIZE_1MB 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define FARADAY_PCI_MEMSIZE_2MB 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define FARADAY_PCI_MEMSIZE_4MB 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define FARADAY_PCI_MEMSIZE_8MB 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define FARADAY_PCI_MEMSIZE_16MB 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define FARADAY_PCI_MEMSIZE_32MB 0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define FARADAY_PCI_MEMSIZE_64MB 0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define FARADAY_PCI_MEMSIZE_128MB 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define FARADAY_PCI_MEMSIZE_256MB 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define FARADAY_PCI_MEMSIZE_512MB 0x9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define FARADAY_PCI_MEMSIZE_1GB 0xa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define FARADAY_PCI_MEMSIZE_2GB 0xb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define FARADAY_PCI_MEMSIZE_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * The DMA base is set to 0x0 for all memory segments, it reflects the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * fact that the memory of the host system starts at 0x0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define FARADAY_PCI_DMA_MEM1_BASE 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define FARADAY_PCI_DMA_MEM2_BASE 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define FARADAY_PCI_DMA_MEM3_BASE 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Defines for PCI configuration command register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define PCI_CONF_ENABLE BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define PCI_CONF_WHERE(r) ((r) & 0xFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define PCI_CONF_BUS(b) (((b) & 0xFF) << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define PCI_CONF_DEVICE(d) (((d) & 0x1F) << 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define PCI_CONF_FUNCTION(f) (((f) & 0x07) << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * struct faraday_pci_variant - encodes IP block differences
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * @cascaded_irq: this host has cascaded IRQs from an interrupt controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * embedded in the host bridge.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct faraday_pci_variant {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) bool cascaded_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct faraday_pci {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct irq_domain *irqdomain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct pci_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct clk *bus_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static int faraday_res_to_memcfg(resource_size_t mem_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) resource_size_t mem_size, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u32 outval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) switch (mem_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) case SZ_1M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) outval = FARADAY_PCI_MEMSIZE_1MB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) case SZ_2M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) outval = FARADAY_PCI_MEMSIZE_2MB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) case SZ_4M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) outval = FARADAY_PCI_MEMSIZE_4MB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) case SZ_8M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) outval = FARADAY_PCI_MEMSIZE_8MB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) case SZ_16M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) outval = FARADAY_PCI_MEMSIZE_16MB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) case SZ_32M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) outval = FARADAY_PCI_MEMSIZE_32MB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) case SZ_64M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) outval = FARADAY_PCI_MEMSIZE_64MB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) case SZ_128M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) outval = FARADAY_PCI_MEMSIZE_128MB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) case SZ_256M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) outval = FARADAY_PCI_MEMSIZE_256MB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) case SZ_512M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) outval = FARADAY_PCI_MEMSIZE_512MB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case SZ_1G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) outval = FARADAY_PCI_MEMSIZE_1GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case SZ_2G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) outval = FARADAY_PCI_MEMSIZE_2GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) outval <<= FARADAY_PCI_MEMSIZE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* This is probably not good */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (mem_base & ~(FARADAY_PCI_MEMBASE_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) pr_warn("truncated PCI memory base\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* Translate to bridge side address space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) outval |= (mem_base & FARADAY_PCI_MEMBASE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) pr_debug("Translated pci base @%pap, size %pap to config %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) &mem_base, &mem_size, outval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) *val = outval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static int faraday_raw_pci_read_config(struct faraday_pci *p, int bus_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) unsigned int fn, int config, int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) writel(PCI_CONF_BUS(bus_number) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) PCI_CONF_DEVICE(PCI_SLOT(fn)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) PCI_CONF_WHERE(config) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) PCI_CONF_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) p->base + FTPCI_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) *value = readl(p->base + FTPCI_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (size == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *value = (*value >> (8 * (config & 3))) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) else if (size == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *value = (*value >> (8 * (config & 3))) & 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int faraday_pci_read_config(struct pci_bus *bus, unsigned int fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) int config, int size, u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct faraday_pci *p = bus->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) dev_dbg(&bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) "[read] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) PCI_SLOT(fn), PCI_FUNC(fn), config, size, *value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return faraday_raw_pci_read_config(p, bus->number, fn, config, size, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static int faraday_raw_pci_write_config(struct faraday_pci *p, int bus_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) unsigned int fn, int config, int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int ret = PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) writel(PCI_CONF_BUS(bus_number) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) PCI_CONF_DEVICE(PCI_SLOT(fn)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) PCI_CONF_FUNCTION(PCI_FUNC(fn)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) PCI_CONF_WHERE(config) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) PCI_CONF_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) p->base + FTPCI_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) writel(value, p->base + FTPCI_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) writew(value, p->base + FTPCI_DATA + (config & 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) writeb(value, p->base + FTPCI_DATA + (config & 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ret = PCIBIOS_BAD_REGISTER_NUMBER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int faraday_pci_write_config(struct pci_bus *bus, unsigned int fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) int config, int size, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct faraday_pci *p = bus->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) dev_dbg(&bus->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) "[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) PCI_SLOT(fn), PCI_FUNC(fn), config, size, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return faraday_raw_pci_write_config(p, bus->number, fn, config, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static struct pci_ops faraday_pci_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .read = faraday_pci_read_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .write = faraday_pci_write_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static void faraday_pci_ack_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct faraday_pci *p = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) faraday_raw_pci_read_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTSTS_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) faraday_raw_pci_write_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static void faraday_pci_mask_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct faraday_pci *p = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) faraday_raw_pci_read_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) reg &= ~((0xF << PCI_CTRL2_INTSTS_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) | BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) faraday_raw_pci_write_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static void faraday_pci_unmask_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct faraday_pci *p = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) faraday_raw_pci_read_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) reg &= ~(0xF << PCI_CTRL2_INTSTS_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) reg |= BIT(irqd_to_hwirq(d) + PCI_CTRL2_INTMASK_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) faraday_raw_pci_write_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static void faraday_pci_irq_handler(struct irq_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct faraday_pci *p = irq_desc_get_handler_data(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct irq_chip *irqchip = irq_desc_get_chip(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned int irq_stat, reg, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) faraday_raw_pci_read_config(p, 0, 0, FARADAY_PCI_CTRL2, 4, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) irq_stat = reg >> PCI_CTRL2_INTSTS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) chained_irq_enter(irqchip, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if ((irq_stat & BIT(i)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) generic_handle_irq(irq_find_mapping(p->irqdomain, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) chained_irq_exit(irqchip, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static struct irq_chip faraday_pci_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) .name = "PCI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .irq_ack = faraday_pci_ack_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .irq_mask = faraday_pci_mask_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .irq_unmask = faraday_pci_unmask_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static int faraday_pci_irq_map(struct irq_domain *domain, unsigned int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) irq_hw_number_t hwirq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) irq_set_chip_and_handler(irq, &faraday_pci_irq_chip, handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) irq_set_chip_data(irq, domain->host_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static const struct irq_domain_ops faraday_pci_irqdomain_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) .map = faraday_pci_irq_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static int faraday_pci_setup_cascaded_irq(struct faraday_pci *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct device_node *intc = of_get_next_child(p->dev->of_node, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (!intc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) dev_err(p->dev, "missing child interrupt-controller node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* All PCI IRQs cascade off this one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) irq = of_irq_get(intc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) dev_err(p->dev, "failed to get parent IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) of_node_put(intc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return irq ?: -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) p->irqdomain = irq_domain_add_linear(intc, PCI_NUM_INTX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) &faraday_pci_irqdomain_ops, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) of_node_put(intc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (!p->irqdomain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) dev_err(p->dev, "failed to create Gemini PCI IRQ domain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) irq_set_chained_handler_and_data(irq, faraday_pci_irq_handler, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) irq_create_mapping(p->irqdomain, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int faraday_pci_parse_map_dma_ranges(struct faraday_pci *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct device *dev = p->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct pci_host_bridge *bridge = pci_host_bridge_from_priv(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct resource_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) u32 confreg[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) FARADAY_PCI_MEM1_BASE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) FARADAY_PCI_MEM2_BASE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) FARADAY_PCI_MEM3_BASE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) resource_list_for_each_entry(entry, &bridge->dma_ranges) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) u64 pci_addr = entry->res->start - entry->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) u64 end = entry->res->end - entry->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ret = faraday_res_to_memcfg(pci_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) resource_size(entry->res), &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) "DMA range %d: illegal MEM resource size\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) dev_info(dev, "DMA MEM%d BASE: 0x%016llx -> 0x%016llx config %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) i + 1, pci_addr, end, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (i <= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) faraday_raw_pci_write_config(p, 0, 0, confreg[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 4, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) dev_err(dev, "ignore extraneous dma-range %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static int faraday_pci_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) const struct faraday_pci_variant *variant =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct resource_entry *win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct faraday_pci *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct resource *io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct pci_host_bridge *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) unsigned char max_bus_speed = PCI_SPEED_33MHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) unsigned char cur_bus_speed = PCI_SPEED_33MHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) host = devm_pci_alloc_host_bridge(dev, sizeof(*p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (!host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) host->ops = &faraday_pci_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) p = pci_host_bridge_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) host->sysdata = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) p->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /* Retrieve and enable optional clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) clk = devm_clk_get(dev, "PCLK");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ret = clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) dev_err(dev, "could not prepare PCLK\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) p->bus_clk = devm_clk_get(dev, "PCICLK");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (IS_ERR(p->bus_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return PTR_ERR(p->bus_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ret = clk_prepare_enable(p->bus_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) dev_err(dev, "could not prepare PCICLK\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) p->base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (IS_ERR(p->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return PTR_ERR(p->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) win = resource_list_first_type(&host->windows, IORESOURCE_IO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (win) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) io = win->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (!faraday_res_to_memcfg(io->start - win->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) resource_size(io), &val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /* setup I/O space size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) writel(val, p->base + FTPCI_IOSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) dev_err(dev, "illegal IO mem size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* Setup hostbridge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) val = readl(p->base + FTPCI_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) val |= PCI_COMMAND_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) val |= PCI_COMMAND_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) val |= PCI_COMMAND_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) writel(val, p->base + FTPCI_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* Mask and clear all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) faraday_raw_pci_write_config(p, 0, 0, FARADAY_PCI_CTRL2 + 2, 2, 0xF000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (variant->cascaded_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ret = faraday_pci_setup_cascaded_irq(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) dev_err(dev, "failed to setup cascaded IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* Check bus clock if we can gear up to 66 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (!IS_ERR(p->bus_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) faraday_raw_pci_read_config(p, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) FARADAY_PCI_STATUS_CMD, 4, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) rate = clk_get_rate(p->bus_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if ((rate == 33000000) && (val & PCI_STATUS_66MHZ_CAPABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) dev_info(dev, "33MHz bus is 66MHz capable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) max_bus_speed = PCI_SPEED_66MHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ret = clk_set_rate(p->bus_clk, 66000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) dev_err(dev, "failed to set bus clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) dev_info(dev, "33MHz only bus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) max_bus_speed = PCI_SPEED_33MHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /* Bumping the clock may fail so read back the rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) rate = clk_get_rate(p->bus_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (rate == 33000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) cur_bus_speed = PCI_SPEED_33MHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (rate == 66000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) cur_bus_speed = PCI_SPEED_66MHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) ret = faraday_pci_parse_map_dma_ranges(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ret = pci_scan_root_bus_bridge(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) dev_err(dev, "failed to scan host: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) p->bus = host->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) p->bus->max_bus_speed = max_bus_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) p->bus->cur_bus_speed = cur_bus_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) pci_bus_assign_resources(p->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) pci_bus_add_devices(p->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * We encode bridge variants here, we have at least two so it doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * hurt to have infrastructure to encompass future variants as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static const struct faraday_pci_variant faraday_regular = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .cascaded_irq = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) static const struct faraday_pci_variant faraday_dual = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .cascaded_irq = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static const struct of_device_id faraday_pci_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .compatible = "faraday,ftpci100",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .data = &faraday_regular,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) .compatible = "faraday,ftpci100-dual",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .data = &faraday_dual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static struct platform_driver faraday_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .name = "ftpci100",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) .of_match_table = of_match_ptr(faraday_pci_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .suppress_bind_attrs = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .probe = faraday_pci_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) builtin_platform_driver(faraday_pci_driver);