@@ -286,6 +286,7 @@ struct zynqmp_dp_config {
286286 * @next_bridge: The downstream bridge
287287 * @config: IP core configuration from DTS
288288 * @aux: aux channel
289+ * @aux_done: Completed when we get an AUX reply or timeout
289290 * @phy: PHY handles for DP lanes
290291 * @num_lanes: number of enabled phy lanes
291292 * @hpd_work: hot plug detection worker
@@ -306,6 +307,7 @@ struct zynqmp_dp {
306307 struct drm_bridge bridge ;
307308 struct work_struct hpd_work ;
308309 struct work_struct hpd_irq_work ;
310+ struct completion aux_done ;
309311 struct mutex lock ;
310312
311313 struct drm_bridge * next_bridge ;
@@ -942,12 +944,15 @@ static int zynqmp_dp_aux_cmd_submit(struct zynqmp_dp *dp, u32 cmd, u16 addr,
942944 u8 * buf , u8 bytes , u8 * reply )
943945{
944946 bool is_read = (cmd & AUX_READ_BIT ) ? true : false;
947+ unsigned long time_left ;
945948 u32 reg , i ;
946949
947950 reg = zynqmp_dp_read (dp , ZYNQMP_DP_INTERRUPT_SIGNAL_STATE );
948951 if (reg & ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REQUEST )
949952 return - EBUSY ;
950953
954+ reinit_completion (& dp -> aux_done );
955+
951956 zynqmp_dp_write (dp , ZYNQMP_DP_AUX_ADDRESS , addr );
952957 if (!is_read )
953958 for (i = 0 ; i < bytes ; i ++ )
@@ -962,17 +967,14 @@ static int zynqmp_dp_aux_cmd_submit(struct zynqmp_dp *dp, u32 cmd, u16 addr,
962967 zynqmp_dp_write (dp , ZYNQMP_DP_AUX_COMMAND , reg );
963968
964969 /* Wait for reply to be delivered upto 2ms */
965- for ( i = 0 ; ; i ++ ) {
966- reg = zynqmp_dp_read ( dp , ZYNQMP_DP_INTERRUPT_SIGNAL_STATE );
967- if (reg & ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REPLY )
968- break ;
970+ time_left = wait_for_completion_timeout ( & dp -> aux_done ,
971+ msecs_to_jiffies ( 2 ) );
972+ if (! time_left )
973+ return - ETIMEDOUT ;
969974
970- if (reg & ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REPLY_TIMEOUT ||
971- i == 2 )
972- return - ETIMEDOUT ;
973-
974- usleep_range (1000 , 1100 );
975- }
975+ reg = zynqmp_dp_read (dp , ZYNQMP_DP_INTERRUPT_SIGNAL_STATE );
976+ if (reg & ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REPLY_TIMEOUT )
977+ return - ETIMEDOUT ;
976978
977979 reg = zynqmp_dp_read (dp , ZYNQMP_DP_AUX_REPLY_CODE );
978980 if (reply )
@@ -1056,6 +1058,9 @@ static int zynqmp_dp_aux_init(struct zynqmp_dp *dp)
10561058 (w << ZYNQMP_DP_AUX_CLK_DIVIDER_AUX_FILTER_SHIFT ) |
10571059 (rate / (1000 * 1000 )));
10581060
1061+ zynqmp_dp_write (dp , ZYNQMP_DP_INT_EN , ZYNQMP_DP_INT_REPLY_RECEIVED |
1062+ ZYNQMP_DP_INT_REPLY_TIMEOUT );
1063+
10591064 dp -> aux .name = "ZynqMP DP AUX" ;
10601065 dp -> aux .dev = dp -> dev ;
10611066 dp -> aux .drm_dev = dp -> bridge .dev ;
@@ -1073,6 +1078,9 @@ static int zynqmp_dp_aux_init(struct zynqmp_dp *dp)
10731078static void zynqmp_dp_aux_cleanup (struct zynqmp_dp * dp )
10741079{
10751080 drm_dp_aux_unregister (& dp -> aux );
1081+
1082+ zynqmp_dp_write (dp , ZYNQMP_DP_INT_DS , ZYNQMP_DP_INT_REPLY_RECEIVED |
1083+ ZYNQMP_DP_INT_REPLY_TIMEOUT );
10761084}
10771085
10781086/* -----------------------------------------------------------------------------
@@ -1730,6 +1738,12 @@ static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data)
17301738 if (status & ZYNQMP_DP_INT_HPD_IRQ )
17311739 schedule_work (& dp -> hpd_irq_work );
17321740
1741+ if (status & ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REPLY )
1742+ complete (& dp -> aux_done );
1743+
1744+ if (status & ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REPLY_TIMEOUT )
1745+ complete (& dp -> aux_done );
1746+
17331747 return IRQ_HANDLED ;
17341748}
17351749
@@ -1753,6 +1767,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub)
17531767 dp -> dpsub = dpsub ;
17541768 dp -> status = connector_status_disconnected ;
17551769 mutex_init (& dp -> lock );
1770+ init_completion (& dp -> aux_done );
17561771
17571772 INIT_WORK (& dp -> hpd_work , zynqmp_dp_hpd_work_func );
17581773 INIT_WORK (& dp -> hpd_irq_work , zynqmp_dp_hpd_irq_work_func );
0 commit comments