linux/arch/arm/mach-pxa/cm-x2xx-pci.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * linux/arch/arm/mach-pxa/cm-x2xx-pci.c
   4 *
   5 * PCI bios-type initialisation for PCI machines
   6 *
   7 * Bits taken from various places.
   8 *
   9 * Copyright (C) 2007, 2008 Compulab, Ltd.
  10 * Mike Rapoport <mike@compulab.co.il>
  11 */
  12
  13#include <linux/kernel.h>
  14#include <linux/pci.h>
  15#include <linux/init.h>
  16#include <linux/device.h>
  17#include <linux/platform_device.h>
  18#include <linux/irq.h>
  19#include <linux/gpio.h>
  20
  21#include <asm/mach/pci.h>
  22#include <asm/mach-types.h>
  23
  24#include <asm/hardware/it8152.h>
  25
  26void __iomem *it8152_base_address;
  27static int cmx2xx_it8152_irq_gpio;
  28
  29static void cmx2xx_it8152_irq_demux(struct irq_desc *desc)
  30{
  31        /* clear our parent irq */
  32        desc->irq_data.chip->irq_ack(&desc->irq_data);
  33
  34        it8152_irq_demux(desc);
  35}
  36
  37void __cmx2xx_pci_init_irq(int irq_gpio)
  38{
  39        it8152_init_irq();
  40
  41        cmx2xx_it8152_irq_gpio = irq_gpio;
  42
  43        irq_set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING);
  44
  45        irq_set_chained_handler(gpio_to_irq(irq_gpio),
  46                                cmx2xx_it8152_irq_demux);
  47}
  48
  49#ifdef CONFIG_PM
  50static unsigned long sleep_save_ite[10];
  51
  52void __cmx2xx_pci_suspend(void)
  53{
  54        /* save ITE state */
  55        sleep_save_ite[0] = __raw_readl(IT8152_INTC_PDCNIMR);
  56        sleep_save_ite[1] = __raw_readl(IT8152_INTC_LPCNIMR);
  57        sleep_save_ite[2] = __raw_readl(IT8152_INTC_LPNIAR);
  58
  59        /* Clear ITE IRQ's */
  60        __raw_writel((0), IT8152_INTC_PDCNIRR);
  61        __raw_writel((0), IT8152_INTC_LPCNIRR);
  62}
  63
  64void __cmx2xx_pci_resume(void)
  65{
  66        /* restore IT8152 state */
  67        __raw_writel((sleep_save_ite[0]), IT8152_INTC_PDCNIMR);
  68        __raw_writel((sleep_save_ite[1]), IT8152_INTC_LPCNIMR);
  69        __raw_writel((sleep_save_ite[2]), IT8152_INTC_LPNIAR);
  70}
  71#else
  72void cmx2xx_pci_suspend(void) {}
  73void cmx2xx_pci_resume(void) {}
  74#endif
  75
  76/* PCI IRQ mapping*/
  77static int __init cmx2xx_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
  78{
  79        int irq;
  80
  81        dev_dbg(&dev->dev, "%s: slot=%x, pin=%x\n", __func__, slot, pin);
  82
  83        irq = it8152_pci_map_irq(dev, slot, pin);
  84        if (irq)
  85                return irq;
  86
  87        /*
  88          Here comes the ugly part. The routing is baseboard specific,
  89          but defining a platform for each possible base of CM-X2XX is
  90          unrealistic. Here we keep mapping for ATXBase and SB-X2XX.
  91        */
  92        /* ATXBASE PCI slot */
  93        if (slot == 7)
  94                return IT8152_PCI_INTA;
  95
  96        /* ATXBase/SB-X2XX CardBus */
  97        if (slot == 8 || slot == 0)
  98                return IT8152_PCI_INTB;
  99
 100        /* ATXBase Ethernet */
 101        if (slot == 9)
 102                return IT8152_PCI_INTA;
 103
 104        /* CM-x255 Onboard Ethernet */
 105        if (slot == 15)
 106                return IT8152_PCI_INTC;
 107
 108        /* SB-x2xx Ethernet */
 109        if (slot == 16)
 110                return IT8152_PCI_INTA;
 111
 112        /* PC104+ interrupt routing */
 113        if ((slot == 17) || (slot == 19))
 114                return IT8152_PCI_INTA;
 115        if ((slot == 18) || (slot == 20))
 116                return IT8152_PCI_INTB;
 117
 118        return(0);
 119}
 120
 121static void cmx2xx_pci_preinit(void)
 122{
 123        pr_info("Initializing CM-X2XX PCI subsystem\n");
 124
 125        pcibios_min_io = 0;
 126        pcibios_min_mem = 0;
 127
 128        __raw_writel(0x800, IT8152_PCI_CFG_ADDR);
 129        if (__raw_readl(IT8152_PCI_CFG_DATA) == 0x81521283) {
 130                pr_info("PCI Bridge found.\n");
 131
 132                /* set PCI I/O base at 0 */
 133                writel(0x848, IT8152_PCI_CFG_ADDR);
 134                writel(0, IT8152_PCI_CFG_DATA);
 135
 136                /* set PCI memory base at 0 */
 137                writel(0x840, IT8152_PCI_CFG_ADDR);
 138                writel(0, IT8152_PCI_CFG_DATA);
 139
 140                writel(0x20, IT8152_GPIO_GPDR);
 141
 142                /* CardBus Controller on ATXbase baseboard */
 143                writel(0x4000, IT8152_PCI_CFG_ADDR);
 144                if (readl(IT8152_PCI_CFG_DATA) == 0xAC51104C) {
 145                        pr_info("CardBus Bridge found.\n");
 146
 147                        /* Configure socket 0 */
 148                        writel(0x408C, IT8152_PCI_CFG_ADDR);
 149                        writel(0x1022, IT8152_PCI_CFG_DATA);
 150
 151                        writel(0x4080, IT8152_PCI_CFG_ADDR);
 152                        writel(0x3844d060, IT8152_PCI_CFG_DATA);
 153
 154                        writel(0x4090, IT8152_PCI_CFG_ADDR);
 155                        writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) |
 156                                0x60440000),
 157                               IT8152_PCI_CFG_DATA);
 158
 159                        writel(0x4018, IT8152_PCI_CFG_ADDR);
 160                        writel(0xb0000000, IT8152_PCI_CFG_DATA);
 161
 162                        /* Configure socket 1 */
 163                        writel(0x418C, IT8152_PCI_CFG_ADDR);
 164                        writel(0x1022, IT8152_PCI_CFG_DATA);
 165
 166                        writel(0x4180, IT8152_PCI_CFG_ADDR);
 167                        writel(0x3844d060, IT8152_PCI_CFG_DATA);
 168
 169                        writel(0x4190, IT8152_PCI_CFG_ADDR);
 170                        writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) |
 171                                0x60440000),
 172                               IT8152_PCI_CFG_DATA);
 173
 174                        writel(0x4118, IT8152_PCI_CFG_ADDR);
 175                        writel(0xb0000000, IT8152_PCI_CFG_DATA);
 176                }
 177        }
 178}
 179
 180static struct hw_pci cmx2xx_pci __initdata = {
 181        .map_irq        = cmx2xx_pci_map_irq,
 182        .nr_controllers = 1,
 183        .ops            = &it8152_ops,
 184        .setup          = it8152_pci_setup,
 185        .preinit        = cmx2xx_pci_preinit,
 186};
 187
 188static int __init cmx2xx_init_pci(void)
 189{
 190        if (machine_is_armcore())
 191                pci_common_init(&cmx2xx_pci);
 192
 193        return 0;
 194}
 195
 196subsys_initcall(cmx2xx_init_pci);
 197