2 * ops-vr41xx.c, PCI configuration routines for the PCIU of NEC VR4100 series.
4 * Copyright (C) 2001-2003 MontaVista Software Inc.
5 * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
6 * Copyright (C) 2004-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
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.
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.
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
24 * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
25 * - New creation, NEC VR4122 and VR4131 are supported.
27 #include <linux/pci.h>
28 #include <linux/types.h>
32 #define PCICONFDREG (void __iomem *)KSEG1ADDR(0x0f000c14)
33 #define PCICONFAREG (void __iomem *)KSEG1ADDR(0x0f000c18)
35 static inline int set_pci_configuration_address(unsigned char number
,
36 unsigned int devfn
, int where
)
40 * Type 0 configuration
42 if (PCI_SLOT(devfn
) < 11 || where
> 0xff)
45 writel((1U << PCI_SLOT(devfn
)) | (PCI_FUNC(devfn
) << 8) |
46 (where
& 0xfc), PCICONFAREG
);
49 * Type 1 configuration
54 writel(((uint32_t)number
<< 16) | ((devfn
& 0xff) << 8) |
55 (where
& 0xfc) | 1U, PCICONFAREG
);
61 static int pci_config_read(struct pci_bus
*bus
, unsigned int devfn
, int where
,
62 int size
, uint32_t *val
)
67 if (set_pci_configuration_address(bus
->number
, devfn
, where
) < 0)
68 return PCIBIOS_DEVICE_NOT_FOUND
;
70 data
= readl(PCICONFDREG
);
74 *val
= (data
>> ((where
& 3) << 3)) & 0xffU
;
77 *val
= (data
>> ((where
& 2) << 3)) & 0xffffU
;
83 return PCIBIOS_FUNC_NOT_SUPPORTED
;
86 return PCIBIOS_SUCCESSFUL
;
89 static int pci_config_write(struct pci_bus
*bus
, unsigned int devfn
, int where
,
90 int size
, uint32_t val
)
95 if (set_pci_configuration_address(bus
->number
, devfn
, where
) < 0)
96 return PCIBIOS_DEVICE_NOT_FOUND
;
98 data
= readl(PCICONFDREG
);
102 shift
= (where
& 3) << 3;
103 data
&= ~(0xffU
<< shift
);
104 data
|= ((val
& 0xffU
) << shift
);
107 shift
= (where
& 2) << 3;
108 data
&= ~(0xffffU
<< shift
);
109 data
|= ((val
& 0xffffU
) << shift
);
115 return PCIBIOS_FUNC_NOT_SUPPORTED
;
118 writel(data
, PCICONFDREG
);
120 return PCIBIOS_SUCCESSFUL
;
123 struct pci_ops vr41xx_pci_ops
= {
124 .read
= pci_config_read
,
125 .write
= pci_config_write
,