Subversion Repositories Kolibri OS

Rev

Rev 5060 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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. /* IOSF sideband */
  29. static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
  30.                            u32 port, u32 opcode, u32 addr, u32 *val)
  31. {
  32.         u32 cmd, be = 0xf, bar = 0;
  33.         bool is_read = (opcode == PUNIT_OPCODE_REG_READ ||
  34.                         opcode == DPIO_OPCODE_REG_READ);
  35.  
  36.         cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
  37.                 (port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
  38.                 (bar << IOSF_BAR_SHIFT);
  39.  
  40.         WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
  41.  
  42.         if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
  43.                 DRM_DEBUG_DRIVER("IOSF sideband idle wait (%s) timed out\n",
  44.                                  is_read ? "read" : "write");
  45.                 return -EAGAIN;
  46.         }
  47.  
  48.         I915_WRITE(VLV_IOSF_ADDR, addr);
  49.         if (!is_read)
  50.                 I915_WRITE(VLV_IOSF_DATA, *val);
  51.         I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd);
  52.  
  53.         if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
  54.                 DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n",
  55.                                  is_read ? "read" : "write");
  56.                 return -ETIMEDOUT;
  57.         }
  58.  
  59.         if (is_read)
  60.                 *val = I915_READ(VLV_IOSF_DATA);
  61.         I915_WRITE(VLV_IOSF_DATA, 0);
  62.  
  63.         return 0;
  64. }
  65.  
  66. u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr)
  67. {
  68.         u32 val = 0;
  69.  
  70.         WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
  71.  
  72.         mutex_lock(&dev_priv->dpio_lock);
  73.         vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
  74.                         PUNIT_OPCODE_REG_READ, addr, &val);
  75.         mutex_unlock(&dev_priv->dpio_lock);
  76.  
  77.         return val;
  78. }
  79.  
  80. void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val)
  81. {
  82.         WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
  83.  
  84.         mutex_lock(&dev_priv->dpio_lock);
  85.         vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
  86.                         PUNIT_OPCODE_REG_WRITE, addr, &val);
  87.         mutex_unlock(&dev_priv->dpio_lock);
  88. }
  89.  
  90. u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
  91. {
  92.         u32 val = 0;
  93.  
  94.         WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
  95.  
  96.         mutex_lock(&dev_priv->dpio_lock);
  97.         vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_NC,
  98.                         PUNIT_OPCODE_REG_READ, addr, &val);
  99.         mutex_unlock(&dev_priv->dpio_lock);
  100.  
  101.         return val;
  102. }
  103.  
  104. u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg)
  105. {
  106.         u32 val = 0;
  107.  
  108.         vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_DPIO,
  109.                         DPIO_OPCODE_REG_READ, reg, &val);
  110.  
  111.         return val;
  112. }
  113.  
  114. void vlv_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val)
  115. {
  116.         vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_DPIO,
  117.                         DPIO_OPCODE_REG_WRITE, reg, &val);
  118. }
  119.  
  120. /* SBI access */
  121. u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
  122.                    enum intel_sbi_destination destination)
  123. {
  124.         u32 value = 0;
  125.         WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
  126.  
  127.         if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
  128.                                 100)) {
  129.                 DRM_ERROR("timeout waiting for SBI to become ready\n");
  130.                 return 0;
  131.         }
  132.  
  133.         I915_WRITE(SBI_ADDR, (reg << 16));
  134.  
  135.         if (destination == SBI_ICLK)
  136.                 value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
  137.         else
  138.                 value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
  139.         I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY);
  140.  
  141.         if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
  142.                                 100)) {
  143.                 DRM_ERROR("timeout waiting for SBI to complete read transaction\n");
  144.                 return 0;
  145.         }
  146.  
  147.         return I915_READ(SBI_DATA);
  148. }
  149.  
  150. void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
  151.                      enum intel_sbi_destination destination)
  152. {
  153.         u32 tmp;
  154.  
  155.         WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
  156.  
  157.         if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
  158.                                 100)) {
  159.                 DRM_ERROR("timeout waiting for SBI to become ready\n");
  160.                 return;
  161.         }
  162.  
  163.         I915_WRITE(SBI_ADDR, (reg << 16));
  164.         I915_WRITE(SBI_DATA, value);
  165.  
  166.         if (destination == SBI_ICLK)
  167.                 tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR;
  168.         else
  169.                 tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR;
  170.         I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp);
  171.  
  172.         if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
  173.                                 100)) {
  174.                 DRM_ERROR("timeout waiting for SBI to complete write transaction\n");
  175.                 return;
  176.         }
  177. }
  178.