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
  21.  * DEALINGS IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *      Shobhit Kumar <shobhit.kumar@intel.com>
  25.  *      Yogesh Mohan Marimuthu <yogesh.mohan.marimuthu@intel.com>
  26.  */
  27.  
  28. #include <linux/kernel.h>
  29. #include "intel_drv.h"
  30. #include "i915_drv.h"
  31. #include "intel_dsi.h"
  32.  
  33. #define DSI_HSS_PACKET_SIZE             4
  34. #define DSI_HSE_PACKET_SIZE             4
  35. #define DSI_HSA_PACKET_EXTRA_SIZE       6
  36. #define DSI_HBP_PACKET_EXTRA_SIZE       6
  37. #define DSI_HACTIVE_PACKET_EXTRA_SIZE   6
  38. #define DSI_HFP_PACKET_EXTRA_SIZE       6
  39. #define DSI_EOTP_PACKET_SIZE            4
  40.  
  41. struct dsi_mnp {
  42.         u32 dsi_pll_ctrl;
  43.         u32 dsi_pll_div;
  44. };
  45.  
  46. static const u32 lfsr_converts[] = {
  47.         426, 469, 234, 373, 442, 221, 110, 311, 411,            /* 62 - 70 */
  48.         461, 486, 243, 377, 188, 350, 175, 343, 427, 213,       /* 71 - 80 */
  49.         106, 53, 282, 397, 354, 227, 113, 56, 284, 142,         /* 81 - 90 */
  50.         71, 35                                                  /* 91 - 92 */
  51. };
  52.  
  53. #ifdef DSI_CLK_FROM_RR
  54.  
  55. static u32 dsi_rr_formula(const struct drm_display_mode *mode,
  56.                           int pixel_format, int video_mode_format,
  57.                           int lane_count, bool eotp)
  58. {
  59.         u32 bpp;
  60.         u32 hactive, vactive, hfp, hsync, hbp, vfp, vsync, vbp;
  61.         u32 hsync_bytes, hbp_bytes, hactive_bytes, hfp_bytes;
  62.         u32 bytes_per_line, bytes_per_frame;
  63.         u32 num_frames;
  64.         u32 bytes_per_x_frames, bytes_per_x_frames_x_lanes;
  65.         u32 dsi_bit_clock_hz;
  66.         u32 dsi_clk;
  67.  
  68.         switch (pixel_format) {
  69.         default:
  70.         case VID_MODE_FORMAT_RGB888:
  71.         case VID_MODE_FORMAT_RGB666_LOOSE:
  72.                 bpp = 24;
  73.                 break;
  74.         case VID_MODE_FORMAT_RGB666:
  75.                 bpp = 18;
  76.                 break;
  77.         case VID_MODE_FORMAT_RGB565:
  78.                 bpp = 16;
  79.                 break;
  80.         }
  81.  
  82.         hactive = mode->hdisplay;
  83.         vactive = mode->vdisplay;
  84.         hfp = mode->hsync_start - mode->hdisplay;
  85.         hsync = mode->hsync_end - mode->hsync_start;
  86.         hbp = mode->htotal - mode->hsync_end;
  87.  
  88.         vfp = mode->vsync_start - mode->vdisplay;
  89.         vsync = mode->vsync_end - mode->vsync_start;
  90.         vbp = mode->vtotal - mode->vsync_end;
  91.  
  92.         hsync_bytes = DIV_ROUND_UP(hsync * bpp, 8);
  93.         hbp_bytes = DIV_ROUND_UP(hbp * bpp, 8);
  94.         hactive_bytes = DIV_ROUND_UP(hactive * bpp, 8);
  95.         hfp_bytes = DIV_ROUND_UP(hfp * bpp, 8);
  96.  
  97.         bytes_per_line = DSI_HSS_PACKET_SIZE + hsync_bytes +
  98.                 DSI_HSA_PACKET_EXTRA_SIZE + DSI_HSE_PACKET_SIZE +
  99.                 hbp_bytes + DSI_HBP_PACKET_EXTRA_SIZE +
  100.                 hactive_bytes + DSI_HACTIVE_PACKET_EXTRA_SIZE +
  101.                 hfp_bytes + DSI_HFP_PACKET_EXTRA_SIZE;
  102.  
  103.         /*
  104.          * XXX: Need to accurately calculate LP to HS transition timeout and add
  105.          * it to bytes_per_line/bytes_per_frame.
  106.          */
  107.  
  108.         if (eotp && video_mode_format == VIDEO_MODE_BURST)
  109.                 bytes_per_line += DSI_EOTP_PACKET_SIZE;
  110.  
  111.         bytes_per_frame = vsync * bytes_per_line + vbp * bytes_per_line +
  112.                 vactive * bytes_per_line + vfp * bytes_per_line;
  113.  
  114.         if (eotp &&
  115.             (video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE ||
  116.              video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS))
  117.                 bytes_per_frame += DSI_EOTP_PACKET_SIZE;
  118.  
  119.         num_frames = drm_mode_vrefresh(mode);
  120.         bytes_per_x_frames = num_frames * bytes_per_frame;
  121.  
  122.         bytes_per_x_frames_x_lanes = bytes_per_x_frames / lane_count;
  123.  
  124.         /* the dsi clock is divided by 2 in the hardware to get dsi ddr clock */
  125.         dsi_bit_clock_hz = bytes_per_x_frames_x_lanes * 8;
  126.         dsi_clk = dsi_bit_clock_hz / 1000;
  127.  
  128.         if (eotp && video_mode_format == VIDEO_MODE_BURST)
  129.                 dsi_clk *= 2;
  130.  
  131.         return dsi_clk;
  132. }
  133.  
  134. #else
  135.  
  136. /* Get DSI clock from pixel clock */
  137. static u32 dsi_clk_from_pclk(const struct drm_display_mode *mode,
  138.                           int pixel_format, int lane_count)
  139. {
  140.         u32 dsi_clk_khz;
  141.         u32 bpp;
  142.  
  143.         switch (pixel_format) {
  144.         default:
  145.         case VID_MODE_FORMAT_RGB888:
  146.         case VID_MODE_FORMAT_RGB666_LOOSE:
  147.                 bpp = 24;
  148.                 break;
  149.         case VID_MODE_FORMAT_RGB666:
  150.                 bpp = 18;
  151.                 break;
  152.         case VID_MODE_FORMAT_RGB565:
  153.                 bpp = 16;
  154.                 break;
  155.         }
  156.  
  157.         /* DSI data rate = pixel clock * bits per pixel / lane count
  158.            pixel clock is converted from KHz to Hz */
  159.         dsi_clk_khz = DIV_ROUND_CLOSEST(mode->clock * bpp, lane_count);
  160.  
  161.         return dsi_clk_khz;
  162. }
  163.  
  164. #endif
  165.  
  166. static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp)
  167. {
  168.         u32 m, n, p;
  169.         u32 ref_clk;
  170.         u32 error;
  171.         u32 tmp_error;
  172.         int target_dsi_clk;
  173.         int calc_dsi_clk;
  174.         u32 calc_m;
  175.         u32 calc_p;
  176.         u32 m_seed;
  177.  
  178.         /* dsi_clk is expected in KHZ */
  179.         if (dsi_clk < 300000 || dsi_clk > 1150000) {
  180.                 DRM_ERROR("DSI CLK Out of Range\n");
  181.                 return -ECHRNG;
  182.         }
  183.  
  184.         ref_clk = 25000;
  185.         target_dsi_clk = dsi_clk;
  186.         error = 0xFFFFFFFF;
  187.         tmp_error = 0xFFFFFFFF;
  188.         calc_m = 0;
  189.         calc_p = 0;
  190.  
  191.         for (m = 62; m <= 92; m++) {
  192.                 for (p = 2; p <= 6; p++) {
  193.                         /* Find the optimal m and p divisors
  194.                         with minimal error +/- the required clock */
  195.                         calc_dsi_clk = (m * ref_clk) / p;
  196.                         if (calc_dsi_clk == target_dsi_clk) {
  197.                                 calc_m = m;
  198.                                 calc_p = p;
  199.                                 error = 0;
  200.                                 break;
  201.                         } else
  202.                                 tmp_error = abs(target_dsi_clk - calc_dsi_clk);
  203.  
  204.                         if (tmp_error < error) {
  205.                                 error = tmp_error;
  206.                                 calc_m = m;
  207.                                 calc_p = p;
  208.                         }
  209.                 }
  210.  
  211.                 if (error == 0)
  212.                         break;
  213.         }
  214.  
  215.         m_seed = lfsr_converts[calc_m - 62];
  216.         n = 1;
  217.         dsi_mnp->dsi_pll_ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2);
  218.         dsi_mnp->dsi_pll_div = (n - 1) << DSI_PLL_N1_DIV_SHIFT |
  219.                 m_seed << DSI_PLL_M1_DIV_SHIFT;
  220.  
  221.         return 0;
  222. }
  223.  
  224. /*
  225.  * XXX: The muxing and gating is hard coded for now. Need to add support for
  226.  * sharing PLLs with two DSI outputs.
  227.  */
  228. static void vlv_configure_dsi_pll(struct intel_encoder *encoder)
  229. {
  230.         struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
  231.         struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
  232.         const struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode;
  233.         struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
  234.         int ret;
  235.         struct dsi_mnp dsi_mnp;
  236.         u32 dsi_clk;
  237.  
  238.         dsi_clk = dsi_clk_from_pclk(mode, intel_dsi->pixel_format,
  239.                                                 intel_dsi->lane_count);
  240.  
  241.         ret = dsi_calc_mnp(dsi_clk, &dsi_mnp);
  242.         if (ret) {
  243.                 DRM_DEBUG_KMS("dsi_calc_mnp failed\n");
  244.                 return;
  245.         }
  246.  
  247.         dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL;
  248.  
  249.         DRM_DEBUG_KMS("dsi pll div %08x, ctrl %08x\n",
  250.                       dsi_mnp.dsi_pll_div, dsi_mnp.dsi_pll_ctrl);
  251.  
  252.         vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, 0);
  253.         vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, dsi_mnp.dsi_pll_div);
  254.         vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_mnp.dsi_pll_ctrl);
  255. }
  256.  
  257. void vlv_enable_dsi_pll(struct intel_encoder *encoder)
  258. {
  259.         struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
  260.         u32 tmp;
  261.  
  262.         DRM_DEBUG_KMS("\n");
  263.  
  264.         mutex_lock(&dev_priv->dpio_lock);
  265.  
  266.         vlv_configure_dsi_pll(encoder);
  267.  
  268.         /* wait at least 0.5 us after ungating before enabling VCO */
  269.         usleep_range(1, 10);
  270.  
  271.         tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
  272.         tmp |= DSI_PLL_VCO_EN;
  273.         vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp);
  274.  
  275.         mutex_unlock(&dev_priv->dpio_lock);
  276.  
  277.         if (wait_for(I915_READ(PIPECONF(PIPE_A)) & PIPECONF_DSI_PLL_LOCKED, 20)) {
  278.                 DRM_ERROR("DSI PLL lock failed\n");
  279.                 return;
  280.         }
  281.  
  282.         DRM_DEBUG_KMS("DSI PLL locked\n");
  283. }
  284.  
  285. void vlv_disable_dsi_pll(struct intel_encoder *encoder)
  286. {
  287.         struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
  288.         u32 tmp;
  289.  
  290.         DRM_DEBUG_KMS("\n");
  291.  
  292.         mutex_lock(&dev_priv->dpio_lock);
  293.  
  294.         tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
  295.         tmp &= ~DSI_PLL_VCO_EN;
  296.         tmp |= DSI_PLL_LDO_GATE;
  297.         vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp);
  298.  
  299.         mutex_unlock(&dev_priv->dpio_lock);
  300. }
  301.