ALSA: hda - Fix probe of Toshiba laptops with ALC268 codec
[pandora-kernel.git] / arch / mips / cavium-octeon / pci-common.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2005-2007 Cavium Networks
7  */
8 #include <linux/kernel.h>
9 #include <linux/init.h>
10 #include <linux/pci.h>
11 #include <linux/interrupt.h>
12 #include <linux/time.h>
13 #include <linux/delay.h>
14 #include "pci-common.h"
15
16 typeof(pcibios_map_irq) *octeon_pcibios_map_irq;
17 enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID;
18
19 /**
20  * Map a PCI device to the appropriate interrupt line
21  *
22  * @param dev    The Linux PCI device structure for the device to map
23  * @param slot   The slot number for this device on __BUS 0__. Linux
24  *               enumerates through all the bridges and figures out the
25  *               slot on Bus 0 where this device eventually hooks to.
26  * @param pin    The PCI interrupt pin read from the device, then swizzled
27  *               as it goes through each bridge.
28  * @return Interrupt number for the device
29  */
30 int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
31 {
32         if (octeon_pcibios_map_irq)
33                 return octeon_pcibios_map_irq(dev, slot, pin);
34         else
35                 panic("octeon_pcibios_map_irq doesn't point to a "
36                       "pcibios_map_irq() function");
37 }
38
39
40 /**
41  * Called to perform platform specific PCI setup
42  *
43  * @param dev
44  * @return
45  */
46 int pcibios_plat_dev_init(struct pci_dev *dev)
47 {
48         uint16_t config;
49         uint32_t dconfig;
50         int pos;
51         /*
52          * Force the Cache line setting to 64 bytes. The standard
53          * Linux bus scan doesn't seem to set it. Octeon really has
54          * 128 byte lines, but Intel bridges get really upset if you
55          * try and set values above 64 bytes. Value is specified in
56          * 32bit words.
57          */
58         pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 64 / 4);
59         /* Set latency timers for all devices */
60         pci_write_config_byte(dev, PCI_LATENCY_TIMER, 48);
61
62         /* Enable reporting System errors and parity errors on all devices */
63         /* Enable parity checking and error reporting */
64         pci_read_config_word(dev, PCI_COMMAND, &config);
65         config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
66         pci_write_config_word(dev, PCI_COMMAND, config);
67
68         if (dev->subordinate) {
69                 /* Set latency timers on sub bridges */
70                 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 48);
71                 /* More bridge error detection */
72                 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config);
73                 config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
74                 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config);
75         }
76
77         /* Enable the PCIe normal error reporting */
78         pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
79         if (pos) {
80                 /* Update Device Control */
81                 pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config);
82                 /* Correctable Error Reporting */
83                 config |= PCI_EXP_DEVCTL_CERE;
84                 /* Non-Fatal Error Reporting */
85                 config |= PCI_EXP_DEVCTL_NFERE;
86                 /* Fatal Error Reporting */
87                 config |= PCI_EXP_DEVCTL_FERE;
88                 /* Unsupported Request */
89                 config |= PCI_EXP_DEVCTL_URRE;
90                 pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
91         }
92
93         /* Find the Advanced Error Reporting capability */
94         pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
95         if (pos) {
96                 /* Clear Uncorrectable Error Status */
97                 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
98                                       &dconfig);
99                 pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
100                                        dconfig);
101                 /* Enable reporting of all uncorrectable errors */
102                 /* Uncorrectable Error Mask - turned on bits disable errors */
103                 pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0);
104                 /*
105                  * Leave severity at HW default. This only controls if
106                  * errors are reported as uncorrectable or
107                  * correctable, not if the error is reported.
108                  */
109                 /* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */
110                 /* Clear Correctable Error Status */
111                 pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig);
112                 pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig);
113                 /* Enable reporting of all correctable errors */
114                 /* Correctable Error Mask - turned on bits disable errors */
115                 pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0);
116                 /* Advanced Error Capabilities */
117                 pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig);
118                 /* ECRC Generation Enable */
119                 if (config & PCI_ERR_CAP_ECRC_GENC)
120                         config |= PCI_ERR_CAP_ECRC_GENE;
121                 /* ECRC Check Enable */
122                 if (config & PCI_ERR_CAP_ECRC_CHKC)
123                         config |= PCI_ERR_CAP_ECRC_CHKE;
124                 pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig);
125                 /* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */
126                 /* Report all errors to the root complex */
127                 pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND,
128                                        PCI_ERR_ROOT_CMD_COR_EN |
129                                        PCI_ERR_ROOT_CMD_NONFATAL_EN |
130                                        PCI_ERR_ROOT_CMD_FATAL_EN);
131                 /* Clear the Root status register */
132                 pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig);
133                 pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig);
134         }
135
136         return 0;
137 }