Subversion Repositories Kolibri OS

Rev

Rev 4104 | 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. /*
  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.