MIPS: Malta: Select 32bit DMA zone for 64-bit kernels
[linux-drm-fsl-dcu.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                         _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 }