linux/arch/mips/pci/fixup-lemote2f.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2008 Lemote Technology
   3 * Copyright (C) 2004 ICT CAS
   4 * Author: Li xiaoyu, lixy@ict.ac.cn
   5 *
   6 * Copyright (C) 2007 Lemote, Inc.
   7 * Author: Fuxin Zhang, zhangfx@lemote.com
   8 *
   9 *  This program is free software; you can redistribute  it and/or modify it
  10 *  under  the terms of  the GNU General  Public License as published by the
  11 *  Free Software Foundation;  either version 2 of the  License, or (at your
  12 *  option) any later version.
  13 */
  14#include <linux/init.h>
  15#include <linux/pci.h>
  16
  17#include <loongson.h>
  18#include <cs5536/cs5536.h>
  19#include <cs5536/cs5536_pci.h>
  20
  21/* PCI interrupt pins
  22 *
  23 * These should not be changed, or you should consider loongson2f interrupt
  24 * register and your pci card dispatch
  25 */
  26
  27#define PCIA            4
  28#define PCIB            5
  29#define PCIC            6
  30#define PCID            7
  31
  32/* all the pci device has the PCIA pin, check the datasheet. */
  33static char irq_tab[][5] __initdata = {
  34        /*      INTA    INTB    INTC    INTD */
  35        {0, 0, 0, 0, 0},        /*  11: Unused */
  36        {0, 0, 0, 0, 0},        /*  12: Unused */
  37        {0, 0, 0, 0, 0},        /*  13: Unused */
  38        {0, 0, 0, 0, 0},        /*  14: Unused */
  39        {0, 0, 0, 0, 0},        /*  15: Unused */
  40        {0, 0, 0, 0, 0},        /*  16: Unused */
  41        {0, PCIA, 0, 0, 0},     /*  17: RTL8110-0 */
  42        {0, PCIB, 0, 0, 0},     /*  18: RTL8110-1 */
  43        {0, PCIC, 0, 0, 0},     /*  19: SiI3114 */
  44        {0, PCID, 0, 0, 0},     /*  20: 3-ports nec usb */
  45        {0, PCIA, PCIB, PCIC, PCID},    /*  21: PCI-SLOT */
  46        {0, 0, 0, 0, 0},        /*  22: Unused */
  47        {0, 0, 0, 0, 0},        /*  23: Unused */
  48        {0, 0, 0, 0, 0},        /*  24: Unused */
  49        {0, 0, 0, 0, 0},        /*  25: Unused */
  50        {0, 0, 0, 0, 0},        /*  26: Unused */
  51        {0, 0, 0, 0, 0},        /*  27: Unused */
  52};
  53
  54int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
  55{
  56        int virq;
  57
  58        if ((PCI_SLOT(dev->devfn) != PCI_IDSEL_CS5536)
  59            && (PCI_SLOT(dev->devfn) < 32)) {
  60                virq = irq_tab[slot][pin];
  61                printk(KERN_INFO "slot: %d, pin: %d, irq: %d\n", slot, pin,
  62                       virq + LOONGSON_IRQ_BASE);
  63                if (virq != 0)
  64                        return LOONGSON_IRQ_BASE + virq;
  65                else
  66                        return 0;
  67        } else if (PCI_SLOT(dev->devfn) == PCI_IDSEL_CS5536) {  /*  cs5536 */
  68                switch (PCI_FUNC(dev->devfn)) {
  69                case 2:
  70                        pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
  71                                              CS5536_IDE_INTR);
  72                        return CS5536_IDE_INTR; /*  for IDE */
  73                case 3:
  74                        pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
  75                                              CS5536_ACC_INTR);
  76                        return CS5536_ACC_INTR; /*  for AUDIO */
  77                case 4: /*  for OHCI */
  78                case 5: /*  for EHCI */
  79                case 6: /*  for UDC */
  80                case 7: /*  for OTG */
  81                        pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
  82                                              CS5536_USB_INTR);
  83                        return CS5536_USB_INTR;
  84                }
  85                return dev->irq;
  86        } else {
  87                printk(KERN_INFO " strange pci slot number.\n");
  88                return 0;
  89        }
  90}
  91
  92/* Do platform specific device initialization at pci_enable_device() time */
  93int pcibios_plat_dev_init(struct pci_dev *dev)
  94{
  95        return 0;
  96}
  97
  98/* CS5536 SPEC. fixup */
  99static void loongson_cs5536_isa_fixup(struct pci_dev *pdev)
 100{
 101        /* the uart1 and uart2 interrupt in PIC is enabled as default */
 102        pci_write_config_dword(pdev, PCI_UART1_INT_REG, 1);
 103        pci_write_config_dword(pdev, PCI_UART2_INT_REG, 1);
 104}
 105
 106static void loongson_cs5536_ide_fixup(struct pci_dev *pdev)
 107{
 108        /* setting the mutex pin as IDE function */
 109        pci_write_config_dword(pdev, PCI_IDE_CFG_REG,
 110                               CS5536_IDE_FLASH_SIGNATURE);
 111}
 112
 113static void loongson_cs5536_acc_fixup(struct pci_dev *pdev)
 114{
 115        /* enable the AUDIO interrupt in PIC  */
 116        pci_write_config_dword(pdev, PCI_ACC_INT_REG, 1);
 117
 118        pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0);
 119}
 120
 121static void loongson_cs5536_ohci_fixup(struct pci_dev *pdev)
 122{
 123        /* enable the OHCI interrupt in PIC */
 124        /* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */
 125        pci_write_config_dword(pdev, PCI_OHCI_INT_REG, 1);
 126}
 127
 128static void loongson_cs5536_ehci_fixup(struct pci_dev *pdev)
 129{
 130        u32 hi, lo;
 131
 132        /* Serial short detect enable */
 133        _rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo);
 134        _wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 3), lo);
 135
 136        /* setting the USB2.0 micro frame length */
 137        pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000);
 138}
 139
 140static void loongson_nec_fixup(struct pci_dev *pdev)
 141{
 142        unsigned int val;
 143
 144        pci_read_config_dword(pdev, 0xe0, &val);
 145        /* Only 2 port be used */
 146        pci_write_config_dword(pdev, 0xe0, (val & ~3) | 0x2);
 147}
 148
 149DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
 150                         loongson_cs5536_isa_fixup);
 151DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_OHC,
 152                         loongson_cs5536_ohci_fixup);
 153DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_EHC,
 154                         loongson_cs5536_ehci_fixup);
 155DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO,
 156                         loongson_cs5536_acc_fixup);
 157DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE,
 158                         loongson_cs5536_ide_fixup);
 159DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
 160                         loongson_nec_fixup);
 161