Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/mips/loongson/common/cs5536/cs5536_ohci.c
10820 views
1
/*
2
* the OHCI Virtual Support Module of AMD CS5536
3
*
4
* Copyright (C) 2007 Lemote, Inc.
5
* Author : jlliu, [email protected]
6
*
7
* Copyright (C) 2009 Lemote, Inc.
8
* Author: Wu Zhangjin, [email protected]
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
_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
53
lo = value;
54
_wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
55
56
value &= 0xfffffff0;
57
hi = 0x40000000 | ((value & 0xff000000) >> 24);
58
lo = 0x000fffff | ((value & 0x00fff000) << 8);
59
_wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo);
60
}
61
break;
62
case PCI_OHCI_INT_REG:
63
_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
64
lo &= ~(0xf << PIC_YSEL_LOW_USB_SHIFT);
65
if (value) /* enable all the usb interrupt in PIC */
66
lo |= (CS5536_USB_INTR << PIC_YSEL_LOW_USB_SHIFT);
67
_wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
68
break;
69
default:
70
break;
71
}
72
}
73
74
u32 pci_ohci_read_reg(int reg)
75
{
76
u32 conf_data = 0;
77
u32 hi, lo;
78
79
switch (reg) {
80
case PCI_VENDOR_ID:
81
conf_data =
82
CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID);
83
break;
84
case PCI_COMMAND:
85
_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
86
if (hi & PCI_COMMAND_MASTER)
87
conf_data |= PCI_COMMAND_MASTER;
88
if (hi & PCI_COMMAND_MEMORY)
89
conf_data |= PCI_COMMAND_MEMORY;
90
break;
91
case PCI_STATUS:
92
conf_data |= PCI_STATUS_66MHZ;
93
conf_data |= PCI_STATUS_FAST_BACK;
94
_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
95
if (lo & SB_PARE_ERR_FLAG)
96
conf_data |= PCI_STATUS_PARITY;
97
conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
98
break;
99
case PCI_CLASS_REVISION:
100
_rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
101
conf_data = lo & 0x000000ff;
102
conf_data |= (CS5536_OHCI_CLASS_CODE << 8);
103
break;
104
case PCI_CACHE_LINE_SIZE:
105
conf_data =
106
CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
107
PCI_NORMAL_LATENCY_TIMER);
108
break;
109
case PCI_BAR0_REG:
110
_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
111
if (lo & SOFT_BAR_OHCI_FLAG) {
112
conf_data = CS5536_OHCI_RANGE |
113
PCI_BASE_ADDRESS_SPACE_MEMORY;
114
lo &= ~SOFT_BAR_OHCI_FLAG;
115
_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
116
} else {
117
_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
118
conf_data = lo & 0xffffff00;
119
conf_data &= ~0x0000000f; /* 32bit mem */
120
}
121
break;
122
case PCI_CARDBUS_CIS:
123
conf_data = PCI_CARDBUS_CIS_POINTER;
124
break;
125
case PCI_SUBSYSTEM_VENDOR_ID:
126
conf_data =
127
CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
128
break;
129
case PCI_ROM_ADDRESS:
130
conf_data = PCI_EXPANSION_ROM_BAR;
131
break;
132
case PCI_CAPABILITY_LIST:
133
conf_data = PCI_CAPLIST_USB_POINTER;
134
break;
135
case PCI_INTERRUPT_LINE:
136
conf_data =
137
CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
138
break;
139
case PCI_OHCI_INT_REG:
140
_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
141
if ((lo & 0x00000f00) == CS5536_USB_INTR)
142
conf_data = 1;
143
break;
144
default:
145
break;
146
}
147
148
return conf_data;
149
}
150
151