^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) * Low-Level PCI Support for the SH7780
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2005 - 2010 Paul Mundt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "pci-sh4.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/mmu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/sizes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #if defined(CONFIG_CPU_BIG_ENDIAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) # define PCICR_ENDIANNESS SH4_PCICR_BSWP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) # define PCICR_ENDIANNESS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static struct resource sh7785_pci_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .name = "PCI IO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .start = 0x1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) .end = SZ_4M - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) .flags = IORESOURCE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .name = "PCI MEM 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) .start = 0xfd000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .end = 0xfd000000 + SZ_16M - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .flags = IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .name = "PCI MEM 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .start = 0x10000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .end = 0x10000000 + SZ_64M - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .flags = IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * 32-bit only resources must be last.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .name = "PCI MEM 2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .start = 0xc0000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .end = 0xc0000000 + SZ_512M - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static struct pci_channel sh7780_pci_controller = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .pci_ops = &sh4_pci_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .resources = sh7785_pci_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .nr_resources = ARRAY_SIZE(sh7785_pci_resources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .io_offset = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .mem_offset = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .io_map_base = 0xfe200000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .serr_irq = evt2irq(0xa00),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .err_irq = evt2irq(0xaa0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct pci_errors {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) const char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) } pci_arbiter_errors[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) { SH4_PCIAINT_MBKN, "master broken" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) { SH4_PCIAINT_TBTO, "target bus time out" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) { SH4_PCIAINT_MBTO, "master bus time out" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) { SH4_PCIAINT_TABT, "target abort" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) { SH4_PCIAINT_MABT, "master abort" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) { SH4_PCIAINT_RDPE, "read data parity error" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) { SH4_PCIAINT_WDPE, "write data parity error" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }, pci_interrupt_errors[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) { SH4_PCIINT_MLCK, "master lock error" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) { SH4_PCIINT_TABT, "target-target abort" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) { SH4_PCIINT_TRET, "target retry time out" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) { SH4_PCIINT_MFDE, "master function disable error" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) { SH4_PCIINT_PRTY, "address parity error" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) { SH4_PCIINT_SERR, "SERR" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) { SH4_PCIINT_TWDP, "data parity error for target write" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) { SH4_PCIINT_TRDP, "PERR detected for target read" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) { SH4_PCIINT_MTABT, "target abort for master" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) { SH4_PCIINT_MMABT, "master abort for master" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) { SH4_PCIINT_MWPD, "master write data parity error" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) { SH4_PCIINT_MRPD, "master read data parity error" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static irqreturn_t sh7780_pci_err_irq(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct pci_channel *hose = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) unsigned int cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) addr = __raw_readl(hose->reg_base + SH4_PCIALR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * Handle status errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) status = __raw_readw(hose->reg_base + PCI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (status & (PCI_STATUS_PARITY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) PCI_STATUS_DETECTED_PARITY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) PCI_STATUS_SIG_TARGET_ABORT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) PCI_STATUS_REC_TARGET_ABORT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) PCI_STATUS_REC_MASTER_ABORT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) cmd = pcibios_handle_status_errors(addr, status, hose);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (likely(cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) __raw_writew(cmd, hose->reg_base + PCI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * Handle arbiter errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) status = __raw_readl(hose->reg_base + SH4_PCIAINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) for (i = cmd = 0; i < ARRAY_SIZE(pci_arbiter_errors); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (status & pci_arbiter_errors[i].mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) printk(KERN_DEBUG "PCI: %s, addr=%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) pci_arbiter_errors[i].str, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) cmd |= pci_arbiter_errors[i].mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) __raw_writel(cmd, hose->reg_base + SH4_PCIAINT);
^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) * Handle the remaining PCI errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) status = __raw_readl(hose->reg_base + SH4_PCIINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) for (i = cmd = 0; i < ARRAY_SIZE(pci_interrupt_errors); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (status & pci_interrupt_errors[i].mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) printk(KERN_DEBUG "PCI: %s, addr=%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) pci_interrupt_errors[i].str, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) cmd |= pci_interrupt_errors[i].mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) __raw_writel(cmd, hose->reg_base + SH4_PCIINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static irqreturn_t sh7780_pci_serr_irq(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct pci_channel *hose = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) printk(KERN_DEBUG "PCI: system error received: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* Deassert SERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) __raw_writel(SH4_PCIINTM_SDIM, hose->reg_base + SH4_PCIINTM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* Back off the IRQ for awhile */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) disable_irq_nosync(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) hose->serr_timer.expires = jiffies + HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) add_timer(&hose->serr_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static int __init sh7780_pci_setup_irqs(struct pci_channel *hose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* Clear out PCI arbiter IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) __raw_writel(0, hose->reg_base + SH4_PCIAINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* Clear all error conditions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) __raw_writew(PCI_STATUS_DETECTED_PARITY | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) PCI_STATUS_SIG_SYSTEM_ERROR | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) PCI_STATUS_REC_MASTER_ABORT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) PCI_STATUS_REC_TARGET_ABORT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) PCI_STATUS_SIG_TARGET_ABORT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) PCI_STATUS_PARITY, hose->reg_base + PCI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ret = request_irq(hose->serr_irq, sh7780_pci_serr_irq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) "PCI SERR interrupt", hose);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (unlikely(ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) pr_err("PCI: Failed hooking SERR IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * The PCI ERR IRQ needs to be IRQF_SHARED since all of the power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * down IRQ vectors are routed through the ERR IRQ vector. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * only request_irq() once as there is only a single masking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * source for multiple events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ret = request_irq(hose->err_irq, sh7780_pci_err_irq, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) "PCI ERR interrupt", hose);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (unlikely(ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) free_irq(hose->serr_irq, hose);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* Unmask all of the arbiter IRQs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) __raw_writel(SH4_PCIAINT_MBKN | SH4_PCIAINT_TBTO | SH4_PCIAINT_MBTO | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) SH4_PCIAINT_TABT | SH4_PCIAINT_MABT | SH4_PCIAINT_RDPE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) SH4_PCIAINT_WDPE, hose->reg_base + SH4_PCIAINTM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* Unmask all of the PCI IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) __raw_writel(SH4_PCIINTM_TTADIM | SH4_PCIINTM_TMTOIM | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) SH4_PCIINTM_MDEIM | SH4_PCIINTM_APEDIM | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) SH4_PCIINTM_SDIM | SH4_PCIINTM_DPEITWM | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) SH4_PCIINTM_PEDITRM | SH4_PCIINTM_TADIMM | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) SH4_PCIINTM_MADIMM | SH4_PCIINTM_MWPDIM | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) SH4_PCIINTM_MRDPEIM, hose->reg_base + SH4_PCIINTM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static inline void __init sh7780_pci_teardown_irqs(struct pci_channel *hose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) free_irq(hose->err_irq, hose);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) free_irq(hose->serr_irq, hose);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static void __init sh7780_pci66_init(struct pci_channel *hose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (!pci_is_66mhz_capable(hose, 0, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /* Enable register access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) tmp = __raw_readl(hose->reg_base + SH4_PCICR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) tmp |= SH4_PCICR_PREFIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) __raw_writel(tmp, hose->reg_base + SH4_PCICR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Enable 66MHz operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) tmp = __raw_readw(hose->reg_base + PCI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) tmp |= PCI_STATUS_66MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) __raw_writew(tmp, hose->reg_base + PCI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* Done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) tmp = __raw_readl(hose->reg_base + SH4_PCICR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) tmp |= SH4_PCICR_PREFIX | SH4_PCICR_CFIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) __raw_writel(tmp, hose->reg_base + SH4_PCICR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static int __init sh7780_pci_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct pci_channel *chan = &sh7780_pci_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) phys_addr_t memphys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) size_t memsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) const char *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) pr_notice("PCI: Starting initialization.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) chan->reg_base = 0xfe040000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* Enable CPU access to the PCIC registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) __raw_writel(PCIECR_ENBL, PCIECR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_PRST | PCICR_ENDIANNESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) chan->reg_base + SH4_PCICR);
^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) * Wait for it to come back up. The spec says to allow for up to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * 1 second after toggling the reset pin, but in practice 100ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * is more than enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) mdelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) id = __raw_readw(chan->reg_base + PCI_VENDOR_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (id != PCI_VENDOR_ID_RENESAS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) pr_err("PCI: Unknown vendor ID 0x%04x.\n", id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) id = __raw_readw(chan->reg_base + PCI_DEVICE_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) type = (id == PCI_DEVICE_ID_RENESAS_SH7763) ? "SH7763" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) (id == PCI_DEVICE_ID_RENESAS_SH7780) ? "SH7780" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) (id == PCI_DEVICE_ID_RENESAS_SH7781) ? "SH7781" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) (id == PCI_DEVICE_ID_RENESAS_SH7785) ? "SH7785" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (unlikely(!type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) pr_err("PCI: Found an unsupported Renesas host controller, device id 0x%04x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) pr_notice("PCI: Found a Renesas %s host controller, revision %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) type, __raw_readb(chan->reg_base + PCI_REVISION_ID));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * Now throw it in to register initialization mode and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * start the real work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) __raw_writel(SH4_PCICR_PREFIX | PCICR_ENDIANNESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) chan->reg_base + SH4_PCICR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) memphys = __pa(memory_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) memsize = roundup_pow_of_two(memory_end - memory_start);
^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) * If there's more than 512MB of memory, we need to roll over to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * LAR1/LSR1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (memsize > SZ_512M) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) __raw_writel(memphys + SZ_512M, chan->reg_base + SH4_PCILAR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) __raw_writel((((memsize - SZ_512M) - SZ_1M) & 0x1ff00000) | 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) chan->reg_base + SH4_PCILSR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) memsize = SZ_512M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * Otherwise just zero it out and disable it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) __raw_writel(0, chan->reg_base + SH4_PCILAR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) __raw_writel(0, chan->reg_base + SH4_PCILSR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^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) * LAR0/LSR0 covers up to the first 512MB, which is enough to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * cover all of lowmem on most platforms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) __raw_writel(memphys, chan->reg_base + SH4_PCILAR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) __raw_writel(((memsize - SZ_1M) & 0x1ff00000) | 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) chan->reg_base + SH4_PCILSR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * Hook up the ERR and SERR IRQs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ret = sh7780_pci_setup_irqs(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (unlikely(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * Disable the cache snoop controller for non-coherent DMA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) __raw_writel(0, chan->reg_base + SH7780_PCICSCR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) __raw_writel(0, chan->reg_base + SH7780_PCICSAR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) __raw_writel(0, chan->reg_base + SH7780_PCICSCR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) __raw_writel(0, chan->reg_base + SH7780_PCICSAR1);
^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) * Setup the memory BARs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) for (i = 1; i < chan->nr_resources; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct resource *res = chan->resources + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) resource_size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (unlikely(res->flags & IORESOURCE_IO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * Make sure we're in the right physical addressing mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * for dealing with the resource.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) chan->nr_resources--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) size = resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * The MBMR mask is calculated in units of 256kB, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * keeps things pretty simple.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) chan->reg_base + SH7780_PCIMBMR(i - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) __raw_writel(res->start, chan->reg_base + SH7780_PCIMBR(i - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * And I/O.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) __raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) __raw_writel(0, chan->reg_base + SH7780_PCIIOBR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) __raw_writel(0, chan->reg_base + SH7780_PCIIOBMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) __raw_writew(PCI_COMMAND_SERR | PCI_COMMAND_WAIT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) PCI_COMMAND_MEMORY, chan->reg_base + PCI_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * Initialization mode complete, release the control register and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * enable round robin mode to stop device overruns/starvation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) PCICR_ENDIANNESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) chan->reg_base + SH4_PCICR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) ret = register_pci_controller(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (unlikely(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) sh7780_pci66_init(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) pr_notice("PCI: Running at %dMHz.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) (__raw_readw(chan->reg_base + PCI_STATUS) & PCI_STATUS_66MHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ? 66 : 33);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) sh7780_pci_teardown_irqs(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) arch_initcall(sh7780_pci_init);