Merge branch 'davinci-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / arch / mips / loongson / common / cs5536 / cs5536_ohci.c
1 /*
2  * the OHCI Virtual Support Module of AMD CS5536
3  *
4  * Copyright (C) 2007 Lemote, Inc.
5  * Author : jlliu, liujl@lemote.com
6  *
7  * Copyright (C) 2009 Lemote, Inc.
8  * Author: Wu Zhangjin, wuzhangjin@gmail.com
9  *
10  * This program is free software; you can redistribute  it and/or modify it
11  * under  the terms of  the GNU General  Public License as published by the
12  * Free Software Foundation;  either version 2 of the  License, or (at your
13  * option) any later version.
14  */
15
16 #include <cs5536/cs5536.h>
17 #include <cs5536/cs5536_pci.h>
18
19 void pci_ohci_write_reg(int reg, u32 value)
20 {
21         u32 hi = 0, lo = value;
22
23         switch (reg) {
24         case PCI_COMMAND:
25                 _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
26                 if (value & PCI_COMMAND_MASTER)
27                         hi |= PCI_COMMAND_MASTER;
28                 else
29                         hi &= ~PCI_COMMAND_MASTER;
30
31                 if (value & PCI_COMMAND_MEMORY)
32                         hi |= PCI_COMMAND_MEMORY;
33                 else
34                         hi &= ~PCI_COMMAND_MEMORY;
35                 _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
36                 break;
37         case PCI_STATUS:
38                 if (value & PCI_STATUS_PARITY) {
39                         _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
40                         if (lo & SB_PARE_ERR_FLAG) {
41                                 lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
42                                 _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
43                         }
44                 }
45                 break;
46         case PCI_BAR0_REG:
47                 if (value == PCI_BAR_RANGE_MASK) {
48                         _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
49                         lo |= SOFT_BAR_OHCI_FLAG;
50                         _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
51                 } else if ((value & 0x01) == 0x00) {
52                         _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
53
54                         value &= 0xfffffff0;
55                         hi = 0x40000000 | ((value & 0xff000000) >> 24);
56                         lo = 0x000fffff | ((value & 0x00fff000) << 8);
57                         _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo);
58                 }
59                 break;
60         case PCI_OHCI_INT_REG:
61                 _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
62                 lo &= ~(0xf << PIC_YSEL_LOW_USB_SHIFT);
63                 if (value)      /* enable all the usb interrupt in PIC */
64                         lo |= (CS5536_USB_INTR << PIC_YSEL_LOW_USB_SHIFT);
65                 _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
66                 break;
67         default:
68                 break;
69         }
70 }
71
72 u32 pci_ohci_read_reg(int reg)
73 {
74         u32 conf_data = 0;
75         u32 hi, lo;
76
77         switch (reg) {
78         case PCI_VENDOR_ID:
79                 conf_data =
80                     CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID);
81                 break;
82         case PCI_COMMAND:
83                 _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
84                 if (hi & PCI_COMMAND_MASTER)
85                         conf_data |= PCI_COMMAND_MASTER;
86                 if (hi & PCI_COMMAND_MEMORY)
87                         conf_data |= PCI_COMMAND_MEMORY;
88                 break;
89         case PCI_STATUS:
90                 conf_data |= PCI_STATUS_66MHZ;
91                 conf_data |= PCI_STATUS_FAST_BACK;
92                 _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
93                 if (lo & SB_PARE_ERR_FLAG)
94                         conf_data |= PCI_STATUS_PARITY;
95                 conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
96                 break;
97         case PCI_CLASS_REVISION:
98                 _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
99                 conf_data = lo & 0x000000ff;
100                 conf_data |= (CS5536_OHCI_CLASS_CODE << 8);
101                 break;
102         case PCI_CACHE_LINE_SIZE:
103                 conf_data =
104                     CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
105                                             PCI_NORMAL_LATENCY_TIMER);
106                 break;
107         case PCI_BAR0_REG:
108                 _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
109                 if (lo & SOFT_BAR_OHCI_FLAG) {
110                         conf_data = CS5536_OHCI_RANGE |
111                             PCI_BASE_ADDRESS_SPACE_MEMORY;
112                         lo &= ~SOFT_BAR_OHCI_FLAG;
113                         _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
114                 } else {
115                         _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
116                         conf_data = lo & 0xffffff00;
117                         conf_data &= ~0x0000000f;       /* 32bit mem */
118                 }
119                 break;
120         case PCI_CARDBUS_CIS:
121                 conf_data = PCI_CARDBUS_CIS_POINTER;
122                 break;
123         case PCI_SUBSYSTEM_VENDOR_ID:
124                 conf_data =
125                     CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
126                 break;
127         case PCI_ROM_ADDRESS:
128                 conf_data = PCI_EXPANSION_ROM_BAR;
129                 break;
130         case PCI_CAPABILITY_LIST:
131                 conf_data = PCI_CAPLIST_USB_POINTER;
132                 break;
133         case PCI_INTERRUPT_LINE:
134                 conf_data =
135                     CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
136                 break;
137         case PCI_OHCI_INT_REG:
138                 _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
139                 if ((lo & 0x00000f00) == CS5536_USB_INTR)
140                         conf_data = 1;
141                 break;
142         default:
143                 break;
144         }
145
146         return conf_data;
147 }