Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ops-vr41xx.c
Go to the documentation of this file.
1 /*
2  * ops-vr41xx.c, PCI configuration routines for the PCIU of NEC VR4100 series.
3  *
4  * Copyright (C) 2001-2003 MontaVista Software Inc.
5  * Author: Yoichi Yuasa <[email protected]>
6  * Copyright (C) 2004-2005 Yoichi Yuasa <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  */
22 /*
23  * Changes:
24  * MontaVista Software Inc. <[email protected]>
25  * - New creation, NEC VR4122 and VR4131 are supported.
26  */
27 #include <linux/pci.h>
28 #include <linux/types.h>
29 
30 #include <asm/io.h>
31 
32 #define PCICONFDREG (void __iomem *)KSEG1ADDR(0x0f000c14)
33 #define PCICONFAREG (void __iomem *)KSEG1ADDR(0x0f000c18)
34 
35 static inline int set_pci_configuration_address(unsigned char number,
36  unsigned int devfn, int where)
37 {
38  if (number == 0) {
39  /*
40  * Type 0 configuration
41  */
42  if (PCI_SLOT(devfn) < 11 || where > 0xff)
43  return -EINVAL;
44 
45  writel((1U << PCI_SLOT(devfn)) | (PCI_FUNC(devfn) << 8) |
46  (where & 0xfc), PCICONFAREG);
47  } else {
48  /*
49  * Type 1 configuration
50  */
51  if (where > 0xff)
52  return -EINVAL;
53 
54  writel(((uint32_t)number << 16) | ((devfn & 0xff) << 8) |
55  (where & 0xfc) | 1U, PCICONFAREG);
56  }
57 
58  return 0;
59 }
60 
61 static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where,
62  int size, uint32_t *val)
63 {
64  uint32_t data;
65 
66  *val = 0xffffffffU;
67  if (set_pci_configuration_address(bus->number, devfn, where) < 0)
69 
70  data = readl(PCICONFDREG);
71 
72  switch (size) {
73  case 1:
74  *val = (data >> ((where & 3) << 3)) & 0xffU;
75  break;
76  case 2:
77  *val = (data >> ((where & 2) << 3)) & 0xffffU;
78  break;
79  case 4:
80  *val = data;
81  break;
82  default:
84  }
85 
86  return PCIBIOS_SUCCESSFUL;
87 }
88 
89 static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where,
90  int size, uint32_t val)
91 {
92  uint32_t data;
93  int shift;
94 
95  if (set_pci_configuration_address(bus->number, devfn, where) < 0)
97 
98  data = readl(PCICONFDREG);
99 
100  switch (size) {
101  case 1:
102  shift = (where & 3) << 3;
103  data &= ~(0xffU << shift);
104  data |= ((val & 0xffU) << shift);
105  break;
106  case 2:
107  shift = (where & 2) << 3;
108  data &= ~(0xffffU << shift);
109  data |= ((val & 0xffffU) << shift);
110  break;
111  case 4:
112  data = val;
113  break;
114  default:
116  }
117 
118  writel(data, PCICONFDREG);
119 
120  return PCIBIOS_SUCCESSFUL;
121 }
122 
124  .read = pci_config_read,
125  .write = pci_config_write,
126 };