LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915/display - icl_dsi.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 942 0.0 %
Date: 2022-03-28 16:04:14 Functions: 0 45 0.0 %
Branches: 0 510 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright © 2018 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                 :            :  *   Madhav Chauhan <madhav.chauhan@intel.com>
      25                 :            :  *   Jani Nikula <jani.nikula@intel.com>
      26                 :            :  */
      27                 :            : 
      28                 :            : #include <drm/drm_atomic_helper.h>
      29                 :            : #include <drm/drm_mipi_dsi.h>
      30                 :            : 
      31                 :            : #include "intel_atomic.h"
      32                 :            : #include "intel_combo_phy.h"
      33                 :            : #include "intel_connector.h"
      34                 :            : #include "intel_ddi.h"
      35                 :            : #include "intel_dsi.h"
      36                 :            : #include "intel_panel.h"
      37                 :            : #include "intel_vdsc.h"
      38                 :            : 
      39                 :          0 : static inline int header_credits_available(struct drm_i915_private *dev_priv,
      40                 :            :                                            enum transcoder dsi_trans)
      41                 :            : {
      42                 :          0 :         return (I915_READ(DSI_CMD_TXCTL(dsi_trans)) & FREE_HEADER_CREDIT_MASK)
      43                 :          0 :                 >> FREE_HEADER_CREDIT_SHIFT;
      44                 :            : }
      45                 :            : 
      46                 :          0 : static inline int payload_credits_available(struct drm_i915_private *dev_priv,
      47                 :            :                                             enum transcoder dsi_trans)
      48                 :            : {
      49                 :          0 :         return (I915_READ(DSI_CMD_TXCTL(dsi_trans)) & FREE_PLOAD_CREDIT_MASK)
      50                 :          0 :                 >> FREE_PLOAD_CREDIT_SHIFT;
      51                 :            : }
      52                 :            : 
      53                 :          0 : static void wait_for_header_credits(struct drm_i915_private *dev_priv,
      54                 :            :                                     enum transcoder dsi_trans)
      55                 :            : {
      56   [ #  #  #  #  :          0 :         if (wait_for_us(header_credits_available(dev_priv, dsi_trans) >=
                   #  # ]
      57                 :            :                         MAX_HEADER_CREDIT, 100))
      58                 :          0 :                 DRM_ERROR("DSI header credits not released\n");
      59                 :          0 : }
      60                 :            : 
      61                 :          0 : static void wait_for_payload_credits(struct drm_i915_private *dev_priv,
      62                 :            :                                      enum transcoder dsi_trans)
      63                 :            : {
      64   [ #  #  #  #  :          0 :         if (wait_for_us(payload_credits_available(dev_priv, dsi_trans) >=
                   #  # ]
      65                 :            :                         MAX_PLOAD_CREDIT, 100))
      66                 :          0 :                 DRM_ERROR("DSI payload credits not released\n");
      67                 :          0 : }
      68                 :            : 
      69                 :          0 : static enum transcoder dsi_port_to_transcoder(enum port port)
      70                 :            : {
      71                 :          0 :         if (port == PORT_A)
      72                 :            :                 return TRANSCODER_DSI_0;
      73                 :            :         else
      74                 :          0 :                 return TRANSCODER_DSI_1;
      75                 :            : }
      76                 :            : 
      77                 :          0 : static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder)
      78                 :            : {
      79                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
      80                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
      81                 :          0 :         struct mipi_dsi_device *dsi;
      82                 :          0 :         enum port port;
      83                 :          0 :         enum transcoder dsi_trans;
      84                 :          0 :         int ret;
      85                 :            : 
      86                 :            :         /* wait for header/payload credits to be released */
      87   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
      88         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
      89                 :          0 :                 wait_for_header_credits(dev_priv, dsi_trans);
      90                 :          0 :                 wait_for_payload_credits(dev_priv, dsi_trans);
      91                 :            :         }
      92                 :            : 
      93                 :            :         /* send nop DCS command */
      94   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
      95                 :          0 :                 dsi = intel_dsi->dsi_hosts[port]->device;
      96                 :          0 :                 dsi->mode_flags |= MIPI_DSI_MODE_LPM;
      97                 :          0 :                 dsi->channel = 0;
      98                 :          0 :                 ret = mipi_dsi_dcs_nop(dsi);
      99         [ #  # ]:          0 :                 if (ret < 0)
     100                 :          0 :                         DRM_ERROR("error sending DCS NOP command\n");
     101                 :            :         }
     102                 :            : 
     103                 :            :         /* wait for header credits to be released */
     104   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     105         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
     106                 :          0 :                 wait_for_header_credits(dev_priv, dsi_trans);
     107                 :            :         }
     108                 :            : 
     109                 :            :         /* wait for LP TX in progress bit to be cleared */
     110   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     111         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
     112   [ #  #  #  #  :          0 :                 if (wait_for_us(!(I915_READ(DSI_LP_MSG(dsi_trans)) &
                   #  # ]
     113                 :            :                                   LPTX_IN_PROGRESS), 20))
     114                 :          0 :                         DRM_ERROR("LPTX bit not cleared\n");
     115                 :            :         }
     116                 :          0 : }
     117                 :            : 
     118                 :            : static bool add_payld_to_queue(struct intel_dsi_host *host, const u8 *data,
     119                 :            :                                u32 len)
     120                 :            : {
     121                 :            :         struct intel_dsi *intel_dsi = host->intel_dsi;
     122                 :            :         struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
     123                 :            :         enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
     124                 :            :         int free_credits;
     125                 :            :         int i, j;
     126                 :            : 
     127                 :            :         for (i = 0; i < len; i += 4) {
     128                 :            :                 u32 tmp = 0;
     129                 :            : 
     130                 :            :                 free_credits = payload_credits_available(dev_priv, dsi_trans);
     131                 :            :                 if (free_credits < 1) {
     132                 :            :                         DRM_ERROR("Payload credit not available\n");
     133                 :            :                         return false;
     134                 :            :                 }
     135                 :            : 
     136                 :            :                 for (j = 0; j < min_t(u32, len - i, 4); j++)
     137                 :            :                         tmp |= *data++ << 8 * j;
     138                 :            : 
     139                 :            :                 I915_WRITE(DSI_CMD_TXPYLD(dsi_trans), tmp);
     140                 :            :         }
     141                 :            : 
     142                 :            :         return true;
     143                 :            : }
     144                 :            : 
     145                 :          0 : static int dsi_send_pkt_hdr(struct intel_dsi_host *host,
     146                 :            :                             struct mipi_dsi_packet pkt, bool enable_lpdt)
     147                 :            : {
     148                 :          0 :         struct intel_dsi *intel_dsi = host->intel_dsi;
     149         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
     150         [ #  # ]:          0 :         enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
     151                 :          0 :         u32 tmp;
     152                 :          0 :         int free_credits;
     153                 :            : 
     154                 :            :         /* check if header credit available */
     155                 :          0 :         free_credits = header_credits_available(dev_priv, dsi_trans);
     156         [ #  # ]:          0 :         if (free_credits < 1) {
     157                 :          0 :                 DRM_ERROR("send pkt header failed, not enough hdr credits\n");
     158                 :          0 :                 return -1;
     159                 :            :         }
     160                 :            : 
     161                 :          0 :         tmp = I915_READ(DSI_CMD_TXHDR(dsi_trans));
     162                 :            : 
     163         [ #  # ]:          0 :         if (pkt.payload)
     164                 :          0 :                 tmp |= PAYLOAD_PRESENT;
     165                 :            :         else
     166                 :          0 :                 tmp &= ~PAYLOAD_PRESENT;
     167                 :            : 
     168                 :          0 :         tmp &= ~VBLANK_FENCE;
     169                 :            : 
     170         [ #  # ]:          0 :         if (enable_lpdt)
     171                 :          0 :                 tmp |= LP_DATA_TRANSFER;
     172                 :            : 
     173                 :          0 :         tmp &= ~(PARAM_WC_MASK | VC_MASK | DT_MASK);
     174                 :          0 :         tmp |= ((pkt.header[0] & VC_MASK) << VC_SHIFT);
     175                 :          0 :         tmp |= ((pkt.header[0] & DT_MASK) << DT_SHIFT);
     176                 :          0 :         tmp |= (pkt.header[1] << PARAM_WC_LOWER_SHIFT);
     177                 :          0 :         tmp |= (pkt.header[2] << PARAM_WC_UPPER_SHIFT);
     178                 :          0 :         I915_WRITE(DSI_CMD_TXHDR(dsi_trans), tmp);
     179                 :            : 
     180                 :          0 :         return 0;
     181                 :            : }
     182                 :            : 
     183                 :            : static int dsi_send_pkt_payld(struct intel_dsi_host *host,
     184                 :            :                               struct mipi_dsi_packet pkt)
     185                 :            : {
     186                 :            :         /* payload queue can accept *256 bytes*, check limit */
     187                 :            :         if (pkt.payload_length > MAX_PLOAD_CREDIT * 4) {
     188                 :            :                 DRM_ERROR("payload size exceeds max queue limit\n");
     189                 :            :                 return -1;
     190                 :            :         }
     191                 :            : 
     192                 :            :         /* load data into command payload queue */
     193                 :            :         if (!add_payld_to_queue(host, pkt.payload,
     194                 :            :                                 pkt.payload_length)) {
     195                 :            :                 DRM_ERROR("adding payload to queue failed\n");
     196                 :            :                 return -1;
     197                 :            :         }
     198                 :            : 
     199                 :            :         return 0;
     200                 :            : }
     201                 :            : 
     202                 :          0 : static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder)
     203                 :            : {
     204                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     205                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     206                 :          0 :         enum phy phy;
     207                 :          0 :         u32 tmp;
     208                 :          0 :         int lane;
     209                 :            : 
     210   [ #  #  #  # ]:          0 :         for_each_dsi_phy(phy, intel_dsi->phys) {
     211                 :            :                 /*
     212                 :            :                  * Program voltage swing and pre-emphasis level values as per
     213                 :            :                  * table in BSPEC under DDI buffer programing
     214                 :            :                  */
     215                 :          0 :                 tmp = I915_READ(ICL_PORT_TX_DW5_LN0(phy));
     216                 :          0 :                 tmp &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK);
     217                 :          0 :                 tmp |= SCALING_MODE_SEL(0x2);
     218                 :          0 :                 tmp |= TAP2_DISABLE | TAP3_DISABLE;
     219                 :          0 :                 tmp |= RTERM_SELECT(0x6);
     220                 :          0 :                 I915_WRITE(ICL_PORT_TX_DW5_GRP(phy), tmp);
     221                 :            : 
     222                 :          0 :                 tmp = I915_READ(ICL_PORT_TX_DW5_AUX(phy));
     223                 :          0 :                 tmp &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK);
     224                 :          0 :                 tmp |= SCALING_MODE_SEL(0x2);
     225                 :          0 :                 tmp |= TAP2_DISABLE | TAP3_DISABLE;
     226                 :          0 :                 tmp |= RTERM_SELECT(0x6);
     227                 :          0 :                 I915_WRITE(ICL_PORT_TX_DW5_AUX(phy), tmp);
     228                 :            : 
     229                 :          0 :                 tmp = I915_READ(ICL_PORT_TX_DW2_LN0(phy));
     230                 :          0 :                 tmp &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
     231                 :            :                          RCOMP_SCALAR_MASK);
     232                 :          0 :                 tmp |= SWING_SEL_UPPER(0x2);
     233                 :          0 :                 tmp |= SWING_SEL_LOWER(0x2);
     234                 :          0 :                 tmp |= RCOMP_SCALAR(0x98);
     235                 :          0 :                 I915_WRITE(ICL_PORT_TX_DW2_GRP(phy), tmp);
     236                 :            : 
     237                 :          0 :                 tmp = I915_READ(ICL_PORT_TX_DW2_AUX(phy));
     238                 :          0 :                 tmp &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
     239                 :            :                          RCOMP_SCALAR_MASK);
     240                 :          0 :                 tmp |= SWING_SEL_UPPER(0x2);
     241                 :          0 :                 tmp |= SWING_SEL_LOWER(0x2);
     242                 :          0 :                 tmp |= RCOMP_SCALAR(0x98);
     243                 :          0 :                 I915_WRITE(ICL_PORT_TX_DW2_AUX(phy), tmp);
     244                 :            : 
     245                 :          0 :                 tmp = I915_READ(ICL_PORT_TX_DW4_AUX(phy));
     246                 :          0 :                 tmp &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
     247                 :            :                          CURSOR_COEFF_MASK);
     248                 :          0 :                 tmp |= POST_CURSOR_1(0x0);
     249                 :          0 :                 tmp |= POST_CURSOR_2(0x0);
     250                 :          0 :                 tmp |= CURSOR_COEFF(0x3f);
     251                 :          0 :                 I915_WRITE(ICL_PORT_TX_DW4_AUX(phy), tmp);
     252                 :            : 
     253         [ #  # ]:          0 :                 for (lane = 0; lane <= 3; lane++) {
     254                 :            :                         /* Bspec: must not use GRP register for write */
     255                 :          0 :                         tmp = I915_READ(ICL_PORT_TX_DW4_LN(lane, phy));
     256                 :          0 :                         tmp &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
     257                 :            :                                  CURSOR_COEFF_MASK);
     258                 :          0 :                         tmp |= POST_CURSOR_1(0x0);
     259                 :          0 :                         tmp |= POST_CURSOR_2(0x0);
     260                 :          0 :                         tmp |= CURSOR_COEFF(0x3f);
     261                 :          0 :                         I915_WRITE(ICL_PORT_TX_DW4_LN(lane, phy), tmp);
     262                 :            :                 }
     263                 :            :         }
     264                 :          0 : }
     265                 :            : 
     266                 :          0 : static void configure_dual_link_mode(struct intel_encoder *encoder,
     267                 :            :                                      const struct intel_crtc_state *pipe_config)
     268                 :            : {
     269                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     270                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     271                 :          0 :         u32 dss_ctl1;
     272                 :            : 
     273                 :          0 :         dss_ctl1 = I915_READ(DSS_CTL1);
     274                 :          0 :         dss_ctl1 |= SPLITTER_ENABLE;
     275                 :          0 :         dss_ctl1 &= ~OVERLAP_PIXELS_MASK;
     276                 :          0 :         dss_ctl1 |= OVERLAP_PIXELS(intel_dsi->pixel_overlap);
     277                 :            : 
     278         [ #  # ]:          0 :         if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
     279                 :          0 :                 const struct drm_display_mode *adjusted_mode =
     280                 :            :                                         &pipe_config->hw.adjusted_mode;
     281                 :          0 :                 u32 dss_ctl2;
     282                 :          0 :                 u16 hactive = adjusted_mode->crtc_hdisplay;
     283                 :          0 :                 u16 dl_buffer_depth;
     284                 :            : 
     285                 :          0 :                 dss_ctl1 &= ~DUAL_LINK_MODE_INTERLEAVE;
     286                 :          0 :                 dl_buffer_depth = hactive / 2 + intel_dsi->pixel_overlap;
     287                 :            : 
     288         [ #  # ]:          0 :                 if (dl_buffer_depth > MAX_DL_BUFFER_TARGET_DEPTH)
     289                 :          0 :                         DRM_ERROR("DL buffer depth exceed max value\n");
     290                 :            : 
     291                 :          0 :                 dss_ctl1 &= ~LEFT_DL_BUF_TARGET_DEPTH_MASK;
     292                 :          0 :                 dss_ctl1 |= LEFT_DL_BUF_TARGET_DEPTH(dl_buffer_depth);
     293                 :          0 :                 dss_ctl2 = I915_READ(DSS_CTL2);
     294                 :          0 :                 dss_ctl2 &= ~RIGHT_DL_BUF_TARGET_DEPTH_MASK;
     295                 :          0 :                 dss_ctl2 |= RIGHT_DL_BUF_TARGET_DEPTH(dl_buffer_depth);
     296                 :          0 :                 I915_WRITE(DSS_CTL2, dss_ctl2);
     297                 :            :         } else {
     298                 :            :                 /* Interleave */
     299                 :          0 :                 dss_ctl1 |= DUAL_LINK_MODE_INTERLEAVE;
     300                 :            :         }
     301                 :            : 
     302                 :          0 :         I915_WRITE(DSS_CTL1, dss_ctl1);
     303                 :          0 : }
     304                 :            : 
     305                 :            : /* aka DSI 8X clock */
     306                 :          0 : static int afe_clk(struct intel_encoder *encoder,
     307                 :            :                    const struct intel_crtc_state *crtc_state)
     308                 :            : {
     309                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     310                 :          0 :         int bpp;
     311                 :            : 
     312   [ #  #  #  #  :          0 :         if (crtc_state->dsc.compression_enable)
             #  #  #  # ]
     313                 :          0 :                 bpp = crtc_state->dsc.compressed_bpp;
     314                 :            :         else
     315   [ #  #  #  #  :          0 :                 bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
          #  #  #  #  #  
                      # ]
     316                 :            : 
     317                 :          0 :         return DIV_ROUND_CLOSEST(intel_dsi->pclk * bpp, intel_dsi->lane_count);
     318                 :            : }
     319                 :            : 
     320                 :          0 : static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder,
     321                 :            :                                           const struct intel_crtc_state *crtc_state)
     322                 :            : {
     323         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     324         [ #  # ]:          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     325                 :          0 :         enum port port;
     326                 :          0 :         int afe_clk_khz;
     327                 :          0 :         u32 esc_clk_div_m;
     328                 :            : 
     329         [ #  # ]:          0 :         afe_clk_khz = afe_clk(encoder, crtc_state);
     330                 :          0 :         esc_clk_div_m = DIV_ROUND_UP(afe_clk_khz, DSI_MAX_ESC_CLK);
     331                 :            : 
     332   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     333                 :          0 :                 I915_WRITE(ICL_DSI_ESC_CLK_DIV(port),
     334                 :            :                            esc_clk_div_m & ICL_ESC_CLK_DIV_MASK);
     335                 :          0 :                 POSTING_READ(ICL_DSI_ESC_CLK_DIV(port));
     336                 :            :         }
     337                 :            : 
     338   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     339                 :          0 :                 I915_WRITE(ICL_DPHY_ESC_CLK_DIV(port),
     340                 :            :                            esc_clk_div_m & ICL_ESC_CLK_DIV_MASK);
     341                 :          0 :                 POSTING_READ(ICL_DPHY_ESC_CLK_DIV(port));
     342                 :            :         }
     343                 :          0 : }
     344                 :            : 
     345                 :          0 : static void get_dsi_io_power_domains(struct drm_i915_private *dev_priv,
     346                 :            :                                      struct intel_dsi *intel_dsi)
     347                 :            : {
     348                 :          0 :         enum port port;
     349                 :            : 
     350   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     351         [ #  # ]:          0 :                 WARN_ON(intel_dsi->io_wakeref[port]);
     352                 :          0 :                 intel_dsi->io_wakeref[port] =
     353         [ #  # ]:          0 :                         intel_display_power_get(dev_priv,
     354                 :            :                                                 port == PORT_A ?
     355                 :            :                                                 POWER_DOMAIN_PORT_DDI_A_IO :
     356                 :            :                                                 POWER_DOMAIN_PORT_DDI_B_IO);
     357                 :            :         }
     358                 :          0 : }
     359                 :            : 
     360                 :          0 : static void gen11_dsi_enable_io_power(struct intel_encoder *encoder)
     361                 :            : {
     362                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     363                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     364                 :          0 :         enum port port;
     365                 :          0 :         u32 tmp;
     366                 :            : 
     367   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     368                 :          0 :                 tmp = I915_READ(ICL_DSI_IO_MODECTL(port));
     369                 :          0 :                 tmp |= COMBO_PHY_MODE_DSI;
     370                 :          0 :                 I915_WRITE(ICL_DSI_IO_MODECTL(port), tmp);
     371                 :            :         }
     372                 :            : 
     373                 :          0 :         get_dsi_io_power_domains(dev_priv, intel_dsi);
     374                 :          0 : }
     375                 :            : 
     376                 :          0 : static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder)
     377                 :            : {
     378                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     379                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     380                 :          0 :         enum phy phy;
     381                 :            : 
     382   [ #  #  #  # ]:          0 :         for_each_dsi_phy(phy, intel_dsi->phys)
     383                 :          0 :                 intel_combo_phy_power_up_lanes(dev_priv, phy, true,
     384                 :          0 :                                                intel_dsi->lane_count, false);
     385                 :          0 : }
     386                 :            : 
     387                 :          0 : static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder)
     388                 :            : {
     389                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     390                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     391                 :          0 :         enum phy phy;
     392                 :          0 :         u32 tmp;
     393                 :          0 :         int lane;
     394                 :            : 
     395                 :            :         /* Step 4b(i) set loadgen select for transmit and aux lanes */
     396   [ #  #  #  # ]:          0 :         for_each_dsi_phy(phy, intel_dsi->phys) {
     397                 :          0 :                 tmp = I915_READ(ICL_PORT_TX_DW4_AUX(phy));
     398                 :          0 :                 tmp &= ~LOADGEN_SELECT;
     399                 :          0 :                 I915_WRITE(ICL_PORT_TX_DW4_AUX(phy), tmp);
     400         [ #  # ]:          0 :                 for (lane = 0; lane <= 3; lane++) {
     401                 :          0 :                         tmp = I915_READ(ICL_PORT_TX_DW4_LN(lane, phy));
     402                 :          0 :                         tmp &= ~LOADGEN_SELECT;
     403         [ #  # ]:          0 :                         if (lane != 2)
     404                 :          0 :                                 tmp |= LOADGEN_SELECT;
     405                 :          0 :                         I915_WRITE(ICL_PORT_TX_DW4_LN(lane, phy), tmp);
     406                 :            :                 }
     407                 :            :         }
     408                 :            : 
     409                 :            :         /* Step 4b(ii) set latency optimization for transmit and aux lanes */
     410   [ #  #  #  # ]:          0 :         for_each_dsi_phy(phy, intel_dsi->phys) {
     411                 :          0 :                 tmp = I915_READ(ICL_PORT_TX_DW2_AUX(phy));
     412                 :          0 :                 tmp &= ~FRC_LATENCY_OPTIM_MASK;
     413                 :          0 :                 tmp |= FRC_LATENCY_OPTIM_VAL(0x5);
     414                 :          0 :                 I915_WRITE(ICL_PORT_TX_DW2_AUX(phy), tmp);
     415                 :          0 :                 tmp = I915_READ(ICL_PORT_TX_DW2_LN0(phy));
     416                 :          0 :                 tmp &= ~FRC_LATENCY_OPTIM_MASK;
     417                 :          0 :                 tmp |= FRC_LATENCY_OPTIM_VAL(0x5);
     418                 :          0 :                 I915_WRITE(ICL_PORT_TX_DW2_GRP(phy), tmp);
     419                 :            : 
     420                 :            :                 /* For EHL, TGL, set latency optimization for PCS_DW1 lanes */
     421   [ #  #  #  # ]:          0 :                 if (IS_ELKHARTLAKE(dev_priv) || (INTEL_GEN(dev_priv) >= 12)) {
     422                 :          0 :                         tmp = I915_READ(ICL_PORT_PCS_DW1_AUX(phy));
     423                 :          0 :                         tmp &= ~LATENCY_OPTIM_MASK;
     424                 :          0 :                         tmp |= LATENCY_OPTIM_VAL(0);
     425                 :          0 :                         I915_WRITE(ICL_PORT_PCS_DW1_AUX(phy), tmp);
     426                 :            : 
     427                 :          0 :                         tmp = I915_READ(ICL_PORT_PCS_DW1_LN0(phy));
     428                 :          0 :                         tmp &= ~LATENCY_OPTIM_MASK;
     429                 :          0 :                         tmp |= LATENCY_OPTIM_VAL(0x1);
     430                 :          0 :                         I915_WRITE(ICL_PORT_PCS_DW1_GRP(phy), tmp);
     431                 :            :                 }
     432                 :            :         }
     433                 :            : 
     434                 :          0 : }
     435                 :            : 
     436                 :          0 : static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder)
     437                 :            : {
     438                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     439                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     440                 :          0 :         u32 tmp;
     441                 :          0 :         enum phy phy;
     442                 :            : 
     443                 :            :         /* clear common keeper enable bit */
     444   [ #  #  #  # ]:          0 :         for_each_dsi_phy(phy, intel_dsi->phys) {
     445                 :          0 :                 tmp = I915_READ(ICL_PORT_PCS_DW1_LN0(phy));
     446                 :          0 :                 tmp &= ~COMMON_KEEPER_EN;
     447                 :          0 :                 I915_WRITE(ICL_PORT_PCS_DW1_GRP(phy), tmp);
     448                 :          0 :                 tmp = I915_READ(ICL_PORT_PCS_DW1_AUX(phy));
     449                 :          0 :                 tmp &= ~COMMON_KEEPER_EN;
     450                 :          0 :                 I915_WRITE(ICL_PORT_PCS_DW1_AUX(phy), tmp);
     451                 :            :         }
     452                 :            : 
     453                 :            :         /*
     454                 :            :          * Set SUS Clock Config bitfield to 11b
     455                 :            :          * Note: loadgen select program is done
     456                 :            :          * as part of lane phy sequence configuration
     457                 :            :          */
     458   [ #  #  #  # ]:          0 :         for_each_dsi_phy(phy, intel_dsi->phys) {
     459                 :          0 :                 tmp = I915_READ(ICL_PORT_CL_DW5(phy));
     460                 :          0 :                 tmp |= SUS_CLOCK_CONFIG;
     461                 :          0 :                 I915_WRITE(ICL_PORT_CL_DW5(phy), tmp);
     462                 :            :         }
     463                 :            : 
     464                 :            :         /* Clear training enable to change swing values */
     465   [ #  #  #  # ]:          0 :         for_each_dsi_phy(phy, intel_dsi->phys) {
     466                 :          0 :                 tmp = I915_READ(ICL_PORT_TX_DW5_LN0(phy));
     467                 :          0 :                 tmp &= ~TX_TRAINING_EN;
     468                 :          0 :                 I915_WRITE(ICL_PORT_TX_DW5_GRP(phy), tmp);
     469                 :          0 :                 tmp = I915_READ(ICL_PORT_TX_DW5_AUX(phy));
     470                 :          0 :                 tmp &= ~TX_TRAINING_EN;
     471                 :          0 :                 I915_WRITE(ICL_PORT_TX_DW5_AUX(phy), tmp);
     472                 :            :         }
     473                 :            : 
     474                 :            :         /* Program swing and de-emphasis */
     475                 :          0 :         dsi_program_swing_and_deemphasis(encoder);
     476                 :            : 
     477                 :            :         /* Set training enable to trigger update */
     478   [ #  #  #  # ]:          0 :         for_each_dsi_phy(phy, intel_dsi->phys) {
     479                 :          0 :                 tmp = I915_READ(ICL_PORT_TX_DW5_LN0(phy));
     480                 :          0 :                 tmp |= TX_TRAINING_EN;
     481                 :          0 :                 I915_WRITE(ICL_PORT_TX_DW5_GRP(phy), tmp);
     482                 :          0 :                 tmp = I915_READ(ICL_PORT_TX_DW5_AUX(phy));
     483                 :          0 :                 tmp |= TX_TRAINING_EN;
     484                 :          0 :                 I915_WRITE(ICL_PORT_TX_DW5_AUX(phy), tmp);
     485                 :            :         }
     486                 :          0 : }
     487                 :            : 
     488                 :          0 : static void gen11_dsi_enable_ddi_buffer(struct intel_encoder *encoder)
     489                 :            : {
     490                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     491                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     492                 :          0 :         u32 tmp;
     493                 :          0 :         enum port port;
     494                 :            : 
     495   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     496                 :          0 :                 tmp = I915_READ(DDI_BUF_CTL(port));
     497                 :          0 :                 tmp |= DDI_BUF_CTL_ENABLE;
     498                 :          0 :                 I915_WRITE(DDI_BUF_CTL(port), tmp);
     499                 :            : 
     500   [ #  #  #  #  :          0 :                 if (wait_for_us(!(I915_READ(DDI_BUF_CTL(port)) &
                   #  # ]
     501                 :            :                                   DDI_BUF_IS_IDLE),
     502                 :            :                                   500))
     503                 :          0 :                         DRM_ERROR("DDI port:%c buffer idle\n", port_name(port));
     504                 :            :         }
     505                 :          0 : }
     506                 :            : 
     507                 :            : static void
     508                 :          0 : gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
     509                 :            :                              const struct intel_crtc_state *crtc_state)
     510                 :            : {
     511                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     512                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     513                 :          0 :         u32 tmp;
     514                 :          0 :         enum port port;
     515                 :          0 :         enum phy phy;
     516                 :            : 
     517                 :            :         /* Program T-INIT master registers */
     518   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     519                 :          0 :                 tmp = I915_READ(ICL_DSI_T_INIT_MASTER(port));
     520                 :          0 :                 tmp &= ~MASTER_INIT_TIMER_MASK;
     521                 :          0 :                 tmp |= intel_dsi->init_count;
     522                 :          0 :                 I915_WRITE(ICL_DSI_T_INIT_MASTER(port), tmp);
     523                 :            :         }
     524                 :            : 
     525                 :            :         /* Program DPHY clock lanes timings */
     526   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     527                 :          0 :                 I915_WRITE(DPHY_CLK_TIMING_PARAM(port), intel_dsi->dphy_reg);
     528                 :            : 
     529                 :            :                 /* shadow register inside display core */
     530                 :          0 :                 I915_WRITE(DSI_CLK_TIMING_PARAM(port), intel_dsi->dphy_reg);
     531                 :            :         }
     532                 :            : 
     533                 :            :         /* Program DPHY data lanes timings */
     534   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     535                 :          0 :                 I915_WRITE(DPHY_DATA_TIMING_PARAM(port),
     536                 :            :                            intel_dsi->dphy_data_lane_reg);
     537                 :            : 
     538                 :            :                 /* shadow register inside display core */
     539                 :          0 :                 I915_WRITE(DSI_DATA_TIMING_PARAM(port),
     540                 :            :                            intel_dsi->dphy_data_lane_reg);
     541                 :            :         }
     542                 :            : 
     543                 :            :         /*
     544                 :            :          * If DSI link operating at or below an 800 MHz,
     545                 :            :          * TA_SURE should be override and programmed to
     546                 :            :          * a value '0' inside TA_PARAM_REGISTERS otherwise
     547                 :            :          * leave all fields at HW default values.
     548                 :            :          */
     549         [ #  # ]:          0 :         if (IS_GEN(dev_priv, 11)) {
     550   [ #  #  #  # ]:          0 :                 if (afe_clk(encoder, crtc_state) <= 800000) {
     551   [ #  #  #  # ]:          0 :                         for_each_dsi_port(port, intel_dsi->ports) {
     552                 :          0 :                                 tmp = I915_READ(DPHY_TA_TIMING_PARAM(port));
     553                 :          0 :                                 tmp &= ~TA_SURE_MASK;
     554                 :          0 :                                 tmp |= TA_SURE_OVERRIDE | TA_SURE(0);
     555                 :          0 :                                 I915_WRITE(DPHY_TA_TIMING_PARAM(port), tmp);
     556                 :            : 
     557                 :            :                                 /* shadow register inside display core */
     558                 :          0 :                                 tmp = I915_READ(DSI_TA_TIMING_PARAM(port));
     559                 :          0 :                                 tmp &= ~TA_SURE_MASK;
     560                 :          0 :                                 tmp |= TA_SURE_OVERRIDE | TA_SURE(0);
     561                 :          0 :                                 I915_WRITE(DSI_TA_TIMING_PARAM(port), tmp);
     562                 :            :                         }
     563                 :            :                 }
     564                 :            :         }
     565                 :            : 
     566         [ #  # ]:          0 :         if (IS_ELKHARTLAKE(dev_priv)) {
     567   [ #  #  #  # ]:          0 :                 for_each_dsi_phy(phy, intel_dsi->phys) {
     568                 :          0 :                         tmp = I915_READ(ICL_DPHY_CHKN(phy));
     569                 :          0 :                         tmp |= ICL_DPHY_CHKN_AFE_OVER_PPI_STRAP;
     570                 :          0 :                         I915_WRITE(ICL_DPHY_CHKN(phy), tmp);
     571                 :            :                 }
     572                 :            :         }
     573                 :          0 : }
     574                 :            : 
     575                 :          0 : static void gen11_dsi_gate_clocks(struct intel_encoder *encoder)
     576                 :            : {
     577                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     578                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     579                 :          0 :         u32 tmp;
     580                 :          0 :         enum phy phy;
     581                 :            : 
     582                 :          0 :         mutex_lock(&dev_priv->dpll_lock);
     583                 :          0 :         tmp = I915_READ(ICL_DPCLKA_CFGCR0);
     584   [ #  #  #  # ]:          0 :         for_each_dsi_phy(phy, intel_dsi->phys)
     585                 :          0 :                 tmp |= ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
     586                 :            : 
     587                 :          0 :         I915_WRITE(ICL_DPCLKA_CFGCR0, tmp);
     588                 :          0 :         mutex_unlock(&dev_priv->dpll_lock);
     589                 :          0 : }
     590                 :            : 
     591                 :          0 : static void gen11_dsi_ungate_clocks(struct intel_encoder *encoder)
     592                 :            : {
     593                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     594                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     595                 :          0 :         u32 tmp;
     596                 :          0 :         enum phy phy;
     597                 :            : 
     598                 :          0 :         mutex_lock(&dev_priv->dpll_lock);
     599                 :          0 :         tmp = I915_READ(ICL_DPCLKA_CFGCR0);
     600   [ #  #  #  # ]:          0 :         for_each_dsi_phy(phy, intel_dsi->phys)
     601                 :          0 :                 tmp &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
     602                 :            : 
     603                 :          0 :         I915_WRITE(ICL_DPCLKA_CFGCR0, tmp);
     604                 :          0 :         mutex_unlock(&dev_priv->dpll_lock);
     605                 :          0 : }
     606                 :            : 
     607                 :            : static void gen11_dsi_map_pll(struct intel_encoder *encoder,
     608                 :            :                               const struct intel_crtc_state *crtc_state)
     609                 :            : {
     610                 :            :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     611                 :            :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     612                 :            :         struct intel_shared_dpll *pll = crtc_state->shared_dpll;
     613                 :            :         enum phy phy;
     614                 :            :         u32 val;
     615                 :            : 
     616                 :            :         mutex_lock(&dev_priv->dpll_lock);
     617                 :            : 
     618                 :            :         val = I915_READ(ICL_DPCLKA_CFGCR0);
     619                 :            :         for_each_dsi_phy(phy, intel_dsi->phys) {
     620                 :            :                 val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
     621                 :            :                 val |= ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
     622                 :            :         }
     623                 :            :         I915_WRITE(ICL_DPCLKA_CFGCR0, val);
     624                 :            : 
     625                 :            :         for_each_dsi_phy(phy, intel_dsi->phys) {
     626                 :            :                 if (INTEL_GEN(dev_priv) >= 12)
     627                 :            :                         val |= ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
     628                 :            :                 else
     629                 :            :                         val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
     630                 :            :         }
     631                 :            :         I915_WRITE(ICL_DPCLKA_CFGCR0, val);
     632                 :            : 
     633                 :            :         POSTING_READ(ICL_DPCLKA_CFGCR0);
     634                 :            : 
     635                 :            :         mutex_unlock(&dev_priv->dpll_lock);
     636                 :            : }
     637                 :            : 
     638                 :            : static void
     639                 :          0 : gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
     640                 :            :                                const struct intel_crtc_state *pipe_config)
     641                 :            : {
     642                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     643                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     644                 :          0 :         struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
     645                 :          0 :         enum pipe pipe = intel_crtc->pipe;
     646                 :          0 :         u32 tmp;
     647                 :          0 :         enum port port;
     648                 :          0 :         enum transcoder dsi_trans;
     649                 :            : 
     650   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     651         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
     652                 :          0 :                 tmp = I915_READ(DSI_TRANS_FUNC_CONF(dsi_trans));
     653                 :            : 
     654         [ #  # ]:          0 :                 if (intel_dsi->eotp_pkt)
     655                 :          0 :                         tmp &= ~EOTP_DISABLED;
     656                 :            :                 else
     657                 :          0 :                         tmp |= EOTP_DISABLED;
     658                 :            : 
     659                 :            :                 /* enable link calibration if freq > 1.5Gbps */
     660   [ #  #  #  # ]:          0 :                 if (afe_clk(encoder, pipe_config) >= 1500 * 1000) {
     661                 :          0 :                         tmp &= ~LINK_CALIBRATION_MASK;
     662                 :          0 :                         tmp |= CALIBRATION_ENABLED_INITIAL_ONLY;
     663                 :            :                 }
     664                 :            : 
     665                 :            :                 /* configure continuous clock */
     666                 :          0 :                 tmp &= ~CONTINUOUS_CLK_MASK;
     667         [ #  # ]:          0 :                 if (intel_dsi->clock_stop)
     668                 :            :                         tmp |= CLK_ENTER_LP_AFTER_DATA;
     669                 :            :                 else
     670                 :          0 :                         tmp |= CLK_HS_CONTINUOUS;
     671                 :            : 
     672                 :            :                 /* configure buffer threshold limit to minimum */
     673                 :          0 :                 tmp &= ~PIX_BUF_THRESHOLD_MASK;
     674                 :          0 :                 tmp |= PIX_BUF_THRESHOLD_1_4;
     675                 :            : 
     676                 :            :                 /* set virtual channel to '0' */
     677                 :          0 :                 tmp &= ~PIX_VIRT_CHAN_MASK;
     678                 :          0 :                 tmp |= PIX_VIRT_CHAN(0);
     679                 :            : 
     680                 :            :                 /* program BGR transmission */
     681         [ #  # ]:          0 :                 if (intel_dsi->bgr_enabled)
     682                 :          0 :                         tmp |= BGR_TRANSMISSION;
     683                 :            : 
     684                 :            :                 /* select pixel format */
     685                 :          0 :                 tmp &= ~PIX_FMT_MASK;
     686         [ #  # ]:          0 :                 if (pipe_config->dsc.compression_enable) {
     687                 :          0 :                         tmp |= PIX_FMT_COMPRESSED;
     688                 :            :                 } else {
     689   [ #  #  #  #  :          0 :                         switch (intel_dsi->pixel_format) {
                      # ]
     690                 :            :                         default:
     691                 :          0 :                                 MISSING_CASE(intel_dsi->pixel_format);
     692                 :            :                                 /* fallthrough */
     693                 :            :                         case MIPI_DSI_FMT_RGB565:
     694                 :            :                                 tmp |= PIX_FMT_RGB565;
     695                 :            :                                 break;
     696                 :          0 :                         case MIPI_DSI_FMT_RGB666_PACKED:
     697                 :          0 :                                 tmp |= PIX_FMT_RGB666_PACKED;
     698                 :          0 :                                 break;
     699                 :          0 :                         case MIPI_DSI_FMT_RGB666:
     700                 :          0 :                                 tmp |= PIX_FMT_RGB666_LOOSE;
     701                 :          0 :                                 break;
     702                 :          0 :                         case MIPI_DSI_FMT_RGB888:
     703                 :          0 :                                 tmp |= PIX_FMT_RGB888;
     704                 :          0 :                                 break;
     705                 :            :                         }
     706                 :            :                 }
     707                 :            : 
     708         [ #  # ]:          0 :                 if (INTEL_GEN(dev_priv) >= 12) {
     709         [ #  # ]:          0 :                         if (is_vid_mode(intel_dsi))
     710                 :          0 :                                 tmp |= BLANKING_PACKET_ENABLE;
     711                 :            :                 }
     712                 :            : 
     713                 :            :                 /* program DSI operation mode */
     714         [ #  # ]:          0 :                 if (is_vid_mode(intel_dsi)) {
     715                 :          0 :                         tmp &= ~OP_MODE_MASK;
     716      [ #  #  # ]:          0 :                         switch (intel_dsi->video_mode_format) {
     717                 :            :                         default:
     718                 :          0 :                                 MISSING_CASE(intel_dsi->video_mode_format);
     719                 :            :                                 /* fallthrough */
     720                 :          0 :                         case VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS:
     721                 :          0 :                                 tmp |= VIDEO_MODE_SYNC_EVENT;
     722                 :          0 :                                 break;
     723                 :          0 :                         case VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE:
     724                 :          0 :                                 tmp |= VIDEO_MODE_SYNC_PULSE;
     725                 :          0 :                                 break;
     726                 :            :                         }
     727                 :          0 :                 }
     728                 :            : 
     729                 :          0 :                 I915_WRITE(DSI_TRANS_FUNC_CONF(dsi_trans), tmp);
     730                 :            :         }
     731                 :            : 
     732                 :            :         /* enable port sync mode if dual link */
     733         [ #  # ]:          0 :         if (intel_dsi->dual_link) {
     734   [ #  #  #  # ]:          0 :                 for_each_dsi_port(port, intel_dsi->ports) {
     735         [ #  # ]:          0 :                         dsi_trans = dsi_port_to_transcoder(port);
     736                 :          0 :                         tmp = I915_READ(TRANS_DDI_FUNC_CTL2(dsi_trans));
     737                 :          0 :                         tmp |= PORT_SYNC_MODE_ENABLE;
     738                 :          0 :                         I915_WRITE(TRANS_DDI_FUNC_CTL2(dsi_trans), tmp);
     739                 :            :                 }
     740                 :            : 
     741                 :            :                 /* configure stream splitting */
     742                 :          0 :                 configure_dual_link_mode(encoder, pipe_config);
     743                 :            :         }
     744                 :            : 
     745   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     746         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
     747                 :            : 
     748                 :            :                 /* select data lane width */
     749                 :          0 :                 tmp = I915_READ(TRANS_DDI_FUNC_CTL(dsi_trans));
     750                 :          0 :                 tmp &= ~DDI_PORT_WIDTH_MASK;
     751                 :          0 :                 tmp |= DDI_PORT_WIDTH(intel_dsi->lane_count);
     752                 :            : 
     753                 :            :                 /* select input pipe */
     754                 :          0 :                 tmp &= ~TRANS_DDI_EDP_INPUT_MASK;
     755   [ #  #  #  #  :          0 :                 switch (pipe) {
                      # ]
     756                 :            :                 default:
     757                 :          0 :                         MISSING_CASE(pipe);
     758                 :            :                         /* fallthrough */
     759                 :            :                 case PIPE_A:
     760                 :            :                         tmp |= TRANS_DDI_EDP_INPUT_A_ON;
     761                 :            :                         break;
     762                 :          0 :                 case PIPE_B:
     763                 :          0 :                         tmp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
     764                 :          0 :                         break;
     765                 :          0 :                 case PIPE_C:
     766                 :          0 :                         tmp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
     767                 :          0 :                         break;
     768                 :          0 :                 case PIPE_D:
     769                 :          0 :                         tmp |= TRANS_DDI_EDP_INPUT_D_ONOFF;
     770                 :          0 :                         break;
     771                 :            :                 }
     772                 :            : 
     773                 :            :                 /* enable DDI buffer */
     774                 :          0 :                 tmp |= TRANS_DDI_FUNC_ENABLE;
     775                 :          0 :                 I915_WRITE(TRANS_DDI_FUNC_CTL(dsi_trans), tmp);
     776                 :            :         }
     777                 :            : 
     778                 :            :         /* wait for link ready */
     779   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     780         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
     781   [ #  #  #  #  :          0 :                 if (wait_for_us((I915_READ(DSI_TRANS_FUNC_CONF(dsi_trans)) &
                   #  # ]
     782                 :            :                                 LINK_READY), 2500))
     783                 :          0 :                         DRM_ERROR("DSI link not ready\n");
     784                 :            :         }
     785                 :          0 : }
     786                 :            : 
     787                 :            : static void
     788                 :          0 : gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
     789                 :            :                                  const struct intel_crtc_state *crtc_state)
     790                 :            : {
     791         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     792         [ #  # ]:          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     793                 :          0 :         const struct drm_display_mode *adjusted_mode =
     794                 :            :                 &crtc_state->hw.adjusted_mode;
     795                 :          0 :         enum port port;
     796                 :          0 :         enum transcoder dsi_trans;
     797                 :            :         /* horizontal timings */
     798                 :          0 :         u16 htotal, hactive, hsync_start, hsync_end, hsync_size;
     799                 :          0 :         u16 hback_porch;
     800                 :            :         /* vertical timings */
     801                 :          0 :         u16 vtotal, vactive, vsync_start, vsync_end, vsync_shift;
     802                 :          0 :         int mul = 1, div = 1;
     803                 :            : 
     804                 :            :         /*
     805                 :            :          * Adjust horizontal timings (htotal, hsync_start, hsync_end) to account
     806                 :            :          * for slower link speed if DSC is enabled.
     807                 :            :          *
     808                 :            :          * The compression frequency ratio is the ratio between compressed and
     809                 :            :          * non-compressed link speeds, and simplifies down to the ratio between
     810                 :            :          * compressed and non-compressed bpp.
     811                 :            :          */
     812         [ #  # ]:          0 :         if (crtc_state->dsc.compression_enable) {
     813                 :          0 :                 mul = crtc_state->dsc.compressed_bpp;
     814         [ #  # ]:          0 :                 div = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
     815                 :            :         }
     816                 :            : 
     817                 :          0 :         hactive = adjusted_mode->crtc_hdisplay;
     818                 :          0 :         htotal = DIV_ROUND_UP(adjusted_mode->crtc_htotal * mul, div);
     819                 :          0 :         hsync_start = DIV_ROUND_UP(adjusted_mode->crtc_hsync_start * mul, div);
     820                 :          0 :         hsync_end = DIV_ROUND_UP(adjusted_mode->crtc_hsync_end * mul, div);
     821                 :          0 :         hsync_size  = hsync_end - hsync_start;
     822                 :          0 :         hback_porch = (adjusted_mode->crtc_htotal -
     823                 :            :                        adjusted_mode->crtc_hsync_end);
     824                 :          0 :         vactive = adjusted_mode->crtc_vdisplay;
     825                 :          0 :         vtotal = adjusted_mode->crtc_vtotal;
     826                 :          0 :         vsync_start = adjusted_mode->crtc_vsync_start;
     827                 :          0 :         vsync_end = adjusted_mode->crtc_vsync_end;
     828                 :          0 :         vsync_shift = hsync_start - htotal / 2;
     829                 :            : 
     830         [ #  # ]:          0 :         if (intel_dsi->dual_link) {
     831                 :          0 :                 hactive /= 2;
     832         [ #  # ]:          0 :                 if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK)
     833                 :          0 :                         hactive += intel_dsi->pixel_overlap;
     834                 :            :                 htotal /= 2;
     835                 :            :         }
     836                 :            : 
     837                 :            :         /* minimum hactive as per bspec: 256 pixels */
     838         [ #  # ]:          0 :         if (adjusted_mode->crtc_hdisplay < 256)
     839                 :          0 :                 DRM_ERROR("hactive is less then 256 pixels\n");
     840                 :            : 
     841                 :            :         /* if RGB666 format, then hactive must be multiple of 4 pixels */
     842   [ #  #  #  # ]:          0 :         if (intel_dsi->pixel_format == MIPI_DSI_FMT_RGB666 && hactive % 4 != 0)
     843                 :          0 :                 DRM_ERROR("hactive pixels are not multiple of 4\n");
     844                 :            : 
     845                 :            :         /* program TRANS_HTOTAL register */
     846   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     847         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
     848                 :          0 :                 I915_WRITE(HTOTAL(dsi_trans),
     849                 :            :                            (hactive - 1) | ((htotal - 1) << 16));
     850                 :            :         }
     851                 :            : 
     852                 :            :         /* TRANS_HSYNC register to be programmed only for video mode */
     853         [ #  # ]:          0 :         if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) {
     854         [ #  # ]:          0 :                 if (intel_dsi->video_mode_format ==
     855                 :            :                     VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE) {
     856                 :            :                         /* BSPEC: hsync size should be atleast 16 pixels */
     857         [ #  # ]:          0 :                         if (hsync_size < 16)
     858                 :          0 :                                 DRM_ERROR("hsync size < 16 pixels\n");
     859                 :            :                 }
     860                 :            : 
     861         [ #  # ]:          0 :                 if (hback_porch < 16)
     862                 :          0 :                         DRM_ERROR("hback porch < 16 pixels\n");
     863                 :            : 
     864         [ #  # ]:          0 :                 if (intel_dsi->dual_link) {
     865                 :          0 :                         hsync_start /= 2;
     866                 :          0 :                         hsync_end /= 2;
     867                 :            :                 }
     868                 :            : 
     869   [ #  #  #  # ]:          0 :                 for_each_dsi_port(port, intel_dsi->ports) {
     870         [ #  # ]:          0 :                         dsi_trans = dsi_port_to_transcoder(port);
     871                 :          0 :                         I915_WRITE(HSYNC(dsi_trans),
     872                 :            :                                    (hsync_start - 1) | ((hsync_end - 1) << 16));
     873                 :            :                 }
     874                 :            :         }
     875                 :            : 
     876                 :            :         /* program TRANS_VTOTAL register */
     877   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     878         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
     879                 :            :                 /*
     880                 :            :                  * FIXME: Programing this by assuming progressive mode, since
     881                 :            :                  * non-interlaced info from VBT is not saved inside
     882                 :            :                  * struct drm_display_mode.
     883                 :            :                  * For interlace mode: program required pixel minus 2
     884                 :            :                  */
     885                 :          0 :                 I915_WRITE(VTOTAL(dsi_trans),
     886                 :            :                            (vactive - 1) | ((vtotal - 1) << 16));
     887                 :            :         }
     888                 :            : 
     889         [ #  # ]:          0 :         if (vsync_end < vsync_start || vsync_end > vtotal)
     890                 :          0 :                 DRM_ERROR("Invalid vsync_end value\n");
     891                 :            : 
     892         [ #  # ]:          0 :         if (vsync_start < vactive)
     893                 :          0 :                 DRM_ERROR("vsync_start less than vactive\n");
     894                 :            : 
     895                 :            :         /* program TRANS_VSYNC register */
     896   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     897         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
     898                 :          0 :                 I915_WRITE(VSYNC(dsi_trans),
     899                 :            :                            (vsync_start - 1) | ((vsync_end - 1) << 16));
     900                 :            :         }
     901                 :            : 
     902                 :            :         /*
     903                 :            :          * FIXME: It has to be programmed only for interlaced
     904                 :            :          * modes. Put the check condition here once interlaced
     905                 :            :          * info available as described above.
     906                 :            :          * program TRANS_VSYNCSHIFT register
     907                 :            :          */
     908   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     909         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
     910                 :          0 :                 I915_WRITE(VSYNCSHIFT(dsi_trans), vsync_shift);
     911                 :            :         }
     912                 :            : 
     913                 :            :         /* program TRANS_VBLANK register, should be same as vtotal programmed */
     914         [ #  # ]:          0 :         if (INTEL_GEN(dev_priv) >= 12) {
     915   [ #  #  #  # ]:          0 :                 for_each_dsi_port(port, intel_dsi->ports) {
     916         [ #  # ]:          0 :                         dsi_trans = dsi_port_to_transcoder(port);
     917                 :          0 :                         I915_WRITE(VBLANK(dsi_trans),
     918                 :            :                                    (vactive - 1) | ((vtotal - 1) << 16));
     919                 :            :                 }
     920                 :            :         }
     921                 :          0 : }
     922                 :            : 
     923                 :          0 : static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder)
     924                 :            : {
     925                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     926                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     927                 :          0 :         enum port port;
     928                 :          0 :         enum transcoder dsi_trans;
     929                 :          0 :         u32 tmp;
     930                 :            : 
     931   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     932         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
     933                 :          0 :                 tmp = I915_READ(PIPECONF(dsi_trans));
     934                 :          0 :                 tmp |= PIPECONF_ENABLE;
     935                 :          0 :                 I915_WRITE(PIPECONF(dsi_trans), tmp);
     936                 :            : 
     937                 :            :                 /* wait for transcoder to be enabled */
     938         [ #  # ]:          0 :                 if (intel_de_wait_for_set(dev_priv, PIPECONF(dsi_trans),
     939                 :            :                                           I965_PIPECONF_ACTIVE, 10))
     940                 :          0 :                         DRM_ERROR("DSI transcoder not enabled\n");
     941                 :            :         }
     942                 :          0 : }
     943                 :            : 
     944                 :          0 : static void gen11_dsi_setup_timeouts(struct intel_encoder *encoder,
     945                 :            :                                      const struct intel_crtc_state *crtc_state)
     946                 :            : {
     947                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     948                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
     949                 :          0 :         enum port port;
     950                 :          0 :         enum transcoder dsi_trans;
     951                 :          0 :         u32 tmp, hs_tx_timeout, lp_rx_timeout, ta_timeout, divisor, mul;
     952                 :            : 
     953                 :            :         /*
     954                 :            :          * escape clock count calculation:
     955                 :            :          * BYTE_CLK_COUNT = TIME_NS/(8 * UI)
     956                 :            :          * UI (nsec) = (10^6)/Bitrate
     957                 :            :          * TIME_NS = (BYTE_CLK_COUNT * 8 * 10^6)/ Bitrate
     958                 :            :          * ESCAPE_CLK_COUNT  = TIME_NS/ESC_CLK_NS
     959                 :            :          */
     960         [ #  # ]:          0 :         divisor = intel_dsi_tlpx_ns(intel_dsi) * afe_clk(encoder, crtc_state) * 1000;
     961                 :          0 :         mul = 8 * 1000000;
     962                 :          0 :         hs_tx_timeout = DIV_ROUND_UP(intel_dsi->hs_tx_timeout * mul,
     963                 :            :                                      divisor);
     964                 :          0 :         lp_rx_timeout = DIV_ROUND_UP(intel_dsi->lp_rx_timeout * mul, divisor);
     965                 :          0 :         ta_timeout = DIV_ROUND_UP(intel_dsi->turn_arnd_val * mul, divisor);
     966                 :            : 
     967   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
     968         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
     969                 :            : 
     970                 :            :                 /* program hst_tx_timeout */
     971                 :          0 :                 tmp = I915_READ(DSI_HSTX_TO(dsi_trans));
     972                 :          0 :                 tmp &= ~HSTX_TIMEOUT_VALUE_MASK;
     973                 :          0 :                 tmp |= HSTX_TIMEOUT_VALUE(hs_tx_timeout);
     974                 :          0 :                 I915_WRITE(DSI_HSTX_TO(dsi_trans), tmp);
     975                 :            : 
     976                 :            :                 /* FIXME: DSI_CALIB_TO */
     977                 :            : 
     978                 :            :                 /* program lp_rx_host timeout */
     979                 :          0 :                 tmp = I915_READ(DSI_LPRX_HOST_TO(dsi_trans));
     980                 :          0 :                 tmp &= ~LPRX_TIMEOUT_VALUE_MASK;
     981                 :          0 :                 tmp |= LPRX_TIMEOUT_VALUE(lp_rx_timeout);
     982                 :          0 :                 I915_WRITE(DSI_LPRX_HOST_TO(dsi_trans), tmp);
     983                 :            : 
     984                 :            :                 /* FIXME: DSI_PWAIT_TO */
     985                 :            : 
     986                 :            :                 /* program turn around timeout */
     987                 :          0 :                 tmp = I915_READ(DSI_TA_TO(dsi_trans));
     988                 :          0 :                 tmp &= ~TA_TIMEOUT_VALUE_MASK;
     989                 :          0 :                 tmp |= TA_TIMEOUT_VALUE(ta_timeout);
     990                 :          0 :                 I915_WRITE(DSI_TA_TO(dsi_trans), tmp);
     991                 :            :         }
     992                 :          0 : }
     993                 :            : 
     994                 :            : static void
     995                 :          0 : gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder,
     996                 :            :                               const struct intel_crtc_state *crtc_state)
     997                 :            : {
     998                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     999                 :            : 
    1000                 :            :         /* step 4a: power up all lanes of the DDI used by DSI */
    1001                 :          0 :         gen11_dsi_power_up_lanes(encoder);
    1002                 :            : 
    1003                 :            :         /* step 4b: configure lane sequencing of the Combo-PHY transmitters */
    1004                 :          0 :         gen11_dsi_config_phy_lanes_sequence(encoder);
    1005                 :            : 
    1006                 :            :         /* step 4c: configure voltage swing and skew */
    1007                 :          0 :         gen11_dsi_voltage_swing_program_seq(encoder);
    1008                 :            : 
    1009                 :            :         /* enable DDI buffer */
    1010                 :          0 :         gen11_dsi_enable_ddi_buffer(encoder);
    1011                 :            : 
    1012                 :            :         /* setup D-PHY timings */
    1013                 :          0 :         gen11_dsi_setup_dphy_timings(encoder, crtc_state);
    1014                 :            : 
    1015                 :            :         /* step 4h: setup DSI protocol timeouts */
    1016                 :          0 :         gen11_dsi_setup_timeouts(encoder, crtc_state);
    1017                 :            : 
    1018                 :            :         /* Step (4h, 4i, 4j, 4k): Configure transcoder */
    1019                 :          0 :         gen11_dsi_configure_transcoder(encoder, crtc_state);
    1020                 :            : 
    1021                 :            :         /* Step 4l: Gate DDI clocks */
    1022         [ #  # ]:          0 :         if (IS_GEN(dev_priv, 11))
    1023                 :          0 :                 gen11_dsi_gate_clocks(encoder);
    1024                 :          0 : }
    1025                 :            : 
    1026                 :          0 : static void gen11_dsi_powerup_panel(struct intel_encoder *encoder)
    1027                 :            : {
    1028                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
    1029                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
    1030                 :          0 :         struct mipi_dsi_device *dsi;
    1031                 :          0 :         enum port port;
    1032                 :          0 :         enum transcoder dsi_trans;
    1033                 :          0 :         u32 tmp;
    1034                 :          0 :         int ret;
    1035                 :            : 
    1036                 :            :         /* set maximum return packet size */
    1037   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
    1038         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
    1039                 :            : 
    1040                 :            :                 /*
    1041                 :            :                  * FIXME: This uses the number of DW's currently in the payload
    1042                 :            :                  * receive queue. This is probably not what we want here.
    1043                 :            :                  */
    1044                 :          0 :                 tmp = I915_READ(DSI_CMD_RXCTL(dsi_trans));
    1045                 :          0 :                 tmp &= NUMBER_RX_PLOAD_DW_MASK;
    1046                 :            :                 /* multiply "Number Rx Payload DW" by 4 to get max value */
    1047                 :          0 :                 tmp = tmp * 4;
    1048                 :          0 :                 dsi = intel_dsi->dsi_hosts[port]->device;
    1049                 :          0 :                 ret = mipi_dsi_set_maximum_return_packet_size(dsi, tmp);
    1050         [ #  # ]:          0 :                 if (ret < 0)
    1051                 :          0 :                         DRM_ERROR("error setting max return pkt size%d\n", tmp);
    1052                 :            :         }
    1053                 :            : 
    1054                 :            :         /* panel power on related mipi dsi vbt sequences */
    1055                 :          0 :         intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_ON);
    1056                 :          0 :         intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay);
    1057                 :          0 :         intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET);
    1058                 :          0 :         intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP);
    1059                 :          0 :         intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON);
    1060                 :            : 
    1061                 :            :         /* ensure all panel commands dispatched before enabling transcoder */
    1062                 :          0 :         wait_for_cmds_dispatched_to_panel(encoder);
    1063                 :          0 : }
    1064                 :            : 
    1065                 :          0 : static void gen11_dsi_pre_pll_enable(struct intel_encoder *encoder,
    1066                 :            :                                      const struct intel_crtc_state *crtc_state,
    1067                 :            :                                      const struct drm_connector_state *conn_state)
    1068                 :            : {
    1069                 :            :         /* step2: enable IO power */
    1070                 :          0 :         gen11_dsi_enable_io_power(encoder);
    1071                 :            : 
    1072                 :            :         /* step3: enable DSI PLL */
    1073                 :          0 :         gen11_dsi_program_esc_clk_div(encoder, crtc_state);
    1074                 :          0 : }
    1075                 :            : 
    1076                 :          0 : static void gen11_dsi_pre_enable(struct intel_encoder *encoder,
    1077                 :            :                                  const struct intel_crtc_state *pipe_config,
    1078                 :            :                                  const struct drm_connector_state *conn_state)
    1079                 :            : {
    1080                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
    1081                 :            : 
    1082                 :            :         /* step3b */
    1083                 :          0 :         gen11_dsi_map_pll(encoder, pipe_config);
    1084                 :            : 
    1085                 :            :         /* step4: enable DSI port and DPHY */
    1086                 :          0 :         gen11_dsi_enable_port_and_phy(encoder, pipe_config);
    1087                 :            : 
    1088                 :            :         /* step5: program and powerup panel */
    1089                 :          0 :         gen11_dsi_powerup_panel(encoder);
    1090                 :            : 
    1091                 :          0 :         intel_dsc_enable(encoder, pipe_config);
    1092                 :            : 
    1093                 :            :         /* step6c: configure transcoder timings */
    1094                 :          0 :         gen11_dsi_set_transcoder_timings(encoder, pipe_config);
    1095                 :            : 
    1096                 :            :         /* step6d: enable dsi transcoder */
    1097                 :          0 :         gen11_dsi_enable_transcoder(encoder);
    1098                 :            : 
    1099                 :            :         /* step7: enable backlight */
    1100                 :          0 :         intel_panel_enable_backlight(pipe_config, conn_state);
    1101                 :          0 :         intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON);
    1102                 :          0 : }
    1103                 :            : 
    1104                 :          0 : static void gen11_dsi_disable_transcoder(struct intel_encoder *encoder)
    1105                 :            : {
    1106                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
    1107                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
    1108                 :          0 :         enum port port;
    1109                 :          0 :         enum transcoder dsi_trans;
    1110                 :          0 :         u32 tmp;
    1111                 :            : 
    1112   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
    1113         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
    1114                 :            : 
    1115                 :            :                 /* disable transcoder */
    1116                 :          0 :                 tmp = I915_READ(PIPECONF(dsi_trans));
    1117                 :          0 :                 tmp &= ~PIPECONF_ENABLE;
    1118                 :          0 :                 I915_WRITE(PIPECONF(dsi_trans), tmp);
    1119                 :            : 
    1120                 :            :                 /* wait for transcoder to be disabled */
    1121         [ #  # ]:          0 :                 if (intel_de_wait_for_clear(dev_priv, PIPECONF(dsi_trans),
    1122                 :            :                                             I965_PIPECONF_ACTIVE, 50))
    1123                 :          0 :                         DRM_ERROR("DSI trancoder not disabled\n");
    1124                 :            :         }
    1125                 :          0 : }
    1126                 :            : 
    1127                 :          0 : static void gen11_dsi_powerdown_panel(struct intel_encoder *encoder)
    1128                 :            : {
    1129                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
    1130                 :            : 
    1131                 :          0 :         intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_OFF);
    1132                 :          0 :         intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_ASSERT_RESET);
    1133                 :          0 :         intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_OFF);
    1134                 :            : 
    1135                 :            :         /* ensure cmds dispatched to panel */
    1136                 :          0 :         wait_for_cmds_dispatched_to_panel(encoder);
    1137                 :          0 : }
    1138                 :            : 
    1139                 :          0 : static void gen11_dsi_deconfigure_trancoder(struct intel_encoder *encoder)
    1140                 :            : {
    1141                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
    1142                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
    1143                 :          0 :         enum port port;
    1144                 :          0 :         enum transcoder dsi_trans;
    1145                 :          0 :         u32 tmp;
    1146                 :            : 
    1147                 :            :         /* put dsi link in ULPS */
    1148   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
    1149         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
    1150                 :          0 :                 tmp = I915_READ(DSI_LP_MSG(dsi_trans));
    1151                 :          0 :                 tmp |= LINK_ENTER_ULPS;
    1152                 :          0 :                 tmp &= ~LINK_ULPS_TYPE_LP11;
    1153                 :          0 :                 I915_WRITE(DSI_LP_MSG(dsi_trans), tmp);
    1154                 :            : 
    1155   [ #  #  #  #  :          0 :                 if (wait_for_us((I915_READ(DSI_LP_MSG(dsi_trans)) &
             #  #  #  # ]
    1156                 :            :                                 LINK_IN_ULPS),
    1157                 :            :                                 10))
    1158                 :          0 :                         DRM_ERROR("DSI link not in ULPS\n");
    1159                 :            :         }
    1160                 :            : 
    1161                 :            :         /* disable ddi function */
    1162   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
    1163         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
    1164                 :          0 :                 tmp = I915_READ(TRANS_DDI_FUNC_CTL(dsi_trans));
    1165                 :          0 :                 tmp &= ~TRANS_DDI_FUNC_ENABLE;
    1166                 :          0 :                 I915_WRITE(TRANS_DDI_FUNC_CTL(dsi_trans), tmp);
    1167                 :            :         }
    1168                 :            : 
    1169                 :            :         /* disable port sync mode if dual link */
    1170         [ #  # ]:          0 :         if (intel_dsi->dual_link) {
    1171   [ #  #  #  # ]:          0 :                 for_each_dsi_port(port, intel_dsi->ports) {
    1172         [ #  # ]:          0 :                         dsi_trans = dsi_port_to_transcoder(port);
    1173                 :          0 :                         tmp = I915_READ(TRANS_DDI_FUNC_CTL2(dsi_trans));
    1174                 :          0 :                         tmp &= ~PORT_SYNC_MODE_ENABLE;
    1175                 :          0 :                         I915_WRITE(TRANS_DDI_FUNC_CTL2(dsi_trans), tmp);
    1176                 :            :                 }
    1177                 :            :         }
    1178                 :          0 : }
    1179                 :            : 
    1180                 :          0 : static void gen11_dsi_disable_port(struct intel_encoder *encoder)
    1181                 :            : {
    1182                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
    1183                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
    1184                 :          0 :         u32 tmp;
    1185                 :          0 :         enum port port;
    1186                 :            : 
    1187                 :          0 :         gen11_dsi_ungate_clocks(encoder);
    1188   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
    1189                 :          0 :                 tmp = I915_READ(DDI_BUF_CTL(port));
    1190                 :          0 :                 tmp &= ~DDI_BUF_CTL_ENABLE;
    1191                 :          0 :                 I915_WRITE(DDI_BUF_CTL(port), tmp);
    1192                 :            : 
    1193   [ #  #  #  #  :          0 :                 if (wait_for_us((I915_READ(DDI_BUF_CTL(port)) &
             #  #  #  # ]
    1194                 :            :                                  DDI_BUF_IS_IDLE),
    1195                 :            :                                  8))
    1196                 :          0 :                         DRM_ERROR("DDI port:%c buffer not idle\n",
    1197                 :            :                                   port_name(port));
    1198                 :            :         }
    1199                 :          0 :         gen11_dsi_gate_clocks(encoder);
    1200                 :          0 : }
    1201                 :            : 
    1202                 :          0 : static void gen11_dsi_disable_io_power(struct intel_encoder *encoder)
    1203                 :            : {
    1204                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
    1205                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
    1206                 :          0 :         enum port port;
    1207                 :          0 :         u32 tmp;
    1208                 :            : 
    1209   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
    1210                 :          0 :                 intel_wakeref_t wakeref;
    1211                 :            : 
    1212                 :          0 :                 wakeref = fetch_and_zero(&intel_dsi->io_wakeref[port]);
    1213         [ #  # ]:          0 :                 intel_display_power_put(dev_priv,
    1214                 :            :                                         port == PORT_A ?
    1215                 :            :                                         POWER_DOMAIN_PORT_DDI_A_IO :
    1216                 :            :                                         POWER_DOMAIN_PORT_DDI_B_IO,
    1217                 :            :                                         wakeref);
    1218                 :            :         }
    1219                 :            : 
    1220                 :            :         /* set mode to DDI */
    1221   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
    1222                 :          0 :                 tmp = I915_READ(ICL_DSI_IO_MODECTL(port));
    1223                 :          0 :                 tmp &= ~COMBO_PHY_MODE_DSI;
    1224                 :          0 :                 I915_WRITE(ICL_DSI_IO_MODECTL(port), tmp);
    1225                 :            :         }
    1226                 :          0 : }
    1227                 :            : 
    1228                 :          0 : static void gen11_dsi_disable(struct intel_encoder *encoder,
    1229                 :            :                               const struct intel_crtc_state *old_crtc_state,
    1230                 :            :                               const struct drm_connector_state *old_conn_state)
    1231                 :            : {
    1232                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
    1233                 :            : 
    1234                 :            :         /* step1: turn off backlight */
    1235                 :          0 :         intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF);
    1236                 :          0 :         intel_panel_disable_backlight(old_conn_state);
    1237                 :            : 
    1238                 :            :         /* step2d,e: disable transcoder and wait */
    1239                 :          0 :         gen11_dsi_disable_transcoder(encoder);
    1240                 :            : 
    1241                 :            :         /* step2f,g: powerdown panel */
    1242                 :          0 :         gen11_dsi_powerdown_panel(encoder);
    1243                 :            : 
    1244                 :            :         /* step2h,i,j: deconfig trancoder */
    1245                 :          0 :         gen11_dsi_deconfigure_trancoder(encoder);
    1246                 :            : 
    1247                 :            :         /* step3: disable port */
    1248                 :          0 :         gen11_dsi_disable_port(encoder);
    1249                 :            : 
    1250                 :            :         /* step4: disable IO power */
    1251                 :          0 :         gen11_dsi_disable_io_power(encoder);
    1252                 :          0 : }
    1253                 :            : 
    1254                 :          0 : static void gen11_dsi_post_disable(struct intel_encoder *encoder,
    1255                 :            :                                    const struct intel_crtc_state *old_crtc_state,
    1256                 :            :                                    const struct drm_connector_state *old_conn_state)
    1257                 :            : {
    1258                 :          0 :         intel_crtc_vblank_off(old_crtc_state);
    1259                 :            : 
    1260                 :          0 :         intel_dsc_disable(old_crtc_state);
    1261                 :            : 
    1262                 :          0 :         skl_scaler_disable(old_crtc_state);
    1263                 :          0 : }
    1264                 :            : 
    1265                 :          0 : static enum drm_mode_status gen11_dsi_mode_valid(struct drm_connector *connector,
    1266                 :            :                                                  struct drm_display_mode *mode)
    1267                 :            : {
    1268                 :            :         /* FIXME: DSC? */
    1269                 :          0 :         return intel_dsi_mode_valid(connector, mode);
    1270                 :            : }
    1271                 :            : 
    1272                 :          0 : static void gen11_dsi_get_timings(struct intel_encoder *encoder,
    1273                 :            :                                   struct intel_crtc_state *pipe_config)
    1274                 :            : {
    1275         [ #  # ]:          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
    1276                 :          0 :         struct drm_display_mode *adjusted_mode =
    1277                 :            :                                         &pipe_config->hw.adjusted_mode;
    1278                 :            : 
    1279         [ #  # ]:          0 :         if (pipe_config->dsc.compressed_bpp) {
    1280                 :          0 :                 int div = pipe_config->dsc.compressed_bpp;
    1281         [ #  # ]:          0 :                 int mul = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
    1282                 :            : 
    1283                 :          0 :                 adjusted_mode->crtc_htotal =
    1284                 :          0 :                         DIV_ROUND_UP(adjusted_mode->crtc_htotal * mul, div);
    1285                 :          0 :                 adjusted_mode->crtc_hsync_start =
    1286                 :          0 :                         DIV_ROUND_UP(adjusted_mode->crtc_hsync_start * mul, div);
    1287                 :          0 :                 adjusted_mode->crtc_hsync_end =
    1288                 :          0 :                         DIV_ROUND_UP(adjusted_mode->crtc_hsync_end * mul, div);
    1289                 :            :         }
    1290                 :            : 
    1291         [ #  # ]:          0 :         if (intel_dsi->dual_link) {
    1292                 :          0 :                 adjusted_mode->crtc_hdisplay *= 2;
    1293         [ #  # ]:          0 :                 if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK)
    1294                 :          0 :                         adjusted_mode->crtc_hdisplay -=
    1295                 :          0 :                                                 intel_dsi->pixel_overlap;
    1296                 :          0 :                 adjusted_mode->crtc_htotal *= 2;
    1297                 :            :         }
    1298                 :          0 :         adjusted_mode->crtc_hblank_start = adjusted_mode->crtc_hdisplay;
    1299                 :          0 :         adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_htotal;
    1300                 :            : 
    1301         [ #  # ]:          0 :         if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) {
    1302         [ #  # ]:          0 :                 if (intel_dsi->dual_link) {
    1303                 :          0 :                         adjusted_mode->crtc_hsync_start *= 2;
    1304                 :          0 :                         adjusted_mode->crtc_hsync_end *= 2;
    1305                 :            :                 }
    1306                 :            :         }
    1307                 :          0 :         adjusted_mode->crtc_vblank_start = adjusted_mode->crtc_vdisplay;
    1308                 :          0 :         adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vtotal;
    1309                 :          0 : }
    1310                 :            : 
    1311                 :          0 : static void gen11_dsi_get_config(struct intel_encoder *encoder,
    1312                 :            :                                  struct intel_crtc_state *pipe_config)
    1313                 :            : {
    1314                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
    1315                 :            :         struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
    1316                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
    1317                 :            : 
    1318                 :          0 :         intel_dsc_get_config(encoder, pipe_config);
    1319                 :            : 
    1320                 :            :         /* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
    1321                 :          0 :         pipe_config->port_clock =
    1322                 :          0 :                 cnl_calc_wrpll_link(dev_priv, &pipe_config->dpll_hw_state);
    1323                 :            : 
    1324                 :          0 :         pipe_config->hw.adjusted_mode.crtc_clock = intel_dsi->pclk;
    1325         [ #  # ]:          0 :         if (intel_dsi->dual_link)
    1326                 :          0 :                 pipe_config->hw.adjusted_mode.crtc_clock *= 2;
    1327                 :            : 
    1328                 :          0 :         gen11_dsi_get_timings(encoder, pipe_config);
    1329                 :          0 :         pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI);
    1330                 :          0 :         pipe_config->pipe_bpp = bdw_get_pipemisc_bpp(crtc);
    1331                 :          0 : }
    1332                 :            : 
    1333                 :          0 : static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder,
    1334                 :            :                                         struct intel_crtc_state *crtc_state)
    1335                 :            : {
    1336         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
    1337                 :          0 :         struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
    1338         [ #  # ]:          0 :         int dsc_max_bpc = INTEL_GEN(dev_priv) >= 12 ? 12 : 10;
    1339                 :          0 :         bool use_dsc;
    1340                 :          0 :         int ret;
    1341                 :            : 
    1342                 :          0 :         use_dsc = intel_bios_get_dsc_params(encoder, crtc_state, dsc_max_bpc);
    1343         [ #  # ]:          0 :         if (!use_dsc)
    1344                 :            :                 return 0;
    1345                 :            : 
    1346         [ #  # ]:          0 :         if (crtc_state->pipe_bpp < 8 * 3)
    1347                 :            :                 return -EINVAL;
    1348                 :            : 
    1349                 :            :         /* FIXME: split only when necessary */
    1350         [ #  # ]:          0 :         if (crtc_state->dsc.slice_count > 1)
    1351                 :          0 :                 crtc_state->dsc.dsc_split = true;
    1352                 :            : 
    1353                 :          0 :         vdsc_cfg->convert_rgb = true;
    1354                 :            : 
    1355                 :          0 :         ret = intel_dsc_compute_params(encoder, crtc_state);
    1356         [ #  # ]:          0 :         if (ret)
    1357                 :            :                 return ret;
    1358                 :            : 
    1359                 :            :         /* DSI specific sanity checks on the common code */
    1360         [ #  # ]:          0 :         WARN_ON(vdsc_cfg->vbr_enable);
    1361         [ #  # ]:          0 :         WARN_ON(vdsc_cfg->simple_422);
    1362         [ #  # ]:          0 :         WARN_ON(vdsc_cfg->pic_width % vdsc_cfg->slice_width);
    1363         [ #  # ]:          0 :         WARN_ON(vdsc_cfg->slice_height < 8);
    1364         [ #  # ]:          0 :         WARN_ON(vdsc_cfg->pic_height % vdsc_cfg->slice_height);
    1365                 :            : 
    1366                 :          0 :         ret = drm_dsc_compute_rc_parameters(vdsc_cfg);
    1367         [ #  # ]:          0 :         if (ret)
    1368                 :            :                 return ret;
    1369                 :            : 
    1370                 :          0 :         crtc_state->dsc.compression_enable = true;
    1371                 :            : 
    1372                 :          0 :         return 0;
    1373                 :            : }
    1374                 :            : 
    1375                 :          0 : static int gen11_dsi_compute_config(struct intel_encoder *encoder,
    1376                 :            :                                     struct intel_crtc_state *pipe_config,
    1377                 :            :                                     struct drm_connector_state *conn_state)
    1378                 :            : {
    1379                 :          0 :         struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
    1380                 :            :                                                    base);
    1381                 :          0 :         struct intel_connector *intel_connector = intel_dsi->attached_connector;
    1382                 :          0 :         struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
    1383                 :          0 :         const struct drm_display_mode *fixed_mode =
    1384                 :            :                                         intel_connector->panel.fixed_mode;
    1385                 :          0 :         struct drm_display_mode *adjusted_mode =
    1386                 :            :                                         &pipe_config->hw.adjusted_mode;
    1387                 :            : 
    1388                 :          0 :         pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
    1389                 :          0 :         intel_fixed_panel_mode(fixed_mode, adjusted_mode);
    1390                 :          0 :         intel_pch_panel_fitting(crtc, pipe_config, conn_state->scaling_mode);
    1391                 :            : 
    1392                 :          0 :         adjusted_mode->flags = 0;
    1393                 :            : 
    1394                 :            :         /* Dual link goes to trancoder DSI'0' */
    1395         [ #  # ]:          0 :         if (intel_dsi->ports == BIT(PORT_B))
    1396                 :          0 :                 pipe_config->cpu_transcoder = TRANSCODER_DSI_1;
    1397                 :            :         else
    1398                 :          0 :                 pipe_config->cpu_transcoder = TRANSCODER_DSI_0;
    1399                 :            : 
    1400         [ #  # ]:          0 :         if (intel_dsi->pixel_format == MIPI_DSI_FMT_RGB888)
    1401                 :          0 :                 pipe_config->pipe_bpp = 24;
    1402                 :            :         else
    1403                 :          0 :                 pipe_config->pipe_bpp = 18;
    1404                 :            : 
    1405                 :          0 :         pipe_config->clock_set = true;
    1406                 :            : 
    1407         [ #  # ]:          0 :         if (gen11_dsi_dsc_compute_config(encoder, pipe_config))
    1408                 :          0 :                 DRM_DEBUG_KMS("Attempting to use DSC failed\n");
    1409                 :            : 
    1410         [ #  # ]:          0 :         pipe_config->port_clock = afe_clk(encoder, pipe_config) / 5;
    1411                 :            : 
    1412                 :          0 :         return 0;
    1413                 :            : }
    1414                 :            : 
    1415                 :          0 : static void gen11_dsi_get_power_domains(struct intel_encoder *encoder,
    1416                 :            :                                         struct intel_crtc_state *crtc_state)
    1417                 :            : {
    1418                 :          0 :         struct drm_i915_private *i915 = to_i915(encoder->base.dev);
    1419                 :            : 
    1420                 :          0 :         get_dsi_io_power_domains(i915,
    1421                 :            :                                  enc_to_intel_dsi(encoder));
    1422                 :            : 
    1423         [ #  # ]:          0 :         if (crtc_state->dsc.compression_enable)
    1424                 :          0 :                 intel_display_power_get(i915,
    1425                 :            :                                         intel_dsc_power_domain(crtc_state));
    1426                 :          0 : }
    1427                 :            : 
    1428                 :          0 : static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
    1429                 :            :                                    enum pipe *pipe)
    1430                 :            : {
    1431                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
    1432                 :          0 :         struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
    1433                 :          0 :         enum transcoder dsi_trans;
    1434                 :          0 :         intel_wakeref_t wakeref;
    1435                 :          0 :         enum port port;
    1436                 :          0 :         bool ret = false;
    1437                 :          0 :         u32 tmp;
    1438                 :            : 
    1439                 :          0 :         wakeref = intel_display_power_get_if_enabled(dev_priv,
    1440                 :            :                                                      encoder->power_domain);
    1441         [ #  # ]:          0 :         if (!wakeref)
    1442                 :            :                 return false;
    1443                 :            : 
    1444   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
    1445         [ #  # ]:          0 :                 dsi_trans = dsi_port_to_transcoder(port);
    1446                 :          0 :                 tmp = I915_READ(TRANS_DDI_FUNC_CTL(dsi_trans));
    1447   [ #  #  #  #  :          0 :                 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
                      # ]
    1448                 :          0 :                 case TRANS_DDI_EDP_INPUT_A_ON:
    1449                 :          0 :                         *pipe = PIPE_A;
    1450                 :          0 :                         break;
    1451                 :          0 :                 case TRANS_DDI_EDP_INPUT_B_ONOFF:
    1452                 :          0 :                         *pipe = PIPE_B;
    1453                 :          0 :                         break;
    1454                 :          0 :                 case TRANS_DDI_EDP_INPUT_C_ONOFF:
    1455                 :          0 :                         *pipe = PIPE_C;
    1456                 :          0 :                         break;
    1457                 :          0 :                 case TRANS_DDI_EDP_INPUT_D_ONOFF:
    1458                 :          0 :                         *pipe = PIPE_D;
    1459                 :          0 :                         break;
    1460                 :          0 :                 default:
    1461                 :          0 :                         DRM_ERROR("Invalid PIPE input\n");
    1462                 :          0 :                         goto out;
    1463                 :            :                 }
    1464                 :            : 
    1465                 :          0 :                 tmp = I915_READ(PIPECONF(dsi_trans));
    1466                 :          0 :                 ret = tmp & PIPECONF_ENABLE;
    1467                 :            :         }
    1468                 :          0 : out:
    1469                 :          0 :         intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
    1470                 :          0 :         return ret;
    1471                 :            : }
    1472                 :            : 
    1473                 :          0 : static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder)
    1474                 :            : {
    1475                 :          0 :         intel_encoder_destroy(encoder);
    1476                 :          0 : }
    1477                 :            : 
    1478                 :            : static const struct drm_encoder_funcs gen11_dsi_encoder_funcs = {
    1479                 :            :         .destroy = gen11_dsi_encoder_destroy,
    1480                 :            : };
    1481                 :            : 
    1482                 :            : static const struct drm_connector_funcs gen11_dsi_connector_funcs = {
    1483                 :            :         .late_register = intel_connector_register,
    1484                 :            :         .early_unregister = intel_connector_unregister,
    1485                 :            :         .destroy = intel_connector_destroy,
    1486                 :            :         .fill_modes = drm_helper_probe_single_connector_modes,
    1487                 :            :         .atomic_get_property = intel_digital_connector_atomic_get_property,
    1488                 :            :         .atomic_set_property = intel_digital_connector_atomic_set_property,
    1489                 :            :         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
    1490                 :            :         .atomic_duplicate_state = intel_digital_connector_duplicate_state,
    1491                 :            : };
    1492                 :            : 
    1493                 :            : static const struct drm_connector_helper_funcs gen11_dsi_connector_helper_funcs = {
    1494                 :            :         .get_modes = intel_dsi_get_modes,
    1495                 :            :         .mode_valid = gen11_dsi_mode_valid,
    1496                 :            :         .atomic_check = intel_digital_connector_atomic_check,
    1497                 :            : };
    1498                 :            : 
    1499                 :          0 : static int gen11_dsi_host_attach(struct mipi_dsi_host *host,
    1500                 :            :                                  struct mipi_dsi_device *dsi)
    1501                 :            : {
    1502                 :          0 :         return 0;
    1503                 :            : }
    1504                 :            : 
    1505                 :          0 : static int gen11_dsi_host_detach(struct mipi_dsi_host *host,
    1506                 :            :                                  struct mipi_dsi_device *dsi)
    1507                 :            : {
    1508                 :          0 :         return 0;
    1509                 :            : }
    1510                 :            : 
    1511                 :          0 : static ssize_t gen11_dsi_host_transfer(struct mipi_dsi_host *host,
    1512                 :            :                                        const struct mipi_dsi_msg *msg)
    1513                 :            : {
    1514                 :          0 :         struct intel_dsi_host *intel_dsi_host = to_intel_dsi_host(host);
    1515                 :          0 :         struct mipi_dsi_packet dsi_pkt;
    1516                 :          0 :         ssize_t ret;
    1517                 :          0 :         bool enable_lpdt = false;
    1518                 :            : 
    1519                 :          0 :         ret = mipi_dsi_create_packet(&dsi_pkt, msg);
    1520         [ #  # ]:          0 :         if (ret < 0)
    1521                 :            :                 return ret;
    1522                 :            : 
    1523         [ #  # ]:          0 :         if (msg->flags & MIPI_DSI_MSG_USE_LPM)
    1524                 :          0 :                 enable_lpdt = true;
    1525                 :            : 
    1526                 :            :         /* send packet header */
    1527                 :          0 :         ret  = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt);
    1528         [ #  # ]:          0 :         if (ret < 0)
    1529                 :            :                 return ret;
    1530                 :            : 
    1531                 :            :         /* only long packet contains payload */
    1532         [ #  # ]:          0 :         if (mipi_dsi_packet_format_is_long(msg->type)) {
    1533                 :          0 :                 ret = dsi_send_pkt_payld(intel_dsi_host, dsi_pkt);
    1534         [ #  # ]:          0 :                 if (ret < 0)
    1535                 :            :                         return ret;
    1536                 :            :         }
    1537                 :            : 
    1538                 :            :         //TODO: add payload receive code if needed
    1539                 :            : 
    1540                 :          0 :         ret = sizeof(dsi_pkt.header) + dsi_pkt.payload_length;
    1541                 :            : 
    1542                 :          0 :         return ret;
    1543                 :            : }
    1544                 :            : 
    1545                 :            : static const struct mipi_dsi_host_ops gen11_dsi_host_ops = {
    1546                 :            :         .attach = gen11_dsi_host_attach,
    1547                 :            :         .detach = gen11_dsi_host_detach,
    1548                 :            :         .transfer = gen11_dsi_host_transfer,
    1549                 :            : };
    1550                 :            : 
    1551                 :            : #define ICL_PREPARE_CNT_MAX     0x7
    1552                 :            : #define ICL_CLK_ZERO_CNT_MAX    0xf
    1553                 :            : #define ICL_TRAIL_CNT_MAX       0x7
    1554                 :            : #define ICL_TCLK_PRE_CNT_MAX    0x3
    1555                 :            : #define ICL_TCLK_POST_CNT_MAX   0x7
    1556                 :            : #define ICL_HS_ZERO_CNT_MAX     0xf
    1557                 :            : #define ICL_EXIT_ZERO_CNT_MAX   0x7
    1558                 :            : 
    1559                 :          0 : static void icl_dphy_param_init(struct intel_dsi *intel_dsi)
    1560                 :            : {
    1561                 :          0 :         struct drm_device *dev = intel_dsi->base.base.dev;
    1562                 :          0 :         struct drm_i915_private *dev_priv = to_i915(dev);
    1563                 :          0 :         struct mipi_config *mipi_config = dev_priv->vbt.dsi.config;
    1564                 :          0 :         u32 tlpx_ns;
    1565                 :          0 :         u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt;
    1566                 :          0 :         u32 ths_prepare_ns, tclk_trail_ns;
    1567                 :          0 :         u32 hs_zero_cnt;
    1568                 :          0 :         u32 tclk_pre_cnt, tclk_post_cnt;
    1569                 :            : 
    1570                 :          0 :         tlpx_ns = intel_dsi_tlpx_ns(intel_dsi);
    1571                 :            : 
    1572                 :          0 :         tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail);
    1573                 :          0 :         ths_prepare_ns = max(mipi_config->ths_prepare,
    1574                 :            :                              mipi_config->tclk_prepare);
    1575                 :            : 
    1576                 :            :         /*
    1577                 :            :          * prepare cnt in escape clocks
    1578                 :            :          * this field represents a hexadecimal value with a precision
    1579                 :            :          * of 1.2 – i.e. the most significant bit is the integer
    1580                 :            :          * and the least significant 2 bits are fraction bits.
    1581                 :            :          * so, the field can represent a range of 0.25 to 1.75
    1582                 :            :          */
    1583                 :          0 :         prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * 4, tlpx_ns);
    1584         [ #  # ]:          0 :         if (prepare_cnt > ICL_PREPARE_CNT_MAX) {
    1585                 :          0 :                 DRM_DEBUG_KMS("prepare_cnt out of range (%d)\n", prepare_cnt);
    1586                 :          0 :                 prepare_cnt = ICL_PREPARE_CNT_MAX;
    1587                 :            :         }
    1588                 :            : 
    1589                 :            :         /* clk zero count in escape clocks */
    1590                 :          0 :         clk_zero_cnt = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero -
    1591                 :            :                                     ths_prepare_ns, tlpx_ns);
    1592         [ #  # ]:          0 :         if (clk_zero_cnt > ICL_CLK_ZERO_CNT_MAX) {
    1593                 :          0 :                 DRM_DEBUG_KMS("clk_zero_cnt out of range (%d)\n", clk_zero_cnt);
    1594                 :          0 :                 clk_zero_cnt = ICL_CLK_ZERO_CNT_MAX;
    1595                 :            :         }
    1596                 :            : 
    1597                 :            :         /* trail cnt in escape clocks*/
    1598                 :          0 :         trail_cnt = DIV_ROUND_UP(tclk_trail_ns, tlpx_ns);
    1599         [ #  # ]:          0 :         if (trail_cnt > ICL_TRAIL_CNT_MAX) {
    1600                 :          0 :                 DRM_DEBUG_KMS("trail_cnt out of range (%d)\n", trail_cnt);
    1601                 :          0 :                 trail_cnt = ICL_TRAIL_CNT_MAX;
    1602                 :            :         }
    1603                 :            : 
    1604                 :            :         /* tclk pre count in escape clocks */
    1605                 :          0 :         tclk_pre_cnt = DIV_ROUND_UP(mipi_config->tclk_pre, tlpx_ns);
    1606         [ #  # ]:          0 :         if (tclk_pre_cnt > ICL_TCLK_PRE_CNT_MAX) {
    1607                 :          0 :                 DRM_DEBUG_KMS("tclk_pre_cnt out of range (%d)\n", tclk_pre_cnt);
    1608                 :          0 :                 tclk_pre_cnt = ICL_TCLK_PRE_CNT_MAX;
    1609                 :            :         }
    1610                 :            : 
    1611                 :            :         /* tclk post count in escape clocks */
    1612                 :          0 :         tclk_post_cnt = DIV_ROUND_UP(mipi_config->tclk_post, tlpx_ns);
    1613         [ #  # ]:          0 :         if (tclk_post_cnt > ICL_TCLK_POST_CNT_MAX) {
    1614                 :          0 :                 DRM_DEBUG_KMS("tclk_post_cnt out of range (%d)\n", tclk_post_cnt);
    1615                 :          0 :                 tclk_post_cnt = ICL_TCLK_POST_CNT_MAX;
    1616                 :            :         }
    1617                 :            : 
    1618                 :            :         /* hs zero cnt in escape clocks */
    1619                 :          0 :         hs_zero_cnt = DIV_ROUND_UP(mipi_config->ths_prepare_hszero -
    1620                 :            :                                    ths_prepare_ns, tlpx_ns);
    1621         [ #  # ]:          0 :         if (hs_zero_cnt > ICL_HS_ZERO_CNT_MAX) {
    1622                 :          0 :                 DRM_DEBUG_KMS("hs_zero_cnt out of range (%d)\n", hs_zero_cnt);
    1623                 :          0 :                 hs_zero_cnt = ICL_HS_ZERO_CNT_MAX;
    1624                 :            :         }
    1625                 :            : 
    1626                 :            :         /* hs exit zero cnt in escape clocks */
    1627                 :          0 :         exit_zero_cnt = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns);
    1628         [ #  # ]:          0 :         if (exit_zero_cnt > ICL_EXIT_ZERO_CNT_MAX) {
    1629                 :          0 :                 DRM_DEBUG_KMS("exit_zero_cnt out of range (%d)\n", exit_zero_cnt);
    1630                 :          0 :                 exit_zero_cnt = ICL_EXIT_ZERO_CNT_MAX;
    1631                 :            :         }
    1632                 :            : 
    1633                 :            :         /* clock lane dphy timings */
    1634                 :          0 :         intel_dsi->dphy_reg = (CLK_PREPARE_OVERRIDE |
    1635                 :          0 :                                CLK_PREPARE(prepare_cnt) |
    1636                 :          0 :                                CLK_ZERO_OVERRIDE |
    1637                 :          0 :                                CLK_ZERO(clk_zero_cnt) |
    1638                 :          0 :                                CLK_PRE_OVERRIDE |
    1639                 :          0 :                                CLK_PRE(tclk_pre_cnt) |
    1640                 :          0 :                                CLK_POST_OVERRIDE |
    1641                 :          0 :                                CLK_POST(tclk_post_cnt) |
    1642                 :          0 :                                CLK_TRAIL_OVERRIDE |
    1643                 :            :                                CLK_TRAIL(trail_cnt));
    1644                 :            : 
    1645                 :            :         /* data lanes dphy timings */
    1646                 :          0 :         intel_dsi->dphy_data_lane_reg = (HS_PREPARE_OVERRIDE |
    1647                 :          0 :                                          HS_PREPARE(prepare_cnt) |
    1648                 :          0 :                                          HS_ZERO_OVERRIDE |
    1649                 :          0 :                                          HS_ZERO(hs_zero_cnt) |
    1650                 :          0 :                                          HS_TRAIL_OVERRIDE |
    1651                 :          0 :                                          HS_TRAIL(trail_cnt) |
    1652                 :          0 :                                          HS_EXIT_OVERRIDE |
    1653                 :            :                                          HS_EXIT(exit_zero_cnt));
    1654                 :            : 
    1655                 :          0 :         intel_dsi_log_params(intel_dsi);
    1656                 :          0 : }
    1657                 :            : 
    1658                 :          0 : static void icl_dsi_add_properties(struct intel_connector *connector)
    1659                 :            : {
    1660                 :          0 :         u32 allowed_scalers;
    1661                 :            : 
    1662                 :          0 :         allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT) |
    1663                 :            :                            BIT(DRM_MODE_SCALE_FULLSCREEN) |
    1664                 :            :                            BIT(DRM_MODE_SCALE_CENTER);
    1665                 :            : 
    1666                 :          0 :         drm_connector_attach_scaling_mode_property(&connector->base,
    1667                 :            :                                                    allowed_scalers);
    1668                 :            : 
    1669                 :          0 :         connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT;
    1670                 :            : 
    1671                 :          0 :         connector->base.display_info.panel_orientation =
    1672                 :          0 :                         intel_dsi_get_panel_orientation(connector);
    1673                 :          0 :         drm_connector_init_panel_orientation_property(&connector->base,
    1674                 :            :                                 connector->panel.fixed_mode->hdisplay,
    1675                 :          0 :                                 connector->panel.fixed_mode->vdisplay);
    1676                 :          0 : }
    1677                 :            : 
    1678                 :          0 : void icl_dsi_init(struct drm_i915_private *dev_priv)
    1679                 :            : {
    1680                 :          0 :         struct drm_device *dev = &dev_priv->drm;
    1681                 :          0 :         struct intel_dsi *intel_dsi;
    1682                 :          0 :         struct intel_encoder *encoder;
    1683                 :          0 :         struct intel_connector *intel_connector;
    1684                 :          0 :         struct drm_connector *connector;
    1685                 :          0 :         struct drm_display_mode *fixed_mode;
    1686                 :          0 :         enum port port;
    1687                 :            : 
    1688         [ #  # ]:          0 :         if (!intel_bios_is_dsi_present(dev_priv, &port))
    1689                 :          0 :                 return;
    1690                 :            : 
    1691                 :          0 :         intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL);
    1692         [ #  # ]:          0 :         if (!intel_dsi)
    1693                 :            :                 return;
    1694                 :            : 
    1695                 :          0 :         intel_connector = intel_connector_alloc();
    1696         [ #  # ]:          0 :         if (!intel_connector) {
    1697                 :          0 :                 kfree(intel_dsi);
    1698                 :          0 :                 return;
    1699                 :            :         }
    1700                 :            : 
    1701                 :          0 :         encoder = &intel_dsi->base;
    1702                 :          0 :         intel_dsi->attached_connector = intel_connector;
    1703                 :          0 :         connector = &intel_connector->base;
    1704                 :            : 
    1705                 :            :         /* register DSI encoder with DRM subsystem */
    1706                 :          0 :         drm_encoder_init(dev, &encoder->base, &gen11_dsi_encoder_funcs,
    1707                 :            :                          DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port));
    1708                 :            : 
    1709                 :          0 :         encoder->pre_pll_enable = gen11_dsi_pre_pll_enable;
    1710                 :          0 :         encoder->pre_enable = gen11_dsi_pre_enable;
    1711                 :          0 :         encoder->disable = gen11_dsi_disable;
    1712                 :          0 :         encoder->post_disable = gen11_dsi_post_disable;
    1713                 :          0 :         encoder->port = port;
    1714                 :          0 :         encoder->get_config = gen11_dsi_get_config;
    1715                 :          0 :         encoder->update_pipe = intel_panel_update_backlight;
    1716                 :          0 :         encoder->compute_config = gen11_dsi_compute_config;
    1717                 :          0 :         encoder->get_hw_state = gen11_dsi_get_hw_state;
    1718                 :          0 :         encoder->type = INTEL_OUTPUT_DSI;
    1719                 :          0 :         encoder->cloneable = 0;
    1720                 :          0 :         encoder->pipe_mask = ~0;
    1721                 :          0 :         encoder->power_domain = POWER_DOMAIN_PORT_DSI;
    1722                 :          0 :         encoder->get_power_domains = gen11_dsi_get_power_domains;
    1723                 :            : 
    1724                 :            :         /* register DSI connector with DRM subsystem */
    1725                 :          0 :         drm_connector_init(dev, connector, &gen11_dsi_connector_funcs,
    1726                 :            :                            DRM_MODE_CONNECTOR_DSI);
    1727                 :          0 :         drm_connector_helper_add(connector, &gen11_dsi_connector_helper_funcs);
    1728                 :          0 :         connector->display_info.subpixel_order = SubPixelHorizontalRGB;
    1729                 :          0 :         connector->interlace_allowed = false;
    1730                 :          0 :         connector->doublescan_allowed = false;
    1731                 :          0 :         intel_connector->get_hw_state = intel_connector_get_hw_state;
    1732                 :            : 
    1733                 :            :         /* attach connector to encoder */
    1734                 :          0 :         intel_connector_attach_encoder(intel_connector, encoder);
    1735                 :            : 
    1736                 :          0 :         mutex_lock(&dev->mode_config.mutex);
    1737                 :          0 :         fixed_mode = intel_panel_vbt_fixed_mode(intel_connector);
    1738                 :          0 :         mutex_unlock(&dev->mode_config.mutex);
    1739                 :            : 
    1740         [ #  # ]:          0 :         if (!fixed_mode) {
    1741                 :          0 :                 DRM_ERROR("DSI fixed mode info missing\n");
    1742                 :          0 :                 goto err;
    1743                 :            :         }
    1744                 :            : 
    1745                 :          0 :         intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
    1746                 :          0 :         intel_panel_setup_backlight(connector, INVALID_PIPE);
    1747                 :            : 
    1748         [ #  # ]:          0 :         if (dev_priv->vbt.dsi.config->dual_link)
    1749                 :          0 :                 intel_dsi->ports = BIT(PORT_A) | BIT(PORT_B);
    1750                 :            :         else
    1751                 :          0 :                 intel_dsi->ports = BIT(port);
    1752                 :            : 
    1753                 :          0 :         intel_dsi->dcs_backlight_ports = dev_priv->vbt.dsi.bl_ports;
    1754                 :          0 :         intel_dsi->dcs_cabc_ports = dev_priv->vbt.dsi.cabc_ports;
    1755                 :            : 
    1756   [ #  #  #  # ]:          0 :         for_each_dsi_port(port, intel_dsi->ports) {
    1757                 :          0 :                 struct intel_dsi_host *host;
    1758                 :            : 
    1759                 :          0 :                 host = intel_dsi_host_init(intel_dsi, &gen11_dsi_host_ops, port);
    1760         [ #  # ]:          0 :                 if (!host)
    1761                 :          0 :                         goto err;
    1762                 :            : 
    1763                 :          0 :                 intel_dsi->dsi_hosts[port] = host;
    1764                 :            :         }
    1765                 :            : 
    1766         [ #  # ]:          0 :         if (!intel_dsi_vbt_init(intel_dsi, MIPI_DSI_GENERIC_PANEL_ID)) {
    1767                 :          0 :                 DRM_DEBUG_KMS("no device found\n");
    1768                 :          0 :                 goto err;
    1769                 :            :         }
    1770                 :            : 
    1771                 :          0 :         icl_dphy_param_init(intel_dsi);
    1772                 :            : 
    1773                 :          0 :         icl_dsi_add_properties(intel_connector);
    1774                 :          0 :         return;
    1775                 :            : 
    1776                 :          0 : err:
    1777                 :          0 :         drm_encoder_cleanup(&encoder->base);
    1778                 :          0 :         kfree(intel_dsi);
    1779                 :          0 :         kfree(intel_connector);
    1780                 :            : }

Generated by: LCOV version 1.14