hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
....@@ -17,6 +17,7 @@
1717 #include <drm/drm_crtc_helper.h>
1818 #include <drm/drm_dsc.h>
1919 #include <drm/drm_edid.h>
20
+#include <drm/drm_hdcp.h>
2021 #include <drm/bridge/dw_hdmi.h>
2122 #include <drm/drm_edid.h>
2223 #include <drm/drm_of.h>
....@@ -105,6 +106,8 @@
105106 #define RK3588_HDMI1_LEVEL_INT BIT(24)
106107 #define RK3588_HDMI1_INTR_CHANGE_CNT (0x7 << 21)
107108
109
+#define RK3588_GRF_VO1_CON1 0x0004
110
+#define HDCP1_P1_GPIO_IN BIT(9)
108111 #define RK3588_GRF_VO1_CON3 0x000c
109112 #define RK3588_COLOR_FORMAT_MASK 0xf
110113 #define RK3588_RGB 0
....@@ -129,6 +132,8 @@
129132 #define RK3588_HDMI0_GRANT_SW BIT(11)
130133 #define RK3588_HDMI1_GRANT_SEL BIT(12)
131134 #define RK3588_HDMI1_GRANT_SW BIT(13)
135
+#define RK3588_GRF_VO1_CON4 0x0010
136
+#define RK3588_HDMI_HDCP14_MEM_EN BIT(15)
132137 #define RK3588_GRF_VO1_CON6 0x0018
133138 #define RK3588_GRF_VO1_CON7 0x001c
134139
....@@ -197,7 +202,6 @@
197202 u8 id;
198203 bool hpd_stat;
199204 bool is_hdmi_qp;
200
- bool user_split_mode;
201205
202206 unsigned long bus_format;
203207 unsigned long output_bus_format;
....@@ -215,9 +219,9 @@
215219 struct drm_property *next_hdr_sink_data_property;
216220 struct drm_property *output_hdmi_dvi;
217221 struct drm_property *output_type_capacity;
218
- struct drm_property *user_split_mode_prop;
219222 struct drm_property *allm_capacity;
220223 struct drm_property *allm_enable;
224
+ struct drm_property *hdcp_state_property;
221225
222226 struct drm_property_blob *hdr_panel_blob_ptr;
223227 struct drm_property_blob *next_hdr_data_ptr;
....@@ -234,6 +238,7 @@
234238 u8 max_lanes;
235239 u8 add_func;
236240 u8 edid_colorimetry;
241
+ u8 hdcp_status;
237242 struct rockchip_drm_dsc_cap dsc_cap;
238243 struct next_hdr_sink_data next_hdr_data;
239244 struct dw_hdmi_link_config link_cfg;
....@@ -1592,14 +1597,6 @@
15921597 struct drm_crtc *crtc;
15931598 struct rockchip_hdmi *hdmi;
15941599
1595
- /*
1596
- * Pixel clocks we support are always < 2GHz and so fit in an
1597
- * int. We should make sure source rate does too so we don't get
1598
- * overflow when we multiply by 1000.
1599
- */
1600
- if (mode->clock > INT_MAX / 1000)
1601
- return MODE_BAD;
1602
-
16031600 if (!encoder) {
16041601 const struct drm_connector_helper_funcs *funcs;
16051602
....@@ -1615,6 +1612,21 @@
16151612 return MODE_BAD;
16161613
16171614 hdmi = to_rockchip_hdmi(encoder);
1615
+
1616
+ if (hdmi->is_hdmi_qp) {
1617
+ if (!hdmi->enable_gpio && mode->clock > 600000)
1618
+ return MODE_BAD;
1619
+
1620
+ return MODE_OK;
1621
+ }
1622
+
1623
+ /*
1624
+ * Pixel clocks we support are always < 2GHz and so fit in an
1625
+ * int. We should make sure source rate does too so we don't get
1626
+ * overflow when we multiply by 1000.
1627
+ */
1628
+ if (mode->clock > INT_MAX / 1000)
1629
+ return MODE_BAD;
16181630
16191631 /*
16201632 * If sink max TMDS clock < 340MHz, we should check the mode pixel
....@@ -1668,10 +1680,14 @@
16681680 {
16691681 struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
16701682 struct drm_crtc *crtc = encoder->crtc;
1671
- struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
1683
+ struct rockchip_crtc_state *s;
16721684
1673
- if (WARN_ON(!crtc || !crtc->state))
1685
+ if (!crtc || !crtc->state) {
1686
+ dev_info(hdmi->dev, "%s old crtc state is null\n", __func__);
16741687 return;
1688
+ }
1689
+
1690
+ s = to_rockchip_crtc_state(crtc->state);
16751691
16761692 if (crtc->state->active_changed) {
16771693 if (hdmi->plat_data->split_mode) {
....@@ -1699,8 +1715,10 @@
16991715 int mux;
17001716 int ret;
17011717
1702
- if (WARN_ON(!crtc || !crtc->state))
1718
+ if (!crtc || !crtc->state) {
1719
+ dev_info(hdmi->dev, "%s old crtc state is null\n", __func__);
17031720 return;
1721
+ }
17041722
17051723 if (hdmi->phy)
17061724 phy_set_bus_width(hdmi->phy, hdmi->phy_bus_width);
....@@ -1878,6 +1896,26 @@
18781896 regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON6, val);
18791897 }
18801898
1899
+static void rk3588_set_hdcp_status(void *data, u8 status)
1900
+{
1901
+ struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
1902
+
1903
+ hdmi->hdcp_status = status;
1904
+}
1905
+
1906
+static void rk3588_set_hdcp2_enable(void *data, bool enable)
1907
+{
1908
+ struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
1909
+ u32 val;
1910
+
1911
+ if (enable)
1912
+ val = HIWORD_UPDATE(HDCP1_P1_GPIO_IN, HDCP1_P1_GPIO_IN);
1913
+ else
1914
+ val = HIWORD_UPDATE(0, HDCP1_P1_GPIO_IN);
1915
+
1916
+ regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON1, val);
1917
+}
1918
+
18811919 static void rk3588_set_grf_cfg(void *data)
18821920 {
18831921 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
....@@ -2027,11 +2065,6 @@
20272065 else
20282066 color_depth = 8;
20292067
2030
- if (!sink_is_hdmi) {
2031
- *color_format = RK_IF_FORMAT_RGB;
2032
- color_depth = 8;
2033
- }
2034
-
20352068 *eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
20362069 if (conn_state->hdr_output_metadata) {
20372070 hdr_metadata = (struct hdr_output_metadata *)
....@@ -2080,6 +2113,11 @@
20802113
20812114 if (hdmi->is_hdmi_qp && mode.clock >= 600000)
20822115 *color_format = RK_IF_FORMAT_YCBCR420;
2116
+
2117
+ if (!sink_is_hdmi) {
2118
+ *color_format = RK_IF_FORMAT_RGB;
2119
+ color_depth = 8;
2120
+ }
20832121
20842122 if (*color_format == RK_IF_FORMAT_YCBCR422 || color_depth == 8)
20852123 tmdsclock = pixclock;
....@@ -2551,6 +2589,18 @@
25512589 }
25522590 }
25532591
2592
+static void dw_hdmi_rockchip_set_hdcp14_mem(void *data, bool enable)
2593
+{
2594
+ struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
2595
+ u32 val;
2596
+
2597
+ val = HIWORD_UPDATE(enable << 15, RK3588_HDMI_HDCP14_MEM_EN);
2598
+ if (!hdmi->id)
2599
+ regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON4, val);
2600
+ else
2601
+ regmap_write(hdmi->vo1_regmap, RK3588_GRF_VO1_CON7, val);
2602
+}
2603
+
25542604 static const struct drm_prop_enum_list color_depth_enum_list[] = {
25552605 { 0, "Automatic" }, /* Prefer highest color depth */
25562606 { 8, "24bit" },
....@@ -2597,6 +2647,7 @@
25972647 struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
25982648 struct drm_property *prop;
25992649 struct rockchip_drm_private *private = connector->dev->dev_private;
2650
+ int ret;
26002651
26012652 switch (color) {
26022653 case MEDIA_BUS_FMT_RGB101010_1X30:
....@@ -2711,30 +2762,24 @@
27112762 drm_object_attach_property(&connector->base, prop, 0);
27122763 }
27132764
2714
- prop = drm_property_create_bool(connector->dev, DRM_MODE_PROP_IMMUTABLE,
2715
- "USER_SPLIT_MODE");
2716
- if (prop) {
2717
- hdmi->user_split_mode_prop = prop;
2718
- drm_object_attach_property(&connector->base, prop,
2719
- hdmi->user_split_mode ? 1 : 0);
2720
- }
2765
+ if (hdmi->is_hdmi_qp) {
2766
+ prop = drm_property_create_bool(connector->dev, 0, "allm_capacity");
2767
+ if (prop) {
2768
+ hdmi->allm_capacity = prop;
2769
+ drm_object_attach_property(&connector->base, prop,
2770
+ !!(hdmi->add_func & SUPPORT_HDMI_ALLM));
2771
+ }
27212772
2722
- prop = drm_property_create_bool(connector->dev, 0, "allm_capacity");
2723
- if (prop) {
2724
- hdmi->allm_capacity = prop;
2725
- drm_object_attach_property(&connector->base, prop,
2726
- !!(hdmi->add_func & SUPPORT_HDMI_ALLM));
2773
+ prop = drm_property_create_enum(connector->dev, 0,
2774
+ "allm_enable",
2775
+ allm_enable_list,
2776
+ ARRAY_SIZE(allm_enable_list));
2777
+ if (prop) {
2778
+ hdmi->allm_enable = prop;
2779
+ drm_object_attach_property(&connector->base, prop, 0);
2780
+ }
2781
+ hdmi->enable_allm = allm_en;
27272782 }
2728
-
2729
- prop = drm_property_create_enum(connector->dev, 0,
2730
- "allm_enable",
2731
- allm_enable_list,
2732
- ARRAY_SIZE(allm_enable_list));
2733
- if (prop) {
2734
- hdmi->allm_enable = prop;
2735
- drm_object_attach_property(&connector->base, prop, 0);
2736
- }
2737
- hdmi->enable_allm = allm_en;
27382783
27392784 prop = drm_property_create_enum(connector->dev, 0,
27402785 "output_hdmi_dvi",
....@@ -2773,6 +2818,21 @@
27732818 drm_object_attach_property(&connector->base,
27742819 connector->colorspace_property, 0);
27752820 drm_object_attach_property(&connector->base, private->connector_id_prop, hdmi->id);
2821
+
2822
+ ret = drm_connector_attach_content_protection_property(connector, true);
2823
+ if (ret) {
2824
+ dev_err(hdmi->dev, "failed to attach content protection: %d\n", ret);
2825
+ return;
2826
+ }
2827
+
2828
+ prop = drm_property_create_range(connector->dev, 0, RK_IF_PROP_ENCRYPTED,
2829
+ RK_IF_HDCP_ENCRYPTED_NONE, RK_IF_HDCP_ENCRYPTED_LEVEL2);
2830
+ if (!prop) {
2831
+ dev_err(hdmi->dev, "create hdcp encrypted prop for hdmi%d failed\n", hdmi->id);
2832
+ return;
2833
+ }
2834
+ hdmi->hdcp_state_property = prop;
2835
+ drm_object_attach_property(&connector->base, prop, RK_IF_HDCP_ENCRYPTED_NONE);
27762836 }
27772837
27782838 static void
....@@ -2833,12 +2893,6 @@
28332893 drm_property_destroy(connector->dev,
28342894 hdmi->output_type_capacity);
28352895 hdmi->output_type_capacity = NULL;
2836
- }
2837
-
2838
- if (hdmi->user_split_mode_prop) {
2839
- drm_property_destroy(connector->dev,
2840
- hdmi->user_split_mode_prop);
2841
- hdmi->user_split_mode_prop = NULL;
28422896 }
28432897
28442898 if (hdmi->allm_capacity) {
....@@ -2913,6 +2967,8 @@
29132967 if (allm_enable != hdmi->enable_allm)
29142968 dw_hdmi_qp_set_allm_enable(hdmi->hdmi_qp, hdmi->enable_allm);
29152969 return 0;
2970
+ } else if (property == hdmi->hdcp_state_property) {
2971
+ return 0;
29162972 }
29172973
29182974 DRM_ERROR("Unknown property [PROP:%d:%s]\n",
....@@ -2982,14 +3038,19 @@
29823038 else
29833039 *val = dw_hdmi_qp_get_output_type_cap(hdmi->hdmi_qp);
29843040 return 0;
2985
- } else if (property == hdmi->user_split_mode_prop) {
2986
- *val = hdmi->user_split_mode;
2987
- return 0;
29883041 } else if (property == hdmi->allm_capacity) {
29893042 *val = !!(hdmi->add_func & SUPPORT_HDMI_ALLM);
29903043 return 0;
29913044 } else if (property == hdmi->allm_enable) {
29923045 *val = hdmi->enable_allm;
3046
+ return 0;
3047
+ } else if (property == hdmi->hdcp_state_property) {
3048
+ if (hdmi->hdcp_status & BIT(1))
3049
+ *val = RK_IF_HDCP_ENCRYPTED_LEVEL2;
3050
+ else if (hdmi->hdcp_status & BIT(0))
3051
+ *val = RK_IF_HDCP_ENCRYPTED_LEVEL1;
3052
+ else
3053
+ *val = RK_IF_HDCP_ENCRYPTED_NONE;
29933054 return 0;
29943055 }
29953056
....@@ -3376,6 +3437,7 @@
33763437 };
33773438
33783439 static const struct dw_hdmi_plat_data rk3588_hdmi_drv_data = {
3440
+ .mode_valid = dw_hdmi_rockchip_mode_valid,
33793441 .phy_data = &rk3588_hdmi_chip_data,
33803442 .qp_phy_ops = &rk3588_hdmi_phy_ops,
33813443 .phy_name = "samsung_hdptx_phy",
....@@ -3463,6 +3525,8 @@
34633525 plat_data->get_colorimetry =
34643526 dw_hdmi_rockchip_get_colorimetry;
34653527 plat_data->get_link_cfg = dw_hdmi_rockchip_get_link_cfg;
3528
+ plat_data->set_hdcp2_enable = rk3588_set_hdcp2_enable;
3529
+ plat_data->set_hdcp_status = rk3588_set_hdcp_status;
34663530 plat_data->set_grf_cfg = rk3588_set_grf_cfg;
34673531 plat_data->get_grf_color_fmt = rk3588_get_grf_color_fmt;
34683532 plat_data->convert_to_split_mode = drm_mode_convert_to_split_mode;
....@@ -3478,6 +3542,8 @@
34783542 dw_hdmi_rockchip_set_prev_bus_format;
34793543 plat_data->set_ddc_io =
34803544 dw_hdmi_rockchip_set_ddc_io;
3545
+ plat_data->set_hdcp14_mem =
3546
+ dw_hdmi_rockchip_set_hdcp14_mem;
34813547 plat_data->property_ops = &dw_hdmi_rockchip_property_ops;
34823548
34833549 secondary = rockchip_hdmi_find_by_id(dev->driver, !hdmi->id);
....@@ -3496,12 +3562,6 @@
34963562 secondary->plat_data->split_mode = true;
34973563 if (!secondary->plat_data->first_screen)
34983564 plat_data->first_screen = true;
3499
- }
3500
-
3501
- if (device_property_read_bool(dev, "user-split-mode") ||
3502
- device_property_read_bool(secondary->dev, "user-split-mode")) {
3503
- hdmi->user_split_mode = true;
3504
- secondary->user_split_mode = true;
35053565 }
35063566 }
35073567
....@@ -3675,7 +3735,20 @@
36753735 drm_encoder_cleanup(&hdmi->encoder);
36763736 }
36773737
3678
- if (plat_data->connector) {
3738
+ if (plat_data->bridge) {
3739
+ struct drm_connector *connector = NULL;
3740
+ struct list_head *connector_list =
3741
+ &plat_data->bridge->dev->mode_config.connector_list;
3742
+
3743
+ list_for_each_entry(connector, connector_list, head)
3744
+ if (drm_connector_has_possible_encoder(connector,
3745
+ &hdmi->encoder))
3746
+ break;
3747
+
3748
+ hdmi->sub_dev.connector = connector;
3749
+ hdmi->sub_dev.of_node = dev->of_node;
3750
+ rockchip_drm_register_sub_dev(&hdmi->sub_dev);
3751
+ } else if (plat_data->connector) {
36793752 hdmi->sub_dev.connector = plat_data->connector;
36803753 hdmi->sub_dev.loader_protect = dw_hdmi_rockchip_encoder_loader_protect;
36813754 if (secondary && device_property_read_bool(secondary->dev, "split-mode"))