ath79/mikrotik: use routerbootpart partitions
[oweals/openwrt.git] / target / linux / layerscape / patches-5.4 / 805-display-0028-drm-imx-hdp-handle-the-various-deep-color-settings.patch
1 From 1a8c7e6db6898ea62820bdd4fc9ef70b04ea528a Mon Sep 17 00:00:00 2001
2 From: Laurentiu Palcu <laurentiu.palcu@nxp.com>
3 Date: Thu, 7 Nov 2019 15:23:41 +0200
4 Subject: [PATCH] drm/imx/hdp: handle the various deep-color settings
5
6 iMX8MQ has the ability to handle color depths up to 12bpc. This patch adds
7 support for higher color depths for various modes.
8
9 Signed-off-by: Laurentiu Palcu <laurentiu.palcu@nxp.com>
10 ---
11  drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 132 ++++++++++++++----------
12  1 file changed, 75 insertions(+), 57 deletions(-)
13
14 --- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
15 +++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
16 @@ -67,58 +67,20 @@ static void hdmi_lanes_config(struct cdn
17         cdns_mhdp_reg_write(mhdp, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping);
18  }
19  
20 -#define RGB_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\
21 -                                BIT(HDMI_EXTENDED_COLORIMETRY_OPRGB))
22 -#define YCC_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\
23 -                                BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM) |\
24 -                                BIT(HDMI_EXTENDED_COLORIMETRY_OPYCC_601) |\
25 -                                BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601) |\
26 -                                BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709) |\
27 -                                BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601))
28  static int hdmi_avi_info_set(struct cdns_mhdp_device *mhdp,
29 -                               struct drm_display_mode *mode)
30 +                            struct drm_display_mode *mode)
31  {
32         struct hdmi_avi_infoframe frame;
33 -#if 0
34 -       struct drm_display_info *di = &mhdp->connector.base.display_info;
35 -       enum hdmi_extended_colorimetry ext_col;
36 -       u32 sink_col, allowed_col;
37 -#endif
38         int format = mhdp->video_info.color_fmt;
39 +       struct drm_connector_state *conn_state = mhdp->connector.base.state;
40 +       struct drm_display_mode *adj_mode;
41 +       enum hdmi_quantization_range qr;
42         u8 buf[32];
43         int ret;
44  
45         /* Initialise info frame from DRM mode */
46 -       drm_hdmi_avi_infoframe_from_display_mode(&frame, &mhdp->connector.base, mode);
47 -
48 -#if 0 //TODO to DCSS
49 -       /* Set up colorimetry */
50 -       allowed_col = format == PXL_RGB ? RGB_ALLOWED_COLORIMETRY :
51 -                                                 YCC_ALLOWED_COLORIMETRY;
52 -
53 -       sink_col = di->hdmi.colorimetry & allowed_col;
54 -
55 -       if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020))
56 -               ext_col = HDMI_EXTENDED_COLORIMETRY_BT2020;
57 -       else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM))
58 -               ext_col = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM;
59 -       else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_OPRGB))
60 -               ext_col = HDMI_EXTENDED_COLORIMETRY_OPRGB;
61 -       else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709))
62 -               ext_col = HDMI_EXTENDED_COLORIMETRY_XV_YCC_709;
63 -       else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_OPYCC_601))
64 -               ext_col = HDMI_EXTENDED_COLORIMETRY_OPYCC_601;
65 -       else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601))
66 -               ext_col = HDMI_EXTENDED_COLORIMETRY_S_YCC_601;
67 -       else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601))
68 -               ext_col = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
69 -       else
70 -               ext_col = 0;
71 -
72 -       frame.colorimetry = sink_col ? HDMI_COLORIMETRY_EXTENDED :
73 -                                         HDMI_COLORIMETRY_NONE;
74 -       frame.extended_colorimetry = ext_col;
75 -#endif
76 +       drm_hdmi_avi_infoframe_from_display_mode(&frame, &mhdp->connector.base,
77 +                                                mode);
78  
79         switch (format) {
80         case YCBCR_4_4_4:
81 @@ -135,6 +97,19 @@ static int hdmi_avi_info_set(struct cdns
82                 break;
83         }
84  
85 +       drm_hdmi_avi_infoframe_colorspace(&frame, conn_state);
86 +
87 +       adj_mode = &mhdp->bridge.base.encoder->crtc->state->adjusted_mode;
88 +
89 +       qr = drm_default_rgb_quant_range(adj_mode);
90 +
91 +       drm_hdmi_avi_infoframe_quant_range(&frame, &mhdp->connector.base,
92 +                                          adj_mode, qr);
93 +
94 +       ret = hdmi_avi_infoframe_check(&frame);
95 +       if (WARN_ON(ret))
96 +               return false;
97 +
98         ret = hdmi_avi_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
99         if (ret < 0) {
100                 DRM_ERROR("failed to pack AVI infoframe: %d\n", ret);
101 @@ -404,19 +379,6 @@ static void cdns_hdmi_bridge_mode_set(st
102         struct drm_display_info *display_info = &mhdp->connector.base.display_info;
103         struct video_info *video = &mhdp->video_info;
104  
105 -       switch (display_info->bpc) {
106 -       case 10:
107 -               video->color_depth = 10;
108 -               break;
109 -       case 6:
110 -               video->color_depth = 6;
111 -               break;
112 -       default:
113 -               video->color_depth = 8;
114 -               break;
115 -       }
116 -
117 -       video->color_fmt = PXL_RGB;
118         video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
119         video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
120  
121 @@ -428,10 +390,66 @@ static void cdns_hdmi_bridge_mode_set(st
122         mutex_unlock(&mhdp->lock);
123  }
124  
125 +bool cdns_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
126 +                                const struct drm_display_mode *mode,
127 +                                struct drm_display_mode *adjusted_mode)
128 +{
129 +       struct cdns_mhdp_device *mhdp = bridge->driver_private;
130 +       struct drm_display_info *di = &mhdp->connector.base.display_info;
131 +       struct video_info *video = &mhdp->video_info;
132 +       int vic = drm_match_cea_mode(mode);
133 +
134 +       video->color_depth = 8;
135 +       video->color_fmt = PXL_RGB;
136 +
137 +       /* for all other platforms, other than imx8mq */
138 +       if (strncmp("imx8mq-hdmi", mhdp->plat_data->plat_name, 11)) {
139 +               if (di->bpc == 10 || di->bpc == 6)
140 +                       video->color_depth = di->bpc;
141 +
142 +               return true;
143 +       }
144 +
145 +       /* imx8mq */
146 +       if (vic == 97 || vic == 96) {
147 +               if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
148 +                       video->color_depth = 12;
149 +               else if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
150 +                       video->color_depth = 10;
151 +
152 +               if (drm_mode_is_420_only(di, mode) ||
153 +                   (drm_mode_is_420_also(di, mode) &&
154 +                    video->color_depth > 8)) {
155 +                       video->color_fmt = YCBCR_4_2_0;
156 +
157 +                       adjusted_mode->private_flags = 1;
158 +                       return true;
159 +               }
160 +
161 +               video->color_depth = 8;
162 +               return true;
163 +       }
164 +
165 +       /* Any defined maximum tmds clock limit we must not exceed*/
166 +       if ((di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36) &&
167 +           (mode->clock * 3 / 2 <= di->max_tmds_clock))
168 +               video->color_depth = 12;
169 +       else if ((di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30) &&
170 +                (mode->clock * 5 / 4 <= di->max_tmds_clock))
171 +               video->color_depth = 10;
172 +
173 +       /* 10-bit color depth for the following modes is not supported */
174 +       if ((vic == 95 || vic == 94 || vic == 93) && video->color_depth == 10)
175 +               video->color_depth = 8;
176 +
177 +       return true;
178 +}
179 +
180  static const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = {
181         .attach = cdns_hdmi_bridge_attach,
182         .mode_set = cdns_hdmi_bridge_mode_set,
183         .mode_valid = cdns_hdmi_bridge_mode_valid,
184 +       .mode_fixup = cdns_hdmi_bridge_mode_fixup,
185  };
186  
187  static void hotplug_work_func(struct work_struct *work)