1 /* 2 * Copyright © 2013 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 * 23 */ 24 25 #include "i915_drv.h" 26 #include "intel_drv.h" 27 28 /* 29 * IOSF sideband, see VLV2_SidebandMsg_HAS.docx and 30 * VLV_VLV2_PUNIT_HAS_0.8.docx 31 */ 32 33 /* Standard MMIO read, non-posted */ 34 #define SB_MRD_NP 0x00 35 /* Standard MMIO write, non-posted */ 36 #define SB_MWR_NP 0x01 37 /* Private register read, double-word addressing, non-posted */ 38 #define SB_CRRDDA_NP 0x06 39 /* Private register write, double-word addressing, non-posted */ 40 #define SB_CRWRDA_NP 0x07 41 42 static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn, 43 u32 port, u32 opcode, u32 addr, u32 *val) 44 { 45 u32 cmd, be = 0xf, bar = 0; 46 bool is_read = (opcode == SB_MRD_NP || opcode == SB_CRRDDA_NP); 47 48 cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) | 49 (port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) | 50 (bar << IOSF_BAR_SHIFT); 51 52 WARN_ON(!mutex_is_locked(&dev_priv->sb_lock)); 53 54 if (intel_wait_for_register(dev_priv, 55 VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0, 56 5)) { 57 DRM_DEBUG_DRIVER("IOSF sideband idle wait (%s) timed out\n", 58 is_read ? "read" : "write"); 59 return -EAGAIN; 60 } 61 62 I915_WRITE(VLV_IOSF_ADDR, addr); 63 if (!is_read) 64 I915_WRITE(VLV_IOSF_DATA, *val); 65 I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd); 66 67 if (intel_wait_for_register(dev_priv, 68 VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0, 69 5)) { 70 DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n", 71 is_read ? "read" : "write"); 72 return -ETIMEDOUT; 73 } 74 75 if (is_read) 76 *val = I915_READ(VLV_IOSF_DATA); 77 I915_WRITE(VLV_IOSF_DATA, 0); 78 79 return 0; 80 } 81 82 u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr) 83 { 84 u32 val = 0; 85 86 WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); 87 88 mutex_lock(&dev_priv->sb_lock); 89 vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT, 90 SB_CRRDDA_NP, addr, &val); 91 mutex_unlock(&dev_priv->sb_lock); 92 93 return val; 94 } 95 96 void vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val) 97 { 98 WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); 99 100 mutex_lock(&dev_priv->sb_lock); 101 vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT, 102 SB_CRWRDA_NP, addr, &val); 103 mutex_unlock(&dev_priv->sb_lock); 104 } 105 106 u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg) 107 { 108 u32 val = 0; 109 110 vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_BUNIT, 111 SB_CRRDDA_NP, reg, &val); 112 113 return val; 114 } 115 116 void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val) 117 { 118 vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_BUNIT, 119 SB_CRWRDA_NP, reg, &val); 120 } 121 122 u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr) 123 { 124 u32 val = 0; 125 126 WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); 127 128 mutex_lock(&dev_priv->sb_lock); 129 vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_NC, 130 SB_CRRDDA_NP, addr, &val); 131 mutex_unlock(&dev_priv->sb_lock); 132 133 return val; 134 } 135 136 u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg) 137 { 138 u32 val = 0; 139 vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), port, 140 SB_CRRDDA_NP, reg, &val); 141 return val; 142 } 143 144 void vlv_iosf_sb_write(struct drm_i915_private *dev_priv, 145 u8 port, u32 reg, u32 val) 146 { 147 vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), port, 148 SB_CRWRDA_NP, reg, &val); 149 } 150 151 u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg) 152 { 153 u32 val = 0; 154 vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCK, 155 SB_CRRDDA_NP, reg, &val); 156 return val; 157 } 158 159 void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val) 160 { 161 vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCK, 162 SB_CRWRDA_NP, reg, &val); 163 } 164 165 u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg) 166 { 167 u32 val = 0; 168 vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCU, 169 SB_CRRDDA_NP, reg, &val); 170 return val; 171 } 172 173 void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val) 174 { 175 vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCU, 176 SB_CRWRDA_NP, reg, &val); 177 } 178 179 u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum i915_pipe pipe, int reg) 180 { 181 u32 val = 0; 182 183 vlv_sideband_rw(dev_priv, DPIO_DEVFN, DPIO_PHY_IOSF_PORT(DPIO_PHY(pipe)), 184 SB_MRD_NP, reg, &val); 185 186 /* 187 * FIXME: There might be some registers where all 1's is a valid value, 188 * so ideally we should check the register offset instead... 189 */ 190 WARN(val == 0xffffffff, "DPIO read pipe %c reg 0x%x == 0x%x\n", 191 pipe_name(pipe), reg, val); 192 193 return val; 194 } 195 196 void vlv_dpio_write(struct drm_i915_private *dev_priv, enum i915_pipe pipe, int reg, u32 val) 197 { 198 vlv_sideband_rw(dev_priv, DPIO_DEVFN, DPIO_PHY_IOSF_PORT(DPIO_PHY(pipe)), 199 SB_MWR_NP, reg, &val); 200 } 201 202 /* SBI access */ 203 u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg, 204 enum intel_sbi_destination destination) 205 { 206 u32 value = 0; 207 WARN_ON(!mutex_is_locked(&dev_priv->sb_lock)); 208 209 if (intel_wait_for_register(dev_priv, 210 SBI_CTL_STAT, SBI_BUSY, 0, 211 100)) { 212 DRM_ERROR("timeout waiting for SBI to become ready\n"); 213 return 0; 214 } 215 216 I915_WRITE(SBI_ADDR, (reg << 16)); 217 218 if (destination == SBI_ICLK) 219 value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD; 220 else 221 value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD; 222 I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY); 223 224 if (intel_wait_for_register(dev_priv, 225 SBI_CTL_STAT, 226 SBI_BUSY | SBI_RESPONSE_FAIL, 227 0, 228 100)) { 229 DRM_ERROR("timeout waiting for SBI to complete read transaction\n"); 230 return 0; 231 } 232 233 return I915_READ(SBI_DATA); 234 } 235 236 void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value, 237 enum intel_sbi_destination destination) 238 { 239 u32 tmp; 240 241 WARN_ON(!mutex_is_locked(&dev_priv->sb_lock)); 242 243 if (intel_wait_for_register(dev_priv, 244 SBI_CTL_STAT, SBI_BUSY, 0, 245 100)) { 246 DRM_ERROR("timeout waiting for SBI to become ready\n"); 247 return; 248 } 249 250 I915_WRITE(SBI_ADDR, (reg << 16)); 251 I915_WRITE(SBI_DATA, value); 252 253 if (destination == SBI_ICLK) 254 tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR; 255 else 256 tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR; 257 I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp); 258 259 if (intel_wait_for_register(dev_priv, 260 SBI_CTL_STAT, 261 SBI_BUSY | SBI_RESPONSE_FAIL, 262 0, 263 100)) { 264 DRM_ERROR("timeout waiting for SBI to complete write transaction\n"); 265 return; 266 } 267 } 268 269 u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg) 270 { 271 u32 val = 0; 272 vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI, SB_CRRDDA_NP, 273 reg, &val); 274 return val; 275 } 276 277 void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val) 278 { 279 vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI, SB_CRWRDA_NP, 280 reg, &val); 281 } 282