Subversion Repositories Kolibri OS

Rev

Rev 6084 | 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.  
  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 (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
  55.                 DRM_DEBUG_DRIVER("IOSF sideband idle wait (%s) timed out\n",
  56.                                  is_read ? "read" : "write");
  57.                 return -EAGAIN;
  58.         }
  59.  
  60.         I915_WRITE(VLV_IOSF_ADDR, addr);
  61.         if (!is_read)
  62.                 I915_WRITE(VLV_IOSF_DATA, *val);
  63.         I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd);
  64.  
  65.         if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
  66.                 DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n",
  67.                                  is_read ? "read" : "write");
  68.                 return -ETIMEDOUT;
  69.         }
  70.  
  71.         if (is_read)
  72.                 *val = I915_READ(VLV_IOSF_DATA);
  73.         I915_WRITE(VLV_IOSF_DATA, 0);
  74.  
  75.         return 0;
  76. }
  77.  
  78. u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
  79. {
  80.         u32 val = 0;
  81.  
  82.         WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
  83.  
  84.         mutex_lock(&dev_priv->sb_lock);
  85.         vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
  86.                         SB_CRRDDA_NP, addr, &val);
  87.         mutex_unlock(&dev_priv->sb_lock);
  88.  
  89.         return val;
  90. }
  91.  
  92. void vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val)
  93. {
  94.         WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
  95.  
  96.         mutex_lock(&dev_priv->sb_lock);
  97.         vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
  98.                         SB_CRWRDA_NP, addr, &val);
  99.         mutex_unlock(&dev_priv->sb_lock);
  100. }
  101.  
  102. u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg)
  103. {
  104.         u32 val = 0;
  105.  
  106.         vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_BUNIT,
  107.                         SB_CRRDDA_NP, reg, &val);
  108.  
  109.         return val;
  110. }
  111.  
  112. void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
  113. {
  114.         vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_BUNIT,
  115.                         SB_CRWRDA_NP, reg, &val);
  116. }
  117.  
  118. u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
  119. {
  120.         u32 val = 0;
  121.  
  122.         WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
  123.  
  124.         mutex_lock(&dev_priv->sb_lock);
  125.         vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_NC,
  126.                         SB_CRRDDA_NP, addr, &val);
  127.         mutex_unlock(&dev_priv->sb_lock);
  128.  
  129.         return val;
  130. }
  131.  
  132. u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg)
  133. {
  134.         u32 val = 0;
  135.         vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), port,
  136.                         SB_CRRDDA_NP, reg, &val);
  137.         return val;
  138. }
  139.  
  140. void vlv_iosf_sb_write(struct drm_i915_private *dev_priv,
  141.                        u8 port, u32 reg, u32 val)
  142. {
  143.         vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), port,
  144.                         SB_CRWRDA_NP, reg, &val);
  145. }
  146.  
  147. u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg)
  148. {
  149.         u32 val = 0;
  150.         vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCK,
  151.                         SB_CRRDDA_NP, reg, &val);
  152.         return val;
  153. }
  154.  
  155. void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
  156. {
  157.         vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCK,
  158.                         SB_CRWRDA_NP, reg, &val);
  159. }
  160.  
  161. u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg)
  162. {
  163.         u32 val = 0;
  164.         vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCU,
  165.                         SB_CRRDDA_NP, reg, &val);
  166.         return val;
  167. }
  168.  
  169. void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
  170. {
  171.         vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCU,
  172.                         SB_CRWRDA_NP, reg, &val);
  173. }
  174.  
  175. u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg)
  176. {
  177.         u32 val = 0;
  178.  
  179.         vlv_sideband_rw(dev_priv, DPIO_DEVFN, DPIO_PHY_IOSF_PORT(DPIO_PHY(pipe)),
  180.                         SB_MRD_NP, reg, &val);
  181.  
  182.         /*
  183.          * FIXME: There might be some registers where all 1's is a valid value,
  184.          * so ideally we should check the register offset instead...
  185.          */
  186.         WARN(val == 0xffffffff, "DPIO read pipe %c reg 0x%x == 0x%x\n",
  187.              pipe_name(pipe), reg, val);
  188.  
  189.         return val;
  190. }
  191.  
  192. void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val)
  193. {
  194.         vlv_sideband_rw(dev_priv, DPIO_DEVFN, DPIO_PHY_IOSF_PORT(DPIO_PHY(pipe)),
  195.                         SB_MWR_NP, reg, &val);
  196. }
  197.  
  198. /* SBI access */
  199. u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
  200.                    enum intel_sbi_destination destination)
  201. {
  202.         u32 value = 0;
  203.         WARN_ON(!mutex_is_locked(&dev_priv->sb_lock));
  204.  
  205.         if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
  206.                                 100)) {
  207.                 DRM_ERROR("timeout waiting for SBI to become ready\n");
  208.                 return 0;
  209.         }
  210.  
  211.         I915_WRITE(SBI_ADDR, (reg << 16));
  212.  
  213.         if (destination == SBI_ICLK)
  214.                 value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
  215.         else
  216.                 value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
  217.         I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY);
  218.  
  219.         if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
  220.                                 100)) {
  221.                 DRM_ERROR("timeout waiting for SBI to complete read transaction\n");
  222.                 return 0;
  223.         }
  224.  
  225.         return I915_READ(SBI_DATA);
  226. }
  227.  
  228. void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
  229.                      enum intel_sbi_destination destination)
  230. {
  231.         u32 tmp;
  232.  
  233.         WARN_ON(!mutex_is_locked(&dev_priv->sb_lock));
  234.  
  235.         if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
  236.                                 100)) {
  237.                 DRM_ERROR("timeout waiting for SBI to become ready\n");
  238.                 return;
  239.         }
  240.  
  241.         I915_WRITE(SBI_ADDR, (reg << 16));
  242.         I915_WRITE(SBI_DATA, value);
  243.  
  244.         if (destination == SBI_ICLK)
  245.                 tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR;
  246.         else
  247.                 tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR;
  248.         I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp);
  249.  
  250.         if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
  251.                                 100)) {
  252.                 DRM_ERROR("timeout waiting for SBI to complete write transaction\n");
  253.                 return;
  254.         }
  255. }
  256.  
  257. u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg)
  258. {
  259.         u32 val = 0;
  260.         vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI, SB_CRRDDA_NP,
  261.                         reg, &val);
  262.         return val;
  263. }
  264.  
  265. void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
  266. {
  267.         vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI, SB_CRWRDA_NP,
  268.                         reg, &val);
  269. }
  270.