@@ -286,6 +286,7 @@ struct zynqmp_dp_config {
286
286
* @next_bridge: The downstream bridge
287
287
* @config: IP core configuration from DTS
288
288
* @aux: aux channel
289
+ * @aux_done: Completed when we get an AUX reply or timeout
289
290
* @phy: PHY handles for DP lanes
290
291
* @num_lanes: number of enabled phy lanes
291
292
* @hpd_work: hot plug detection worker
@@ -306,6 +307,7 @@ struct zynqmp_dp {
306
307
struct drm_bridge bridge ;
307
308
struct work_struct hpd_work ;
308
309
struct work_struct hpd_irq_work ;
310
+ struct completion aux_done ;
309
311
struct mutex lock ;
310
312
311
313
struct drm_bridge * next_bridge ;
@@ -942,12 +944,15 @@ static int zynqmp_dp_aux_cmd_submit(struct zynqmp_dp *dp, u32 cmd, u16 addr,
942
944
u8 * buf , u8 bytes , u8 * reply )
943
945
{
944
946
bool is_read = (cmd & AUX_READ_BIT ) ? true : false;
947
+ unsigned long time_left ;
945
948
u32 reg , i ;
946
949
947
950
reg = zynqmp_dp_read (dp , ZYNQMP_DP_INTERRUPT_SIGNAL_STATE );
948
951
if (reg & ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REQUEST )
949
952
return - EBUSY ;
950
953
954
+ reinit_completion (& dp -> aux_done );
955
+
951
956
zynqmp_dp_write (dp , ZYNQMP_DP_AUX_ADDRESS , addr );
952
957
if (!is_read )
953
958
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,
962
967
zynqmp_dp_write (dp , ZYNQMP_DP_AUX_COMMAND , reg );
963
968
964
969
/* 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 ;
969
974
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 ;
976
978
977
979
reg = zynqmp_dp_read (dp , ZYNQMP_DP_AUX_REPLY_CODE );
978
980
if (reply )
@@ -1056,6 +1058,9 @@ static int zynqmp_dp_aux_init(struct zynqmp_dp *dp)
1056
1058
(w << ZYNQMP_DP_AUX_CLK_DIVIDER_AUX_FILTER_SHIFT ) |
1057
1059
(rate / (1000 * 1000 )));
1058
1060
1061
+ zynqmp_dp_write (dp , ZYNQMP_DP_INT_EN , ZYNQMP_DP_INT_REPLY_RECEIVED |
1062
+ ZYNQMP_DP_INT_REPLY_TIMEOUT );
1063
+
1059
1064
dp -> aux .name = "ZynqMP DP AUX" ;
1060
1065
dp -> aux .dev = dp -> dev ;
1061
1066
dp -> aux .drm_dev = dp -> bridge .dev ;
@@ -1073,6 +1078,9 @@ static int zynqmp_dp_aux_init(struct zynqmp_dp *dp)
1073
1078
static void zynqmp_dp_aux_cleanup (struct zynqmp_dp * dp )
1074
1079
{
1075
1080
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 );
1076
1084
}
1077
1085
1078
1086
/* -----------------------------------------------------------------------------
@@ -1730,6 +1738,12 @@ static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data)
1730
1738
if (status & ZYNQMP_DP_INT_HPD_IRQ )
1731
1739
schedule_work (& dp -> hpd_irq_work );
1732
1740
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
+
1733
1747
return IRQ_HANDLED ;
1734
1748
}
1735
1749
@@ -1753,6 +1767,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub)
1753
1767
dp -> dpsub = dpsub ;
1754
1768
dp -> status = connector_status_disconnected ;
1755
1769
mutex_init (& dp -> lock );
1770
+ init_completion (& dp -> aux_done );
1756
1771
1757
1772
INIT_WORK (& dp -> hpd_work , zynqmp_dp_hpd_work_func );
1758
1773
INIT_WORK (& dp -> hpd_irq_work , zynqmp_dp_hpd_irq_work_func );
0 commit comments