Hi Arun,

kernel test robot noticed the following build warnings:

[auto build test WARNING on drm-tip/drm-tip]

url:    
https://github.com/intel-lab-lkp/linux/commits/Arun-R-Murthy/drm-i915-display-dp-On-AUX-xfer-timeout-restart-freshly/20230619-163622
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
patch link:    
https://lore.kernel.org/r/20230619082715.922094-1-arun.r.murthy%40intel.com
patch subject: [Intel-gfx] [PATCHv4] drm/i915/display/dp: On AUX xfer timeout 
restart freshly
config: x86_64-rhel-8.3-rust 
(https://download.01.org/0day-ci/archive/20230619/[email protected]/config)
compiler: clang version 15.0.7 (https://github.com/llvm/llvm-project.git 
8dfdcc7b7bf66834a761bd8de445840ef68e4d1a)
reproduce: 
(https://download.01.org/0day-ci/archive/20230619/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: 
https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/i915/display/intel_dp_aux.c:284:12: warning: variable 
>> 'aux_clock_divider' is uninitialized when used here [-Wuninitialized]
                                                 aux_clock_divider);
                                                 ^~~~~~~~~~~~~~~~~
   drivers/gpu/drm/i915/display/intel_dp_aux.c:222:23: note: initialize the 
variable 'aux_clock_divider' to silence this warning
           u32 aux_clock_divider;
                                ^
                                 = 0
   1 warning generated.


vim +/aux_clock_divider +284 drivers/gpu/drm/i915/display/intel_dp_aux.c

   209  
   210  static int
   211  intel_dp_aux_xfer(struct intel_dp *intel_dp,
   212                    const u8 *send, int send_bytes,
   213                    u8 *recv, int recv_size,
   214                    u32 aux_send_ctl_flags)
   215  {
   216          struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
   217          struct drm_i915_private *i915 =
   218                          to_i915(dig_port->base.base.dev);
   219          enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
   220          bool is_tc_port = intel_phy_is_tc(i915, phy);
   221          i915_reg_t ch_ctl, ch_data[5];
   222          u32 aux_clock_divider;
   223          enum intel_display_power_domain aux_domain;
   224          intel_wakeref_t aux_wakeref;
   225          intel_wakeref_t pps_wakeref;
   226          int i, ret, recv_bytes;
   227          int try, clock = 0;
   228          u32 status;
   229          u32 send_ctl;
   230          bool vdd;
   231  
   232          ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp);
   233          for (i = 0; i < ARRAY_SIZE(ch_data); i++)
   234                  ch_data[i] = intel_dp->aux_ch_data_reg(intel_dp, i);
   235  
   236          if (is_tc_port) {
   237                  intel_tc_port_lock(dig_port);
   238                  /*
   239                   * Abort transfers on a disconnected port as required by
   240                   * DP 1.4a link CTS 4.2.1.5, also avoiding the long AUX
   241                   * timeouts that would otherwise happen.
   242                   * TODO: abort the transfer on non-TC ports as well.
   243                   */
   244                  if (!intel_tc_port_connected_locked(&dig_port->base)) {
   245                          ret = -ENXIO;
   246                          goto out_unlock;
   247                  }
   248          }
   249  
   250          aux_domain = intel_aux_power_domain(dig_port);
   251  
   252          aux_wakeref = intel_display_power_get(i915, aux_domain);
   253          pps_wakeref = intel_pps_lock(intel_dp);
   254  
   255          /*
   256           * We will be called with VDD already enabled for dpcd/edid/oui 
reads.
   257           * In such cases we want to leave VDD enabled and it's up to 
upper layers
   258           * to turn it off. But for eg. i2c-dev access we need to turn 
it on/off
   259           * ourselves.
   260           */
   261          vdd = intel_pps_vdd_on_unlocked(intel_dp);
   262  
   263          /*
   264           * dp aux is extremely sensitive to irq latency, hence request 
the
   265           * lowest possible wakeup latency and so prevent the cpu from 
going into
   266           * deep sleep states.
   267           */
   268          cpu_latency_qos_update_request(&intel_dp->pm_qos, 0);
   269  
   270          intel_pps_check_power_unlocked(intel_dp);
   271  
   272          /*
   273           * FIXME PSR should be disabled here to prevent
   274           * it using the same AUX CH simultaneously
   275           */
   276  
   277          /* Only 5 data registers! */
   278          if (drm_WARN_ON(&i915->drm, send_bytes > 20 || recv_size > 20)) 
{
   279                  ret = -E2BIG;
   280                  goto out;
   281          }
   282          send_ctl = intel_dp->get_aux_send_ctl(intel_dp,
   283                                                send_bytes,
 > 284                                                aux_clock_divider);
   285          send_ctl |= aux_send_ctl_flags;
   286  
   287          while ((aux_clock_divider = 
intel_dp->get_aux_clock_divider(intel_dp, clock++))) {
   288                  /* Re-visit : Must try at least 3 times according to DP 
spec */
   289                  for (try = 0; try < 5; try++) {
   290                          /* Try to wait for any previous AUX channel 
activity */
   291                          status = intel_dp_aux_wait_done(intel_dp);
   292                          /* just trace the final value */
   293                          trace_i915_reg_rw(false, ch_ctl, status, 
sizeof(status), true);
   294  
   295                          if (status & DP_AUX_CH_CTL_SEND_BUSY) {
   296                                  drm_WARN(&i915->drm, 1,
   297                                           "%s: not started, previous Tx 
still in process (status 0x%08x)\n",
   298                                           intel_dp->aux.name, status);
   299                                  intel_dp->aux_busy_last_status = status;
   300                                  if (try > 3) {
   301                                          ret = -EBUSY;
   302                                          goto out;
   303                                  } else
   304                                          continue;
   305                          }
   306  
   307                          /* Load the send data into the aux channel data 
registers */
   308                          for (i = 0; i < send_bytes; i += 4)
   309                                  intel_de_write(i915, ch_data[i >> 2],
   310                                                 intel_dp_aux_pack(send + 
i,
   311                                                                   
send_bytes - i));
   312  
   313                          /* Send the command and wait for it to complete 
*/
   314                          intel_de_write(i915, ch_ctl, send_ctl);
   315  
   316                          /* TODO: if typeC then 4.2ms else 800us. For 
DG2 add 1.5ms for both cases */
   317                          status = intel_dp_aux_wait_done(intel_dp);
   318  
   319                          /* Clear done status and any errors */
   320                          intel_de_write(i915, ch_ctl,
   321                                         status | DP_AUX_CH_CTL_DONE |
   322                                         DP_AUX_CH_CTL_TIME_OUT_ERROR |
   323                                         DP_AUX_CH_CTL_RECEIVE_ERROR);
   324  
   325                          /*
   326                           * DP CTS 1.2 Core Rev 1.1, 4.2.1.1 & 4.2.1.2
   327                           *   400us delay required for errors and 
timeouts
   328                           *   Timeout errors from the HW already meet 
this
   329                           *   requirement so skip to next iteration
   330                           */
   331                          if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR |
   332                                                  
DP_AUX_CH_CTL_SEND_BUSY))
   333                                  continue;
   334  
   335                          if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) {
   336                                  usleep_range(400, 500);
   337                                  continue;
   338                          }
   339                          if (status & DP_AUX_CH_CTL_DONE)
   340                                  goto done;
   341                  }
   342          }
   343  
   344          if ((status & DP_AUX_CH_CTL_DONE) == 0) {
   345                  drm_err(&i915->drm, "%s: not done (status 0x%08x)\n",
   346                          intel_dp->aux.name, status);
   347                  ret = -EBUSY;
   348                  goto out;
   349          }
   350  
   351  done:
   352          /*
   353           * Check for timeout or receive error. Timeouts occur when the 
sink is
   354           * not connected.
   355           */
   356          if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) {
   357                  drm_err(&i915->drm, "%s: receive error (status 
0x%08x)\n",
   358                          intel_dp->aux.name, status);
   359                  ret = -EIO;
   360                  goto out;
   361          }
   362  
   363          /*
   364           * Timeouts occur when the device isn't connected, so they're 
"normal"
   365           * -- don't fill the kernel log with these
   366           */
   367          if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) {
   368                  drm_dbg_kms(&i915->drm, "%s: timeout (status 0x%08x)\n",
   369                              intel_dp->aux.name, status);
   370                  ret = -ETIMEDOUT;
   371                  goto out;
   372          }
   373  
   374          /* Unload any bytes sent back from the other side */
   375          recv_bytes = REG_FIELD_GET(DP_AUX_CH_CTL_MESSAGE_SIZE_MASK, 
status);
   376  
   377          /*
   378           * By BSpec: "Message sizes of 0 or >20 are not allowed."
   379           * We have no idea of what happened so we return -EBUSY so
   380           * drm layer takes care for the necessary retries.
   381           */
   382          if (recv_bytes == 0 || recv_bytes > 20) {
   383                  drm_dbg_kms(&i915->drm,
   384                              "%s: Forbidden recv_bytes = %d on aux 
transaction\n",
   385                              intel_dp->aux.name, recv_bytes);
   386                  ret = -EBUSY;
   387                  goto out;
   388          }
   389  
   390          if (recv_bytes > recv_size)
   391                  recv_bytes = recv_size;
   392  
   393          for (i = 0; i < recv_bytes; i += 4)
   394                  intel_dp_aux_unpack(intel_de_read(i915, ch_data[i >> 
2]),
   395                                      recv + i, recv_bytes - i);
   396  
   397          ret = recv_bytes;
   398  out:
   399          cpu_latency_qos_update_request(&intel_dp->pm_qos, 
PM_QOS_DEFAULT_VALUE);
   400  
   401          if (vdd)
   402                  intel_pps_vdd_off_unlocked(intel_dp, false);
   403  
   404          intel_pps_unlock(intel_dp, pps_wakeref);
   405          intel_display_power_put_async(i915, aux_domain, aux_wakeref);
   406  out_unlock:
   407          if (is_tc_port)
   408                  intel_tc_port_unlock(dig_port);
   409  
   410          return ret;
   411  }
   412  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

Reply via email to