1/* 2 * the IDE 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_ide_write_reg(int reg, u32 value) 20{ 21 u32 hi = 0, lo = value; 22 23 switch (reg) { 24 case PCI_COMMAND: 25 _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); 26 if (value & PCI_COMMAND_MASTER) 27 lo |= (0x03 << 4); 28 else 29 lo &= ~(0x03 << 4); 30 _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); 31 break; 32 case PCI_STATUS: 33 if (value & PCI_STATUS_PARITY) { 34 _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); 35 if (lo & SB_PARE_ERR_FLAG) { 36 lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; 37 _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); 38 } 39 } 40 break; 41 case PCI_CACHE_LINE_SIZE: 42 value &= 0x0000ff00; 43 _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); 44 hi &= 0xffffff00; 45 hi |= (value >> 8); 46 _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); 47 break; 48 case PCI_BAR4_REG: 49 if (value == PCI_BAR_RANGE_MASK) { 50 _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); 51 lo |= SOFT_BAR_IDE_FLAG; 52 _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); 53 } else if (value & 0x01) { 54 _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); 55 lo = (value & 0xfffffff0) | 0x1; 56 _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo); 57 58 value &= 0xfffffffc; 59 hi = 0x60000000 | ((value & 0x000ff000) >> 12); 60 lo = 0x000ffff0 | ((value & 0x00000fff) << 20); 61 _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo); 62 } 63 break; 64 case PCI_IDE_CFG_REG: 65 if (value == CS5536_IDE_FLASH_SIGNATURE) { 66 _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); 67 lo |= 0x01; 68 _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); 69 } else { 70 _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); 71 lo = value; 72 _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo); 73 } 74 break; 75 case PCI_IDE_DTC_REG: 76 _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); 77 lo = value; 78 _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo); 79 break; 80 case PCI_IDE_CAST_REG: 81 _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); 82 lo = value; 83 _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo); 84 break; 85 case PCI_IDE_ETC_REG: 86 _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); 87 lo = value; 88 _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo); 89 break; 90 case PCI_IDE_PM_REG: 91 _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); 92 lo = value; 93 _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo); 94 break; 95 default: 96 break; 97 } 98} 99 100u32 pci_ide_read_reg(int reg) 101{ 102 u32 conf_data = 0; 103 u32 hi, lo; 104 105 switch (reg) { 106 case PCI_VENDOR_ID: 107 conf_data = 108 CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID); 109 break; 110 case PCI_COMMAND: 111 _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); 112 if (lo & 0xfffffff0) 113 conf_data |= PCI_COMMAND_IO; 114 _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); 115 if ((lo & 0x30) == 0x30) 116 conf_data |= PCI_COMMAND_MASTER; 117 break; 118 case PCI_STATUS: 119 conf_data |= PCI_STATUS_66MHZ; 120 conf_data |= PCI_STATUS_FAST_BACK; 121 _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); 122 if (lo & SB_PARE_ERR_FLAG) 123 conf_data |= PCI_STATUS_PARITY; 124 conf_data |= PCI_STATUS_DEVSEL_MEDIUM; 125 break; 126 case PCI_CLASS_REVISION: 127 _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo); 128 conf_data = lo & 0x000000ff; 129 conf_data |= (CS5536_IDE_CLASS_CODE << 8); 130 break; 131 case PCI_CACHE_LINE_SIZE: 132 _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); 133 hi &= 0x000000f8; 134 conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi); 135 break; 136 case PCI_BAR4_REG: 137 _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); 138 if (lo & SOFT_BAR_IDE_FLAG) { 139 conf_data = CS5536_IDE_RANGE | 140 PCI_BASE_ADDRESS_SPACE_IO; 141 lo &= ~SOFT_BAR_IDE_FLAG; 142 _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); 143 } else { 144 _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); 145 conf_data = lo & 0xfffffff0; 146 conf_data |= 0x01; 147 conf_data &= ~0x02; 148 } 149 break; 150 case PCI_CARDBUS_CIS: 151 conf_data = PCI_CARDBUS_CIS_POINTER; 152 break; 153 case PCI_SUBSYSTEM_VENDOR_ID: 154 conf_data = 155 CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID); 156 break; 157 case PCI_ROM_ADDRESS: 158 conf_data = PCI_EXPANSION_ROM_BAR; 159 break; 160 case PCI_CAPABILITY_LIST: 161 conf_data = PCI_CAPLIST_POINTER; 162 break; 163 case PCI_INTERRUPT_LINE: 164 conf_data = 165 CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR); 166 break; 167 case PCI_IDE_CFG_REG: 168 _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); 169 conf_data = lo; 170 break; 171 case PCI_IDE_DTC_REG: 172 _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); 173 conf_data = lo; 174 break; 175 case PCI_IDE_CAST_REG: 176 _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); 177 conf_data = lo; 178 break; 179 case PCI_IDE_ETC_REG: 180 _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); 181 conf_data = lo; 182 break; 183 case PCI_IDE_PM_REG: 184 _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); 185 conf_data = lo; 186 break; 187 default: 188 break; 189 } 190 191 return conf_data; 192} 193