42
42
#include <drm/drm_connector.h>
43
43
#include <drm/drm_crtc_helper.h>
44
44
#include <drm/drm_dp_helper.h>
45
+ #include <drm/drm_hdcp.h>
45
46
#include <drm/drm_modeset_helper_vtables.h>
46
47
#include <drm/drm_print.h>
47
48
#include <drm/drm_probe_helper.h>
48
49
49
50
#include <asm/unaligned.h>
50
51
51
52
#include "cdns-mhdp8546-core.h"
52
-
53
+ #include "cdns-mhdp8546-hdcp.h"
53
54
#include "cdns-mhdp8546-j721e.h"
54
55
55
56
static int cdns_mhdp_mailbox_read (struct cdns_mhdp_device * mhdp )
@@ -1614,10 +1615,51 @@ enum drm_mode_status cdns_mhdp_mode_valid(struct drm_connector *conn,
1614
1615
return MODE_OK ;
1615
1616
}
1616
1617
1618
+ static int cdns_mhdp_connector_atomic_check (struct drm_connector * conn ,
1619
+ struct drm_atomic_state * state )
1620
+ {
1621
+ struct cdns_mhdp_device * mhdp = connector_to_mhdp (conn );
1622
+ struct drm_connector_state * old_state , * new_state ;
1623
+ struct drm_crtc_state * crtc_state ;
1624
+ u64 old_cp , new_cp ;
1625
+
1626
+ if (!mhdp -> hdcp_supported )
1627
+ return 0 ;
1628
+
1629
+ old_state = drm_atomic_get_old_connector_state (state , conn );
1630
+ new_state = drm_atomic_get_new_connector_state (state , conn );
1631
+ old_cp = old_state -> content_protection ;
1632
+ new_cp = new_state -> content_protection ;
1633
+
1634
+ if (old_state -> hdcp_content_type != new_state -> hdcp_content_type &&
1635
+ new_cp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED ) {
1636
+ new_state -> content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED ;
1637
+ goto mode_changed ;
1638
+ }
1639
+
1640
+ if (!new_state -> crtc ) {
1641
+ if (old_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED )
1642
+ new_state -> content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED ;
1643
+ return 0 ;
1644
+ }
1645
+
1646
+ if (old_cp == new_cp ||
1647
+ (old_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
1648
+ new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED ))
1649
+ return 0 ;
1650
+
1651
+ mode_changed :
1652
+ crtc_state = drm_atomic_get_new_crtc_state (state , new_state -> crtc );
1653
+ crtc_state -> mode_changed = true;
1654
+
1655
+ return 0 ;
1656
+ }
1657
+
1617
1658
static const struct drm_connector_helper_funcs cdns_mhdp_conn_helper_funcs = {
1618
1659
.detect_ctx = cdns_mhdp_connector_detect ,
1619
1660
.get_modes = cdns_mhdp_get_modes ,
1620
1661
.mode_valid = cdns_mhdp_mode_valid ,
1662
+ .atomic_check = cdns_mhdp_connector_atomic_check ,
1621
1663
};
1622
1664
1623
1665
static const struct drm_connector_funcs cdns_mhdp_conn_funcs = {
@@ -1662,7 +1704,10 @@ static int cdns_mhdp_connector_init(struct cdns_mhdp_device *mhdp)
1662
1704
return ret ;
1663
1705
}
1664
1706
1665
- return 0 ;
1707
+ if (mhdp -> hdcp_supported )
1708
+ ret = drm_connector_attach_content_protection_property (conn , true);
1709
+
1710
+ return ret ;
1666
1711
}
1667
1712
1668
1713
static int cdns_mhdp_attach (struct drm_bridge * bridge ,
@@ -1957,6 +2002,15 @@ static void cdns_mhdp_atomic_enable(struct drm_bridge *bridge,
1957
2002
if (WARN_ON (!conn_state ))
1958
2003
goto out ;
1959
2004
2005
+ if (mhdp -> hdcp_supported &&
2006
+ mhdp -> hw_state == MHDP_HW_READY &&
2007
+ conn_state -> content_protection ==
2008
+ DRM_MODE_CONTENT_PROTECTION_DESIRED ) {
2009
+ mutex_unlock (& mhdp -> link_mutex );
2010
+ cdns_mhdp_hdcp_enable (mhdp , conn_state -> hdcp_content_type );
2011
+ mutex_lock (& mhdp -> link_mutex );
2012
+ }
2013
+
1960
2014
crtc_state = drm_atomic_get_new_crtc_state (state , conn_state -> crtc );
1961
2015
if (WARN_ON (!crtc_state ))
1962
2016
goto out ;
@@ -2000,6 +2054,9 @@ static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge,
2000
2054
2001
2055
mutex_lock (& mhdp -> link_mutex );
2002
2056
2057
+ if (mhdp -> hdcp_supported )
2058
+ cdns_mhdp_hdcp_disable (mhdp );
2059
+
2003
2060
mhdp -> bridge_enabled = false;
2004
2061
cdns_mhdp_reg_read (mhdp , CDNS_DP_FRAMER_GLOBAL_CONFIG , & resp );
2005
2062
resp &= ~CDNS_DP_FRAMER_EN ;
@@ -2288,7 +2345,6 @@ static irqreturn_t cdns_mhdp_irq_handler(int irq, void *data)
2288
2345
struct cdns_mhdp_device * mhdp = data ;
2289
2346
u32 apb_stat , sw_ev0 ;
2290
2347
bool bridge_attached ;
2291
- int ret ;
2292
2348
2293
2349
apb_stat = readl (mhdp -> regs + CDNS_APB_INT_STATUS );
2294
2350
if (!(apb_stat & CDNS_APB_INT_MASK_SW_EVENT_INT ))
@@ -2307,20 +2363,54 @@ static irqreturn_t cdns_mhdp_irq_handler(int irq, void *data)
2307
2363
spin_unlock (& mhdp -> start_lock );
2308
2364
2309
2365
if (bridge_attached && (sw_ev0 & CDNS_DPTX_HPD )) {
2310
- ret = cdns_mhdp_update_link_status (mhdp );
2311
- if (mhdp -> connector .dev ) {
2312
- if (ret < 0 )
2313
- schedule_work (& mhdp -> modeset_retry_work );
2314
- else
2315
- drm_kms_helper_hotplug_event (mhdp -> bridge .dev );
2316
- } else {
2317
- drm_bridge_hpd_notify (& mhdp -> bridge , cdns_mhdp_detect (mhdp ));
2318
- }
2366
+ schedule_work (& mhdp -> hpd_work );
2367
+ }
2368
+
2369
+ if (sw_ev0 & ~CDNS_DPTX_HPD ) {
2370
+ mhdp -> sw_events |= (sw_ev0 & ~CDNS_DPTX_HPD );
2371
+ wake_up (& mhdp -> sw_events_wq );
2319
2372
}
2320
2373
2321
2374
return IRQ_HANDLED ;
2322
2375
}
2323
2376
2377
+ u32 cdns_mhdp_wait_for_sw_event (struct cdns_mhdp_device * mhdp , u32 event )
2378
+ {
2379
+ u32 ret ;
2380
+
2381
+ ret = wait_event_timeout (mhdp -> sw_events_wq ,
2382
+ mhdp -> sw_events & event ,
2383
+ msecs_to_jiffies (500 ));
2384
+ if (!ret ) {
2385
+ dev_dbg (mhdp -> dev , "SW event 0x%x timeout\n" , event );
2386
+ goto sw_event_out ;
2387
+ }
2388
+
2389
+ ret = mhdp -> sw_events ;
2390
+ mhdp -> sw_events &= ~event ;
2391
+
2392
+ sw_event_out :
2393
+ return ret ;
2394
+ }
2395
+
2396
+ static void cdns_mhdp_hpd_work (struct work_struct * work )
2397
+ {
2398
+ struct cdns_mhdp_device * mhdp = container_of (work ,
2399
+ struct cdns_mhdp_device ,
2400
+ hpd_work );
2401
+ int ret ;
2402
+
2403
+ ret = cdns_mhdp_update_link_status (mhdp );
2404
+ if (mhdp -> connector .dev ) {
2405
+ if (ret < 0 )
2406
+ schedule_work (& mhdp -> modeset_retry_work );
2407
+ else
2408
+ drm_kms_helper_hotplug_event (mhdp -> bridge .dev );
2409
+ } else {
2410
+ drm_bridge_hpd_notify (& mhdp -> bridge , cdns_mhdp_detect (mhdp ));
2411
+ }
2412
+ }
2413
+
2324
2414
static int cdns_mhdp_probe (struct platform_device * pdev )
2325
2415
{
2326
2416
struct device * dev = & pdev -> dev ;
@@ -2356,6 +2446,15 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
2356
2446
return PTR_ERR (mhdp -> regs );
2357
2447
}
2358
2448
2449
+ mhdp -> sapb_regs = devm_platform_ioremap_resource_byname (pdev , "mhdptx-sapb" );
2450
+ if (IS_ERR (mhdp -> sapb_regs )) {
2451
+ mhdp -> hdcp_supported = false;
2452
+ dev_warn (dev ,
2453
+ "Failed to get SAPB memory resource, HDCP not supported\n" );
2454
+ } else {
2455
+ mhdp -> hdcp_supported = true;
2456
+ }
2457
+
2359
2458
mhdp -> phy = devm_of_phy_get_by_index (dev , pdev -> dev .of_node , 0 );
2360
2459
if (IS_ERR (mhdp -> phy )) {
2361
2460
dev_err (dev , "no PHY configured\n" );
@@ -2430,13 +2529,18 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
2430
2529
2431
2530
/* Initialize the work for modeset in case of link train failure */
2432
2531
INIT_WORK (& mhdp -> modeset_retry_work , cdns_mhdp_modeset_retry_fn );
2532
+ INIT_WORK (& mhdp -> hpd_work , cdns_mhdp_hpd_work );
2433
2533
2434
2534
init_waitqueue_head (& mhdp -> fw_load_wq );
2535
+ init_waitqueue_head (& mhdp -> sw_events_wq );
2435
2536
2436
2537
ret = cdns_mhdp_load_firmware (mhdp );
2437
2538
if (ret )
2438
2539
goto phy_exit ;
2439
2540
2541
+ if (mhdp -> hdcp_supported )
2542
+ cdns_mhdp_hdcp_init (mhdp );
2543
+
2440
2544
drm_bridge_add (& mhdp -> bridge );
2441
2545
2442
2546
return 0 ;
0 commit comments