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