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