4 * Config Southbridge USB controller
\r
8 * @xrefitem bom "File Content Label" "Release Content"
\r
9 * @e project: CIMx-SB
\r
11 * @e \$Revision:$ @e \$Date:$
\r
15 *****************************************************************************
\r
17 * This file is part of the coreboot project.
\r
19 * Copyright (C) 2010 Advanced Micro Devices, Inc.
\r
21 * This program is free software; you can redistribute it and/or modify
\r
22 * it under the terms of the GNU General Public License as published by
\r
23 * the Free Software Foundation; version 2 of the License.
\r
25 * This program is distributed in the hope that it will be useful,
\r
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
28 * GNU General Public License for more details.
\r
30 * You should have received a copy of the GNU General Public License
\r
31 * along with this program; if not, write to the Free Software
\r
32 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\r
33 * ***************************************************************************
\r
38 #include "SBPLATFORM.h"
\r
41 // Declaration of local functions
\r
45 * EhciInitAfterPciInit - Config USB controller after PCI emulation
\r
47 * @param[in] Value Controller PCI config address (bus# + device# + function#)
\r
48 * @param[in] pConfig Southbridge configuration structure pointer.
\r
50 VOID EhciInitAfterPciInit (IN UINT32 Value, IN AMDSBCFG* pConfig);
\r
52 * OhciInitAfterPciInit - Config USB OHCI controller after PCI emulation
\r
54 * @param[in] Value Controller PCI config address (bus# + device# + function#)
\r
55 * @param[in] pConfig Southbridge configuration structure pointer.
\r
57 VOID OhciInitAfterPciInit (IN UINT32 Value, IN AMDSBCFG* pConfig);
\r
60 * SetEhciP11Wr - FIXME
\r
62 * @param[in] Value Controller PCI config address (bus# + device# + function#)
\r
63 * @param[in] pConfig Southbridge configuration structure pointer.
\r
65 UINT32 SetEhciPllWr (IN UINT32 Value, IN AMDSBCFG* pConfig);
\r
69 * usbInitBeforePciEnum - Config USB controller before PCI emulation
\r
73 * @param[in] pConfig Southbridge configuration structure pointer.
\r
77 usbInitBeforePciEnum (
\r
78 IN AMDSBCFG* pConfig
\r
81 // Disabled All USB controller
\r
82 RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEF, AccWidthUint8, BIT7, 0);
\r
83 // Clear PM_IO 0x65[4] UsbResetByPciRstEnable, Set this bit so that usb gets reset whenever there is PCIRST.
\r
84 // Enable UsbResumeEnable (USB PME) * Default value
\r
85 // In SB700 USB SleepCtrl set as BIT10+BIT9, but SB800 default is BIT9+BIT8 (6 uframes)
\r
86 RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF0, AccWidthUint16 | S3_SAVE, ~BIT2, BIT2 + BIT7 + BIT8 + BIT9);
\r
87 RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEF, AccWidthUint8, 0, pConfig->USBMODE.UsbModeReg);
\r
91 * usbInitAfterPciInit - Config USB controller after PCI emulation
\r
95 * @param[in] pConfig Southbridge configuration structure pointer.
\r
99 usbInitAfterPciInit (
\r
100 IN AMDSBCFG* pConfig
\r
103 RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGED, AccWidthUint8, ~BIT1, BIT1);
\r
105 usb1EhciInitAfterPciInit (pConfig);
\r
106 usb2EhciInitAfterPciInit (pConfig);
\r
107 usb3EhciInitAfterPciInit (pConfig);
\r
108 usb1OhciInitAfterPciInit (pConfig);
\r
109 usb2OhciInitAfterPciInit (pConfig);
\r
110 usb3OhciInitAfterPciInit (pConfig);
\r
111 usb4OhciInitAfterPciInit (pConfig);
\r
113 if ( pConfig->UsbPhyPowerDown ) {
\r
114 RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF0, AccWidthUint8, ~BIT0, BIT0);
\r
117 RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF0, AccWidthUint8, ~BIT0, 0);
\r
123 * usb1EhciInitAfterPciInit - Config USB1 EHCI controller after PCI emulation
\r
127 * @param[in] pConfig Southbridge configuration structure pointer.
\r
131 usb1EhciInitAfterPciInit (
\r
132 IN AMDSBCFG* pConfig
\r
136 ddDeviceId = (USB1_EHCI_BUS_DEV_FUN << 16);
\r
137 EhciInitAfterPciInit (ddDeviceId, pConfig);
\r
141 * usb2EhciInitAfterPciInit - Config USB2 EHCI controller after PCI emulation
\r
145 * @param[in] pConfig Southbridge configuration structure pointer.
\r
149 usb2EhciInitAfterPciInit (
\r
150 IN AMDSBCFG* pConfig
\r
154 ddDeviceId = (USB2_EHCI_BUS_DEV_FUN << 16);
\r
155 EhciInitAfterPciInit (ddDeviceId, pConfig);
\r
159 * usb3EhciInitAfterPciInit - Config USB3 EHCI controller after PCI emulation
\r
163 * @param[in] pConfig Southbridge configuration structure pointer.
\r
167 usb3EhciInitAfterPciInit (
\r
168 IN AMDSBCFG* pConfig
\r
172 ddDeviceId = (USB3_EHCI_BUS_DEV_FUN << 16);
\r
173 EhciInitAfterPciInit (ddDeviceId, pConfig);
\r
177 EhciInitAfterPciInit (
\r
179 IN AMDSBCFG* pConfig
\r
182 UINT32 ddBarAddress;
\r
185 ReadPCI ((UINT32) Value + SB_EHCI_REG10, AccWidthUint32, &ddBarAddress);
\r
186 if ( (ddBarAddress != - 1) && (ddBarAddress != 0) ) {
\r
187 //Enable Memory access
\r
188 RWPCI ((UINT32) Value + SB_EHCI_REG04, AccWidthUint8, 0, BIT1);
\r
189 if (pConfig->BuildParameters.EhciSsid != NULL ) {
\r
190 RWPCI ((UINT32) Value + SB_EHCI_REG2C, AccWidthUint32 | S3_SAVE, 0x00, pConfig->BuildParameters.EhciSsid);
\r
192 //USB Common PHY CAL & Control Register setting
\r
193 ddVar = 0x00020F00;
\r
194 WriteMEM (ddBarAddress + SB_EHCI_BAR_REGC0, AccWidthUint32, &ddVar);
\r
195 // RPR IN AND OUT DATA PACKET FIFO THRESHOLD
\r
196 // EHCI BAR 0xA4 //IN threshold bits[7:0]=0x40 //OUT threshold bits[23:16]=0x40
\r
197 RWMEM (ddBarAddress + SB_EHCI_BAR_REGA4, AccWidthUint32, 0xFF00FF00, 0x00400040);
\r
198 // RPR EHCI Dynamic Clock Gating Feature
\r
199 RWMEM (ddBarAddress + SB_EHCI_BAR_REGBC, AccWidthUint32, ~BIT12, 0);
\r
200 // RPR Enable adding extra flops to PHY rsync path
\r
202 // EHCI_BAR 0xB4 [6] = 1
\r
203 // EHCI_BAR 0xB4 [7] = 0
\r
204 // EHCI_BAR 0xB4 [12] = 0 ("VLoad")
\r
205 // All other bit field untouched
\r
207 // EHCI_BAR 0xB4[12] = 1
\r
208 RWMEM (ddBarAddress + SB_EHCI_BAR_REGB4, AccWidthUint32, ~(BIT6 + BIT7 + BIT12), 0x00);
\r
209 RWMEM (ddBarAddress + SB_EHCI_BAR_REGB4, AccWidthUint32, ~BIT12, BIT12);
\r
210 //Set EHCI_pci_configx50[6]='1' to disable EHCI MSI support
\r
211 //RPR recommended setting "EHCI Async Park Mode"
\r
212 //Set EHCI_pci_configx50[23]='0' to enable "EHCI Async Park Mode support"
\r
213 //RPR Enabling EHCI Async Stop Enhancement
\r
214 //Set EHCI_pci_configx50[29]='1' to disableEnabling EHCI Async Stop Enhancement
\r
215 RWPCI ((UINT32) Value + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, ~(BIT23), BIT29 + BIT23 + BIT8 + BIT6);
\r
216 // RPR recommended setting "EHCI Advance PHY Power Savings"
\r
217 // Set EHCI_pci_configx50[31]='1'
\r
218 // Fix for EHCI controller driver yellow sign issue under device manager
\r
219 // when used in conjunction with HSET tool driver. EHCI PCI config 0x50[20]=1
\r
220 RWPCI ((UINT32) Value + SB_EHCI_REG50 + 2, AccWidthUint16 | S3_SAVE, (UINT16)0xFFFF, BIT15);
\r
221 // RPR USB Delay A-Link Express L1 State
\r
222 // RPR PING Response Fix Enable EHCI_PCI_Config x54[1] = 1
\r
223 // RPR Empty-list Detection Fix Enable EHCI_PCI_Config x54[3] = 1
\r
224 RWPCI ((UINT32) Value + SB_EHCI_REG54, AccWidthUint32 | S3_SAVE, ~BIT0, BIT0);
\r
225 if ( pConfig->BuildParameters.UsbMsi) {
\r
226 RWPCI ((UINT32) Value + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, ~BIT6, 0x00);
\r
232 * usb1OhciInitAfterPciInit - Config USB1 OHCI controller after PCI emulation
\r
236 * @param[in] pConfig Southbridge configuration structure pointer.
\r
240 usb1OhciInitAfterPciInit (
\r
241 IN AMDSBCFG* pConfig
\r
245 ddDeviceId = (USB1_OHCI_BUS_DEV_FUN << 16);
\r
246 OhciInitAfterPciInit (ddDeviceId, pConfig);
\r
250 * usb2OhciInitAfterPciInit - Config USB2 OHCI controller after PCI emulation
\r
254 * @param[in] pConfig Southbridge configuration structure pointer.
\r
258 usb2OhciInitAfterPciInit (
\r
259 IN AMDSBCFG* pConfig
\r
263 ddDeviceId = (USB2_OHCI_BUS_DEV_FUN << 16);
\r
264 OhciInitAfterPciInit (ddDeviceId, pConfig);
\r
268 * usb3OhciInitAfterPciInit - Config USB3 OHCI controller after PCI emulation
\r
272 * @param[in] pConfig Southbridge configuration structure pointer.
\r
276 usb3OhciInitAfterPciInit (
\r
277 IN AMDSBCFG* pConfig
\r
281 ddDeviceId = (USB3_OHCI_BUS_DEV_FUN << 16);
\r
282 OhciInitAfterPciInit (ddDeviceId, pConfig);
\r
286 * usb4OhciInitAfterPciInit - Config USB4 OHCI controller after PCI emulation
\r
290 * @param[in] pConfig Southbridge configuration structure pointer.
\r
294 usb4OhciInitAfterPciInit (
\r
295 IN AMDSBCFG* pConfig
\r
299 ddDeviceId = (USB4_OHCI_BUS_DEV_FUN << 16);
\r
300 OhciInitAfterPciInit (ddDeviceId, pConfig);
\r
301 if (pConfig->BuildParameters.Ohci4Ssid != NULL ) {
\r
302 RWPCI ((USB4_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG2C, AccWidthUint32 | S3_SAVE, 0x00, pConfig->BuildParameters.Ohci4Ssid);
\r
307 OhciInitAfterPciInit (
\r
309 IN AMDSBCFG* pConfig
\r
312 // Disable the MSI capability of USB host controllers
\r
313 RWPCI ((UINT32) Value + SB_OHCI_REG40 + 1, AccWidthUint8 | S3_SAVE, 0xFF, BIT0);
\r
314 RWPCI ((UINT32) Value + SB_OHCI_REG50, AccWidthUint8 | S3_SAVE, ~(BIT5 + BIT12), 0x00);
\r
315 // RPR USB SMI Handshake
\r
316 RWPCI ((UINT32) Value + SB_OHCI_REG50 + 1, AccWidthUint8 | S3_SAVE, ~BIT4, 0x00);
\r
318 RWPCI ((UINT32) Value + SB_OHCI_REG50 + 1, AccWidthUint8 | S3_SAVE, 0xFC, 0x00);
\r
319 if (Value != (USB4_OHCI_BUS_DEV_FUN << 16)) {
\r
320 if ( pConfig->BuildParameters.OhciSsid != NULL ) {
\r
321 RWPCI ((UINT32) Value + SB_OHCI_REG2C, AccWidthUint32 | S3_SAVE, 0x00, pConfig->BuildParameters.OhciSsid);
\r
324 //RPR recommended setting to, enable fix to cover the corner case S3 wake up issue from some USB 1.1 devices
\r
325 //OHCI 0_PCI_Config 0x50[30] = 1
\r
326 RWPCI ((UINT32) Value + SB_OHCI_REG50 + 3, AccWidthUint8 | S3_SAVE, ~BIT6, BIT6);
\r
327 if ( pConfig->BuildParameters.UsbMsi) {
\r
328 RWPCI ((UINT32) Value + SB_OHCI_REG40 + 1, AccWidthUint8 | S3_SAVE, ~BIT0, 0x00);
\r
329 RWPCI ((UINT32) Value + SB_OHCI_REG50, AccWidthUint8 | S3_SAVE, ~BIT5, BIT5);
\r
337 IN AMDSBCFG* pConfig
\r
340 UINT32 ddRetureValue;
\r
341 UINT32 ddBarAddress;
\r
347 // Memory, and etc.
\r
349 RWPCI ((UINT32) Value + 0xC4, AccWidthUint8, 0xF0, 0x00);
\r
350 RWPCI ((UINT32) Value + 0x04, AccWidthUint8, 0xFF, 0x02);
\r
352 ReadPCI ((UINT32) Value + 0x10, AccWidthUint32, &ddBarAddress);
\r
353 for (portSC = 0x64; portSC < 0x75; portSC += 0x04 ) {
\r
354 // Get OHCI command registers
\r
355 ReadMEM (ddBarAddress + portSC, AccWidthUint16, &dwVar);
\r
356 if ( dwVar & BIT6 ) {
\r
357 ddRetureValue = ddBarAddress + portSC;
\r
358 RWMEM (ddBarAddress + portSC, AccWidthUint16, ~BIT6, 0);
\r
361 ReadMEM (ddBarAddress + portSC, AccWidthUint16, &dwData);
\r
362 if (dwData == 0x1005) break;
\r
367 return ddRetureValue;
\r
371 usbSetPllDuringS3 (
\r
372 IN AMDSBCFG* pConfig
\r
375 UINT32 resumeEhciPortTmp;
\r
376 UINT32 resumeEhciPort;
\r
377 resumeEhciPortTmp = 0;
\r
378 resumeEhciPort = 0;
\r
379 // UINT32 ddDeviceId;
\r
380 //if Force Port Resume == 1
\r
382 // clear Force Port Resume;
\r
383 // while (!(PORTSC == 0x1005)){wait 5 us; read PORTSC;}
\r
385 if (pConfig->USBMODE.UsbModeReg & BIT1) {
\r
386 resumeEhciPortTmp = SetEhciPllWr (USB1_EHCI_BUS_DEV_FUN << 16, pConfig);
\r
387 if (resumeEhciPortTmp > 0) resumeEhciPort = resumeEhciPortTmp;
\r
389 if (pConfig->USBMODE.UsbModeReg & BIT3) {
\r
390 resumeEhciPortTmp = SetEhciPllWr (USB2_EHCI_BUS_DEV_FUN << 16, pConfig);
\r
391 if (resumeEhciPortTmp > 0) resumeEhciPort = resumeEhciPortTmp;
\r
393 if (pConfig->USBMODE.UsbModeReg & BIT5) {
\r
394 resumeEhciPortTmp = SetEhciPllWr (USB3_EHCI_BUS_DEV_FUN << 16, pConfig);
\r
395 if (resumeEhciPortTmp > 0) resumeEhciPort = resumeEhciPortTmp;
\r
398 RWPCI ((UINT32) (USB1_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint32, ~BIT29, 0);
\r
399 RWPCI ((UINT32) (USB2_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint32, ~BIT29, 0);
\r
400 RWPCI ((UINT32) (USB3_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint32, ~BIT29, 0);
\r
401 RWPCI ((UINT32) (USB4_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint32, ~BIT29, 0);
\r
402 RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF3, AccWidthUint8, 0, 0x20);
\r
404 RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF3, AccWidthUint8, 0, 0x00);
\r
405 RWPCI ((UINT32) (USB1_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint32, ~BIT29, BIT29);
\r
406 RWPCI ((UINT32) (USB2_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint32, ~BIT29, BIT29);
\r
407 RWPCI ((UINT32) (USB3_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint32, ~BIT29, BIT29);
\r
408 RWPCI ((UINT32) (USB4_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint32, ~BIT29, BIT29);
\r
410 if (resumeEhciPort > 0) {
\r
411 RWMEM (resumeEhciPort, AccWidthUint8, ~BIT7, BIT7);
\r
413 RWMEM (resumeEhciPort, AccWidthUint8, ~BIT6, BIT6);
\r
416 RWPCI ((UINT32) (USB1_EHCI_BUS_DEV_FUN << 16) + 0xC4, AccWidthUint8, 0xF0, 0x03);
\r
417 RWPCI ((UINT32) (USB2_EHCI_BUS_DEV_FUN << 16) + 0xC4, AccWidthUint8, 0xF0, 0x03);
\r
418 RWPCI ((UINT32) (USB3_EHCI_BUS_DEV_FUN << 16) + 0xC4, AccWidthUint8, 0xF0, 0x03);
\r