@@ -2323,15 +2323,8 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
2323
2323
hdmi -> rxsense );
2324
2324
}
2325
2325
2326
- /* -----------------------------------------------------------------------------
2327
- * DRM Connector Operations
2328
- */
2329
-
2330
- static enum drm_connector_status
2331
- dw_hdmi_connector_detect (struct drm_connector * connector , bool force )
2326
+ static enum drm_connector_status dw_hdmi_detect (struct dw_hdmi * hdmi )
2332
2327
{
2333
- struct dw_hdmi * hdmi = container_of (connector , struct dw_hdmi ,
2334
- connector );
2335
2328
enum drm_connector_status result ;
2336
2329
2337
2330
mutex_lock (& hdmi -> mutex );
@@ -2354,31 +2347,57 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
2354
2347
return result ;
2355
2348
}
2356
2349
2357
- static int dw_hdmi_connector_get_modes (struct drm_connector * connector )
2350
+ static struct edid * dw_hdmi_get_edid (struct dw_hdmi * hdmi ,
2351
+ struct drm_connector * connector )
2358
2352
{
2359
- struct dw_hdmi * hdmi = container_of (connector , struct dw_hdmi ,
2360
- connector );
2361
2353
struct edid * edid ;
2362
- int ret = 0 ;
2363
2354
2364
2355
if (!hdmi -> ddc )
2365
- return 0 ;
2356
+ return NULL ;
2366
2357
2367
2358
edid = drm_get_edid (connector , hdmi -> ddc );
2368
- if (edid ) {
2369
- dev_dbg (hdmi -> dev , "got edid: width[%d] x height[%d]\n" ,
2370
- edid -> width_cm , edid -> height_cm );
2371
-
2372
- hdmi -> sink_is_hdmi = drm_detect_hdmi_monitor (edid );
2373
- hdmi -> sink_has_audio = drm_detect_monitor_audio (edid );
2374
- drm_connector_update_edid_property (connector , edid );
2375
- cec_notifier_set_phys_addr_from_edid (hdmi -> cec_notifier , edid );
2376
- ret = drm_add_edid_modes (connector , edid );
2377
- kfree (edid );
2378
- } else {
2359
+ if (!edid ) {
2379
2360
dev_dbg (hdmi -> dev , "failed to get edid\n" );
2361
+ return NULL ;
2380
2362
}
2381
2363
2364
+ dev_dbg (hdmi -> dev , "got edid: width[%d] x height[%d]\n" ,
2365
+ edid -> width_cm , edid -> height_cm );
2366
+
2367
+ hdmi -> sink_is_hdmi = drm_detect_hdmi_monitor (edid );
2368
+ hdmi -> sink_has_audio = drm_detect_monitor_audio (edid );
2369
+
2370
+ return edid ;
2371
+ }
2372
+
2373
+ /* -----------------------------------------------------------------------------
2374
+ * DRM Connector Operations
2375
+ */
2376
+
2377
+ static enum drm_connector_status
2378
+ dw_hdmi_connector_detect (struct drm_connector * connector , bool force )
2379
+ {
2380
+ struct dw_hdmi * hdmi = container_of (connector , struct dw_hdmi ,
2381
+ connector );
2382
+ return dw_hdmi_detect (hdmi );
2383
+ }
2384
+
2385
+ static int dw_hdmi_connector_get_modes (struct drm_connector * connector )
2386
+ {
2387
+ struct dw_hdmi * hdmi = container_of (connector , struct dw_hdmi ,
2388
+ connector );
2389
+ struct edid * edid ;
2390
+ int ret ;
2391
+
2392
+ edid = dw_hdmi_get_edid (hdmi , connector );
2393
+ if (!edid )
2394
+ return 0 ;
2395
+
2396
+ drm_connector_update_edid_property (connector , edid );
2397
+ cec_notifier_set_phys_addr_from_edid (hdmi -> cec_notifier , edid );
2398
+ ret = drm_add_edid_modes (connector , edid );
2399
+ kfree (edid );
2400
+
2382
2401
return ret ;
2383
2402
}
2384
2403
@@ -2777,10 +2796,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
2777
2796
{
2778
2797
struct dw_hdmi * hdmi = bridge -> driver_private ;
2779
2798
2780
- if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR ) {
2781
- DRM_ERROR ("Fix bridge driver to make connector optional!" );
2782
- return - EINVAL ;
2783
- }
2799
+ if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR )
2800
+ return 0 ;
2784
2801
2785
2802
return dw_hdmi_connector_create (hdmi );
2786
2803
}
@@ -2860,6 +2877,21 @@ static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
2860
2877
mutex_unlock (& hdmi -> mutex );
2861
2878
}
2862
2879
2880
+ static enum drm_connector_status dw_hdmi_bridge_detect (struct drm_bridge * bridge )
2881
+ {
2882
+ struct dw_hdmi * hdmi = bridge -> driver_private ;
2883
+
2884
+ return dw_hdmi_detect (hdmi );
2885
+ }
2886
+
2887
+ static struct edid * dw_hdmi_bridge_get_edid (struct drm_bridge * bridge ,
2888
+ struct drm_connector * connector )
2889
+ {
2890
+ struct dw_hdmi * hdmi = bridge -> driver_private ;
2891
+
2892
+ return dw_hdmi_get_edid (hdmi , connector );
2893
+ }
2894
+
2863
2895
static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
2864
2896
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state ,
2865
2897
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state ,
@@ -2873,6 +2905,8 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
2873
2905
.atomic_disable = dw_hdmi_bridge_atomic_disable ,
2874
2906
.mode_set = dw_hdmi_bridge_mode_set ,
2875
2907
.mode_valid = dw_hdmi_bridge_mode_valid ,
2908
+ .detect = dw_hdmi_bridge_detect ,
2909
+ .get_edid = dw_hdmi_bridge_get_edid ,
2876
2910
};
2877
2911
2878
2912
/* -----------------------------------------------------------------------------
@@ -2988,10 +3022,18 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
2988
3022
}
2989
3023
2990
3024
if (intr_stat & HDMI_IH_PHY_STAT0_HPD ) {
3025
+ enum drm_connector_status status = phy_int_pol & HDMI_PHY_HPD
3026
+ ? connector_status_connected
3027
+ : connector_status_disconnected ;
3028
+
2991
3029
dev_dbg (hdmi -> dev , "EVENT=%s\n" ,
2992
- phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout" );
2993
- if (hdmi -> bridge .dev )
3030
+ status == connector_status_connected ?
3031
+ "plugin" : "plugout" );
3032
+
3033
+ if (hdmi -> bridge .dev ) {
2994
3034
drm_helper_hpd_irq_event (hdmi -> bridge .dev );
3035
+ drm_bridge_hpd_notify (& hdmi -> bridge , status );
3036
+ }
2995
3037
}
2996
3038
2997
3039
hdmi_writeb (hdmi , intr_stat , HDMI_IH_PHY_STAT0 );
@@ -3337,6 +3379,8 @@ __dw_hdmi_probe(struct platform_device *pdev,
3337
3379
3338
3380
hdmi -> bridge .driver_private = hdmi ;
3339
3381
hdmi -> bridge .funcs = & dw_hdmi_bridge_funcs ;
3382
+ hdmi -> bridge .ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
3383
+ | DRM_BRIDGE_OP_HPD ;
3340
3384
#ifdef CONFIG_OF
3341
3385
hdmi -> bridge .of_node = pdev -> dev .of_node ;
3342
3386
#endif
0 commit comments