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 19void 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 74u32 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