]> git.karo-electronics.de Git - mv-sheeva.git/blob - arch/mips/loongson/common/cs5536/cs5536_ehci.c
74f9c59d36afbdce61018451a14c4187a23348e4
[mv-sheeva.git] / arch / mips / loongson / common / cs5536 / cs5536_ehci.c
1 /*
2  * the EHCI 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, wuzj@lemote.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_ehci_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_EHCI), &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_EHCI), 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_EHCI_FLAG;
50                         _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
51                 } else if ((value & 0x01) == 0x00) {
52                         _wrmsr(USB_MSR_REG(USB_EHCI), 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_BM4), hi, lo);
58                 }
59                 break;
60         case PCI_EHCI_LEGSMIEN_REG:
61                 _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
62                 hi &= 0x003f0000;
63                 hi |= (value & 0x3f) << 16;
64                 _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
65                 break;
66         case PCI_EHCI_FLADJ_REG:
67                 _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
68                 hi &= ~0x00003f00;
69                 hi |= value & 0x00003f00;
70                 _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
71                 break;
72         default:
73                 break;
74         }
75 }
76
77 u32 pci_ehci_read_reg(int reg)
78 {
79         u32 conf_data = 0;
80         u32 hi, lo;
81
82         switch (reg) {
83         case PCI_VENDOR_ID:
84                 conf_data =
85                     CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID);
86                 break;
87         case PCI_COMMAND:
88                 _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
89                 if (hi & PCI_COMMAND_MASTER)
90                         conf_data |= PCI_COMMAND_MASTER;
91                 if (hi & PCI_COMMAND_MEMORY)
92                         conf_data |= PCI_COMMAND_MEMORY;
93                 break;
94         case PCI_STATUS:
95                 conf_data |= PCI_STATUS_66MHZ;
96                 conf_data |= PCI_STATUS_FAST_BACK;
97                 _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
98                 if (lo & SB_PARE_ERR_FLAG)
99                         conf_data |= PCI_STATUS_PARITY;
100                 conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
101                 break;
102         case PCI_CLASS_REVISION:
103                 _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
104                 conf_data = lo & 0x000000ff;
105                 conf_data |= (CS5536_EHCI_CLASS_CODE << 8);
106                 break;
107         case PCI_CACHE_LINE_SIZE:
108                 conf_data =
109                     CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
110                                             PCI_NORMAL_LATENCY_TIMER);
111                 break;
112         case PCI_BAR0_REG:
113                 _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
114                 if (lo & SOFT_BAR_EHCI_FLAG) {
115                         conf_data = CS5536_EHCI_RANGE |
116                             PCI_BASE_ADDRESS_SPACE_MEMORY;
117                         lo &= ~SOFT_BAR_EHCI_FLAG;
118                         _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
119                 } else {
120                         _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
121                         conf_data = lo & 0xfffff000;
122                 }
123                 break;
124         case PCI_CARDBUS_CIS:
125                 conf_data = PCI_CARDBUS_CIS_POINTER;
126                 break;
127         case PCI_SUBSYSTEM_VENDOR_ID:
128                 conf_data =
129                     CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
130                 break;
131         case PCI_ROM_ADDRESS:
132                 conf_data = PCI_EXPANSION_ROM_BAR;
133                 break;
134         case PCI_CAPABILITY_LIST:
135                 conf_data = PCI_CAPLIST_USB_POINTER;
136                 break;
137         case PCI_INTERRUPT_LINE:
138                 conf_data =
139                     CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
140                 break;
141         case PCI_EHCI_LEGSMIEN_REG:
142                 _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
143                 conf_data = (hi & 0x003f0000) >> 16;
144                 break;
145         case PCI_EHCI_LEGSMISTS_REG:
146                 _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
147                 conf_data = (hi & 0x3f000000) >> 24;
148                 break;
149         case PCI_EHCI_FLADJ_REG:
150                 _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
151                 conf_data = hi & 0x00003f00;
152                 break;
153         default:
154                 break;
155         }
156
157         return conf_data;
158 }