Home | History | Annotate | Line # | Download | only in i915
intel_sideband.c revision 1.1.1.1.2.2
      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 static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
     33 			   u32 port, u32 opcode, u32 addr, u32 *val)
     34 {
     35 	u32 cmd, be = 0xf, bar = 0;
     36 	bool is_read = (opcode == PUNIT_OPCODE_REG_READ ||
     37 			opcode == DPIO_OPCODE_REG_READ);
     38 
     39 	cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
     40 		(port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
     41 		(bar << IOSF_BAR_SHIFT);
     42 
     43 	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
     44 
     45 	if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
     46 		DRM_DEBUG_DRIVER("IOSF sideband idle wait (%s) timed out\n",
     47 				 is_read ? "read" : "write");
     48 		return -EAGAIN;
     49 	}
     50 
     51 	I915_WRITE(VLV_IOSF_ADDR, addr);
     52 	if (!is_read)
     53 		I915_WRITE(VLV_IOSF_DATA, *val);
     54 	I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd);
     55 
     56 	if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
     57 		DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n",
     58 				 is_read ? "read" : "write");
     59 		return -ETIMEDOUT;
     60 	}
     61 
     62 	if (is_read)
     63 		*val = I915_READ(VLV_IOSF_DATA);
     64 	I915_WRITE(VLV_IOSF_DATA, 0);
     65 
     66 	return 0;
     67 }
     68 
     69 u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr)
     70 {
     71 	u32 val = 0;
     72 
     73 	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
     74 
     75 	mutex_lock(&dev_priv->dpio_lock);
     76 	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
     77 			PUNIT_OPCODE_REG_READ, addr, &val);
     78 	mutex_unlock(&dev_priv->dpio_lock);
     79 
     80 	return val;
     81 }
     82 
     83 void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val)
     84 {
     85 	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
     86 
     87 	mutex_lock(&dev_priv->dpio_lock);
     88 	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
     89 			PUNIT_OPCODE_REG_WRITE, addr, &val);
     90 	mutex_unlock(&dev_priv->dpio_lock);
     91 }
     92 
     93 u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg)
     94 {
     95 	u32 val = 0;
     96 
     97 	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_BUNIT,
     98 			PUNIT_OPCODE_REG_READ, reg, &val);
     99 
    100 	return val;
    101 }
    102 
    103 void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
    104 {
    105 	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_BUNIT,
    106 			PUNIT_OPCODE_REG_WRITE, reg, &val);
    107 }
    108 
    109 u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
    110 {
    111 	u32 val = 0;
    112 
    113 	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
    114 
    115 	mutex_lock(&dev_priv->dpio_lock);
    116 	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_NC,
    117 			PUNIT_OPCODE_REG_READ, addr, &val);
    118 	mutex_unlock(&dev_priv->dpio_lock);
    119 
    120 	return val;
    121 }
    122 
    123 u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg)
    124 {
    125 	u32 val = 0;
    126 	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPIO_NC,
    127 			PUNIT_OPCODE_REG_READ, reg, &val);
    128 	return val;
    129 }
    130 
    131 void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
    132 {
    133 	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPIO_NC,
    134 			PUNIT_OPCODE_REG_WRITE, reg, &val);
    135 }
    136 
    137 u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg)
    138 {
    139 	u32 val = 0;
    140 	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCK,
    141 			PUNIT_OPCODE_REG_READ, reg, &val);
    142 	return val;
    143 }
    144 
    145 void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
    146 {
    147 	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCK,
    148 			PUNIT_OPCODE_REG_WRITE, reg, &val);
    149 }
    150 
    151 u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg)
    152 {
    153 	u32 val = 0;
    154 	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCU,
    155 			PUNIT_OPCODE_REG_READ, reg, &val);
    156 	return val;
    157 }
    158 
    159 void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
    160 {
    161 	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCU,
    162 			PUNIT_OPCODE_REG_WRITE, reg, &val);
    163 }
    164 
    165 u32 vlv_gps_core_read(struct drm_i915_private *dev_priv, u32 reg)
    166 {
    167 	u32 val = 0;
    168 	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPS_CORE,
    169 			PUNIT_OPCODE_REG_READ, reg, &val);
    170 	return val;
    171 }
    172 
    173 void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
    174 {
    175 	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPS_CORE,
    176 			PUNIT_OPCODE_REG_WRITE, reg, &val);
    177 }
    178 
    179 u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum 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 			DPIO_OPCODE_REG_READ, reg, &val);
    185 	return val;
    186 }
    187 
    188 void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val)
    189 {
    190 	vlv_sideband_rw(dev_priv, DPIO_DEVFN, DPIO_PHY_IOSF_PORT(DPIO_PHY(pipe)),
    191 			DPIO_OPCODE_REG_WRITE, reg, &val);
    192 }
    193 
    194 /* SBI access */
    195 u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
    196 		   enum intel_sbi_destination destination)
    197 {
    198 	u32 value = 0;
    199 	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
    200 
    201 	if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
    202 				100)) {
    203 		DRM_ERROR("timeout waiting for SBI to become ready\n");
    204 		return 0;
    205 	}
    206 
    207 	I915_WRITE(SBI_ADDR, (reg << 16));
    208 
    209 	if (destination == SBI_ICLK)
    210 		value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
    211 	else
    212 		value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
    213 	I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY);
    214 
    215 	if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
    216 				100)) {
    217 		DRM_ERROR("timeout waiting for SBI to complete read transaction\n");
    218 		return 0;
    219 	}
    220 
    221 	return I915_READ(SBI_DATA);
    222 }
    223 
    224 void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
    225 		     enum intel_sbi_destination destination)
    226 {
    227 	u32 tmp;
    228 
    229 	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
    230 
    231 	if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
    232 				100)) {
    233 		DRM_ERROR("timeout waiting for SBI to become ready\n");
    234 		return;
    235 	}
    236 
    237 	I915_WRITE(SBI_ADDR, (reg << 16));
    238 	I915_WRITE(SBI_DATA, value);
    239 
    240 	if (destination == SBI_ICLK)
    241 		tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR;
    242 	else
    243 		tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR;
    244 	I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp);
    245 
    246 	if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
    247 				100)) {
    248 		DRM_ERROR("timeout waiting for SBI to complete write transaction\n");
    249 		return;
    250 	}
    251 }
    252 
    253 u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg)
    254 {
    255 	u32 val = 0;
    256 	vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI,
    257 					DPIO_OPCODE_REG_READ, reg, &val);
    258 	return val;
    259 }
    260 
    261 void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
    262 {
    263 	vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI,
    264 					DPIO_OPCODE_REG_WRITE, reg, &val);
    265 }
    266