@@ -412,6 +412,7 @@ struct it6505 {
412
412
* Mutex protects extcon and interrupt functions from interfering
413
413
* each other.
414
414
*/
415
+ struct mutex irq_lock ;
415
416
struct mutex extcon_lock ;
416
417
struct mutex mode_lock ; /* used to bridge_detect */
417
418
struct mutex aux_lock ; /* used to aux data transfers */
@@ -440,7 +441,7 @@ struct it6505 {
440
441
enum hdcp_state hdcp_status ;
441
442
struct delayed_work hdcp_work ;
442
443
struct work_struct hdcp_wait_ksv_list ;
443
- struct completion wait_edid_complete ;
444
+ struct completion extcon_completion ;
444
445
u8 auto_train_retry ;
445
446
bool hdcp_desired ;
446
447
bool is_repeater ;
@@ -725,28 +726,6 @@ static void it6505_calc_video_info(struct it6505 *it6505)
725
726
DRM_MODE_ARG (& it6505 -> video_info ));
726
727
}
727
728
728
- static int it6505_drm_dp_link_probe (struct drm_dp_aux * aux ,
729
- struct it6505_drm_dp_link * link )
730
- {
731
- u8 values [3 ];
732
- int err ;
733
-
734
- memset (link , 0 , sizeof (* link ));
735
-
736
- err = drm_dp_dpcd_read (aux , DP_DPCD_REV , values , sizeof (values ));
737
- if (err < 0 )
738
- return err ;
739
-
740
- link -> revision = values [0 ];
741
- link -> rate = drm_dp_bw_code_to_link_rate (values [1 ]);
742
- link -> num_lanes = values [2 ] & DP_MAX_LANE_COUNT_MASK ;
743
-
744
- if (values [2 ] & DP_ENHANCED_FRAME_CAP )
745
- link -> capabilities = DP_ENHANCED_FRAME_CAP ;
746
-
747
- return 0 ;
748
- }
749
-
750
729
static int it6505_drm_dp_link_set_power (struct drm_dp_aux * aux ,
751
730
struct it6505_drm_dp_link * link ,
752
731
u8 mode )
@@ -1456,11 +1435,19 @@ static void it6505_parse_link_capabilities(struct it6505 *it6505)
1456
1435
int bcaps ;
1457
1436
1458
1437
if (it6505 -> dpcd [0 ] == 0 ) {
1459
- it6505_aux_on (it6505 );
1460
- it6505_get_dpcd (it6505 , DP_DPCD_REV , it6505 -> dpcd ,
1461
- ARRAY_SIZE (it6505 -> dpcd ));
1438
+ dev_err (dev , "DPCD is not initialized" );
1439
+ return ;
1462
1440
}
1463
1441
1442
+ memset (link , 0 , sizeof (* link ));
1443
+
1444
+ link -> revision = it6505 -> dpcd [0 ];
1445
+ link -> rate = drm_dp_bw_code_to_link_rate (it6505 -> dpcd [1 ]);
1446
+ link -> num_lanes = it6505 -> dpcd [2 ] & DP_MAX_LANE_COUNT_MASK ;
1447
+
1448
+ if (it6505 -> dpcd [2 ] & DP_ENHANCED_FRAME_CAP )
1449
+ link -> capabilities = DP_ENHANCED_FRAME_CAP ;
1450
+
1464
1451
DRM_DEV_DEBUG_DRIVER (dev , "DPCD Rev.: %d.%d" ,
1465
1452
link -> revision >> 4 , link -> revision & 0x0F );
1466
1453
@@ -2323,19 +2310,32 @@ static int it6505_process_hpd_irq(struct it6505 *it6505)
2323
2310
static void it6505_irq_hpd (struct it6505 * it6505 )
2324
2311
{
2325
2312
struct device * dev = & it6505 -> client -> dev ;
2313
+ int dp_sink_count ;
2326
2314
2327
2315
it6505 -> hpd_state = it6505_get_sink_hpd_status (it6505 );
2328
2316
DRM_DEV_DEBUG_DRIVER (dev , "hpd change interrupt, change to %s" ,
2329
2317
it6505 -> hpd_state ? "high" : "low" );
2330
2318
2331
- if (it6505 -> bridge .dev )
2332
- drm_helper_hpd_irq_event (it6505 -> bridge .dev );
2333
- DRM_DEV_DEBUG_DRIVER (dev , "it6505->sink_count: %d" ,
2334
- it6505 -> sink_count );
2335
-
2336
2319
if (it6505 -> hpd_state ) {
2337
- wait_for_completion_timeout (& it6505 -> wait_edid_complete ,
2338
- msecs_to_jiffies (6000 ));
2320
+ wait_for_completion_timeout (& it6505 -> extcon_completion ,
2321
+ msecs_to_jiffies (1000 ));
2322
+ it6505_aux_on (it6505 );
2323
+ if (it6505 -> dpcd [0 ] == 0 ) {
2324
+ it6505_get_dpcd (it6505 , DP_DPCD_REV , it6505 -> dpcd ,
2325
+ ARRAY_SIZE (it6505 -> dpcd ));
2326
+ it6505_variable_config (it6505 );
2327
+ it6505_parse_link_capabilities (it6505 );
2328
+ }
2329
+ it6505 -> auto_train_retry = AUTO_TRAIN_RETRY ;
2330
+
2331
+ it6505_drm_dp_link_set_power (& it6505 -> aux , & it6505 -> link ,
2332
+ DP_SET_POWER_D0 );
2333
+ dp_sink_count = it6505_dpcd_read (it6505 , DP_SINK_COUNT );
2334
+ it6505 -> sink_count = DP_GET_SINK_COUNT (dp_sink_count );
2335
+
2336
+ DRM_DEV_DEBUG_DRIVER (dev , "it6505->sink_count: %d" ,
2337
+ it6505 -> sink_count );
2338
+
2339
2339
it6505_lane_termination_on (it6505 );
2340
2340
it6505_lane_power_on (it6505 );
2341
2341
@@ -2363,6 +2363,9 @@ static void it6505_irq_hpd(struct it6505 *it6505)
2363
2363
it6505_lane_off (it6505 );
2364
2364
it6505_link_reset_step_train (it6505 );
2365
2365
}
2366
+
2367
+ if (it6505 -> bridge .dev )
2368
+ drm_helper_hpd_irq_event (it6505 -> bridge .dev );
2366
2369
}
2367
2370
2368
2371
static void it6505_irq_hpd_irq (struct it6505 * it6505 )
@@ -2491,8 +2494,7 @@ static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
2491
2494
};
2492
2495
int int_status [3 ], i ;
2493
2496
2494
- msleep (100 );
2495
- mutex_lock (& it6505 -> extcon_lock );
2497
+ mutex_lock (& it6505 -> irq_lock );
2496
2498
2497
2499
if (it6505 -> enable_drv_hold || !it6505 -> powered )
2498
2500
goto unlock ;
@@ -2522,7 +2524,7 @@ static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
2522
2524
}
2523
2525
2524
2526
unlock :
2525
- mutex_unlock (& it6505 -> extcon_lock );
2527
+ mutex_unlock (& it6505 -> irq_lock );
2526
2528
2527
2529
return IRQ_HANDLED ;
2528
2530
}
@@ -2625,26 +2627,14 @@ static enum drm_connector_status it6505_detect(struct it6505 *it6505)
2625
2627
goto unlock ;
2626
2628
2627
2629
if (it6505 -> enable_drv_hold ) {
2628
- status = it6505_get_sink_hpd_status (it6505 ) ?
2629
- connector_status_connected :
2630
- connector_status_disconnected ;
2630
+ status = it6505 -> hpd_state ? connector_status_connected :
2631
+ connector_status_disconnected ;
2631
2632
goto unlock ;
2632
2633
}
2633
2634
2634
- if (it6505_get_sink_hpd_status (it6505 )) {
2635
- it6505_aux_on (it6505 );
2636
- it6505_drm_dp_link_probe (& it6505 -> aux , & it6505 -> link );
2635
+ if (it6505 -> hpd_state ) {
2637
2636
it6505_drm_dp_link_set_power (& it6505 -> aux , & it6505 -> link ,
2638
2637
DP_SET_POWER_D0 );
2639
- it6505 -> auto_train_retry = AUTO_TRAIN_RETRY ;
2640
-
2641
- if (it6505 -> dpcd [0 ] == 0 ) {
2642
- it6505_get_dpcd (it6505 , DP_DPCD_REV , it6505 -> dpcd ,
2643
- ARRAY_SIZE (it6505 -> dpcd ));
2644
- it6505_variable_config (it6505 );
2645
- it6505_parse_link_capabilities (it6505 );
2646
- }
2647
-
2648
2638
dp_sink_count = it6505_dpcd_read (it6505 , DP_SINK_COUNT );
2649
2639
it6505 -> sink_count = DP_GET_SINK_COUNT (dp_sink_count );
2650
2640
DRM_DEV_DEBUG_DRIVER (dev , "it6505->sink_count:%d branch:%d" ,
@@ -2711,9 +2701,12 @@ static void it6505_extcon_work(struct work_struct *work)
2711
2701
*/
2712
2702
if (ret )
2713
2703
it6505_poweron (it6505 );
2704
+
2705
+ complete_all (& it6505 -> extcon_completion );
2714
2706
} else {
2715
2707
DRM_DEV_DEBUG_DRIVER (dev , "start to power off" );
2716
2708
pm_runtime_put_sync (dev );
2709
+ reinit_completion (& it6505 -> extcon_completion );
2717
2710
2718
2711
drm_helper_hpd_irq_event (it6505 -> bridge .dev );
2719
2712
memset (it6505 -> dpcd , 0 , sizeof (it6505 -> dpcd ));
@@ -2871,10 +2864,7 @@ static int it6505_bridge_attach(struct drm_bridge *bridge,
2871
2864
}
2872
2865
2873
2866
/* Register aux channel */
2874
- it6505 -> aux .name = "DP-AUX" ;
2875
- it6505 -> aux .dev = dev ;
2876
2867
it6505 -> aux .drm_dev = bridge -> dev ;
2877
- it6505 -> aux .transfer = it6505_aux_transfer ;
2878
2868
2879
2869
ret = drm_dp_aux_register (& it6505 -> aux );
2880
2870
@@ -3287,6 +3277,7 @@ static int it6505_i2c_probe(struct i2c_client *client,
3287
3277
if (!it6505 )
3288
3278
return - ENOMEM ;
3289
3279
3280
+ mutex_init (& it6505 -> irq_lock );
3290
3281
mutex_init (& it6505 -> extcon_lock );
3291
3282
mutex_init (& it6505 -> mode_lock );
3292
3283
mutex_init (& it6505 -> aux_lock );
@@ -3342,7 +3333,7 @@ static int it6505_i2c_probe(struct i2c_client *client,
3342
3333
INIT_WORK (& it6505 -> link_works , it6505_link_training_work );
3343
3334
INIT_WORK (& it6505 -> hdcp_wait_ksv_list , it6505_hdcp_wait_ksv_list );
3344
3335
INIT_DELAYED_WORK (& it6505 -> hdcp_work , it6505_hdcp_work );
3345
- init_completion (& it6505 -> wait_edid_complete );
3336
+ init_completion (& it6505 -> extcon_completion );
3346
3337
memset (it6505 -> dpcd , 0 , sizeof (it6505 -> dpcd ));
3347
3338
it6505 -> powered = false;
3348
3339
it6505 -> enable_drv_hold = DEFAULT_DRV_HOLD ;
@@ -3354,6 +3345,11 @@ static int it6505_i2c_probe(struct i2c_client *client,
3354
3345
debugfs_init (it6505 );
3355
3346
pm_runtime_enable (dev );
3356
3347
3348
+ it6505 -> aux .name = "DP-AUX" ;
3349
+ it6505 -> aux .dev = dev ;
3350
+ it6505 -> aux .transfer = it6505_aux_transfer ;
3351
+ drm_dp_aux_init (& it6505 -> aux );
3352
+
3357
3353
it6505 -> bridge .funcs = & it6505_bridge_funcs ;
3358
3354
it6505 -> bridge .type = DRM_MODE_CONNECTOR_DisplayPort ;
3359
3355
it6505 -> bridge .ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
0 commit comments