Commit bc95698959b43f451c667996ec2c22ad9336e745

Authored by Laurentiu Palcu
1 parent b58e87f04e

MLK-21249: drm/imx/hdp: do not set BT2020 colorimetry for 8bit color depth

Currently, we set the colorimetry to BT.2020 even if the color-depth is
8 bit. This is not according to HDMI specification.

This patch makes sure we follow the specs.

Signed-off-by: Laurentiu Palcu <laurentiu.palcu@nxp.com>
CC: Sandor Yu <sandor.yu@nxp.com>
Reviewed-by: Sandor Yu <sandor.yu@nxp.com>
Reviewed-by: Robert Chiras <robert.chiras@nxp.com>
(cherry picked from commit cdacfaadd5dccfdca5dd68640d8f08506f6a9114)

Showing 1 changed file with 4 additions and 0 deletions Inline Diff

drivers/gpu/drm/imx/hdp/imx-hdmi.c
1 /* 1 /*
2 * Copyright 2017-2018 NXP 2 * Copyright 2017-2018 NXP
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2 6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version. 7 * of the License, or (at your option) any later version.
8 * 8 *
9 * This program is distributed in the hope that it will be useful, 9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 */ 13 */
14 14
15 #include <linux/clk.h> 15 #include <linux/clk.h>
16 #ifdef DEBUG_FW_LOAD 16 #ifdef DEBUG_FW_LOAD
17 #include "hdmitx_firmware.h" 17 #include "hdmitx_firmware.h"
18 #endif 18 #endif
19 #include "imx-hdp.h" 19 #include "imx-hdp.h"
20 #include "imx-hdmi.h" 20 #include "imx-hdmi.h"
21 #include "API_AFE_ss28fdsoi_kiran_hdmitx.h" 21 #include "API_AFE_ss28fdsoi_kiran_hdmitx.h"
22 #include "API_AFE_t28hpc_hdmitx.h" 22 #include "API_AFE_t28hpc_hdmitx.h"
23 23
24 #define RGB_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\ 24 #define RGB_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\
25 BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB)) 25 BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB))
26 #define YCC_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\ 26 #define YCC_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\
27 BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM) |\ 27 BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM) |\
28 BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601) |\ 28 BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601) |\
29 BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601) |\ 29 BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601) |\
30 BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709) |\ 30 BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709) |\
31 BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601)) 31 BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601))
32 32
33 #define B0_SILICON_ID 0x11 33 #define B0_SILICON_ID 0x11
34 34
35 static int hdmi_avi_info_set(struct imx_hdp *hdp, 35 static int hdmi_avi_info_set(struct imx_hdp *hdp,
36 struct drm_display_mode *mode, 36 struct drm_display_mode *mode,
37 int format) 37 int format)
38 { 38 {
39 struct hdmi_avi_infoframe frame; 39 struct hdmi_avi_infoframe frame;
40 struct drm_display_info *di = &hdp->connector.display_info; 40 struct drm_display_info *di = &hdp->connector.display_info;
41 enum hdmi_extended_colorimetry ext_colorimetry; 41 enum hdmi_extended_colorimetry ext_colorimetry;
42 u32 sink_colorimetry; 42 u32 sink_colorimetry;
43 u32 allowed_colorimetry; 43 u32 allowed_colorimetry;
44 u8 buf[32]; 44 u8 buf[32];
45 int ret; 45 int ret;
46 46
47 /* Initialise info frame from DRM mode */ 47 /* Initialise info frame from DRM mode */
48 drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, true); 48 drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, true);
49 49
50 /* Set up colorimetry */ 50 /* Set up colorimetry */
51 allowed_colorimetry = format == PXL_RGB ? RGB_ALLOWED_COLORIMETRY : 51 allowed_colorimetry = format == PXL_RGB ? RGB_ALLOWED_COLORIMETRY :
52 YCC_ALLOWED_COLORIMETRY; 52 YCC_ALLOWED_COLORIMETRY;
53 53
54 if (hdp->bpc == 8)
55 allowed_colorimetry &= ~(BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |
56 BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM));
57
54 sink_colorimetry = di->hdmi.colorimetry & allowed_colorimetry; 58 sink_colorimetry = di->hdmi.colorimetry & allowed_colorimetry;
55 59
56 if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020)) 60 if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020))
57 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020; 61 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020;
58 else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM)) 62 else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM))
59 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM; 63 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM;
60 else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB)) 64 else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB))
61 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB; 65 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB;
62 else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709)) 66 else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709))
63 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; 67 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_709;
64 else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601)) 68 else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601))
65 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601; 69 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601;
66 else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601)) 70 else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601))
67 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_S_YCC_601; 71 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_S_YCC_601;
68 else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601)) 72 else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601))
69 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; 73 ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
70 else 74 else
71 ext_colorimetry = 0; 75 ext_colorimetry = 0;
72 76
73 frame.colorimetry = sink_colorimetry ? HDMI_COLORIMETRY_EXTENDED : 77 frame.colorimetry = sink_colorimetry ? HDMI_COLORIMETRY_EXTENDED :
74 HDMI_COLORIMETRY_NONE; 78 HDMI_COLORIMETRY_NONE;
75 frame.extended_colorimetry = ext_colorimetry; 79 frame.extended_colorimetry = ext_colorimetry;
76 80
77 switch (format) { 81 switch (format) {
78 case YCBCR_4_4_4: 82 case YCBCR_4_4_4:
79 frame.colorspace = HDMI_COLORSPACE_YUV444; 83 frame.colorspace = HDMI_COLORSPACE_YUV444;
80 break; 84 break;
81 case YCBCR_4_2_2: 85 case YCBCR_4_2_2:
82 frame.colorspace = HDMI_COLORSPACE_YUV422; 86 frame.colorspace = HDMI_COLORSPACE_YUV422;
83 break; 87 break;
84 case YCBCR_4_2_0: 88 case YCBCR_4_2_0:
85 frame.colorspace = HDMI_COLORSPACE_YUV420; 89 frame.colorspace = HDMI_COLORSPACE_YUV420;
86 break; 90 break;
87 default: 91 default:
88 frame.colorspace = HDMI_COLORSPACE_RGB; 92 frame.colorspace = HDMI_COLORSPACE_RGB;
89 break; 93 break;
90 } 94 }
91 95
92 ret = hdmi_avi_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1); 96 ret = hdmi_avi_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
93 if (ret < 0) { 97 if (ret < 0) {
94 DRM_ERROR("failed to pack AVI infoframe: %d\n", ret); 98 DRM_ERROR("failed to pack AVI infoframe: %d\n", ret);
95 return -1; 99 return -1;
96 } 100 }
97 101
98 buf[0] = 0; 102 buf[0] = 0;
99 return CDN_API_InfoframeSet(&hdp->state, 0, sizeof(buf), 103 return CDN_API_InfoframeSet(&hdp->state, 0, sizeof(buf),
100 buf, HDMI_INFOFRAME_TYPE_AVI); 104 buf, HDMI_INFOFRAME_TYPE_AVI);
101 105
102 } 106 }
103 107
104 static int hdmi_vendor_info_set(struct imx_hdp *hdp, 108 static int hdmi_vendor_info_set(struct imx_hdp *hdp,
105 struct drm_display_mode *mode, 109 struct drm_display_mode *mode,
106 int format) 110 int format)
107 { 111 {
108 struct hdmi_vendor_infoframe frame; 112 struct hdmi_vendor_infoframe frame;
109 u8 buf[32]; 113 u8 buf[32];
110 int ret; 114 int ret;
111 115
112 /* Initialise vendor frame from DRM mode */ 116 /* Initialise vendor frame from DRM mode */
113 ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame, mode); 117 ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame, mode);
114 if (ret < 0) { 118 if (ret < 0) {
115 DRM_DEBUG("Unable to init vendor infoframe: %d\n", ret); 119 DRM_DEBUG("Unable to init vendor infoframe: %d\n", ret);
116 return -1; 120 return -1;
117 } 121 }
118 122
119 ret = hdmi_vendor_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1); 123 ret = hdmi_vendor_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
120 if (ret < 0) { 124 if (ret < 0) {
121 DRM_DEBUG("Unable to pack vendor infoframe: %d\n", ret); 125 DRM_DEBUG("Unable to pack vendor infoframe: %d\n", ret);
122 return -1; 126 return -1;
123 } 127 }
124 128
125 buf[0] = 0; 129 buf[0] = 0;
126 return CDN_API_InfoframeSet(&hdp->state, 3, sizeof(buf), 130 return CDN_API_InfoframeSet(&hdp->state, 3, sizeof(buf),
127 buf, HDMI_INFOFRAME_TYPE_VENDOR); 131 buf, HDMI_INFOFRAME_TYPE_VENDOR);
128 132
129 } 133 }
130 134
131 static void hdmi_mode_set_vswing(state_struct *state) 135 static void hdmi_mode_set_vswing(state_struct *state)
132 { 136 {
133 GENERAL_Read_Register_response regresp[12]; 137 GENERAL_Read_Register_response regresp[12];
134 138
135 Afe_write(state, 0x41e1, 0x7c0); 139 Afe_write(state, 0x41e1, 0x7c0);
136 Afe_write(state, 0x43e1, 0x7c0); 140 Afe_write(state, 0x43e1, 0x7c0);
137 Afe_write(state, 0x45e1, 0x7c0); 141 Afe_write(state, 0x45e1, 0x7c0);
138 Afe_write(state, 0x47e1, 0x7c0); 142 Afe_write(state, 0x47e1, 0x7c0);
139 143
140 Afe_write(state, 0x404C, 0x0); 144 Afe_write(state, 0x404C, 0x0);
141 Afe_write(state, 0x424C, 0x0); 145 Afe_write(state, 0x424C, 0x0);
142 Afe_write(state, 0x444C, 0x0); 146 Afe_write(state, 0x444C, 0x0);
143 Afe_write(state, 0x464C, 0x0); 147 Afe_write(state, 0x464C, 0x0);
144 148
145 Afe_write(state, 0x4047, 0x120); 149 Afe_write(state, 0x4047, 0x120);
146 Afe_write(state, 0x4247, 0x120); 150 Afe_write(state, 0x4247, 0x120);
147 Afe_write(state, 0x4447, 0x120); 151 Afe_write(state, 0x4447, 0x120);
148 Afe_write(state, 0x4647, 0x120); 152 Afe_write(state, 0x4647, 0x120);
149 153
150 regresp[0].val = Afe_read(state, 0x41e1); 154 regresp[0].val = Afe_read(state, 0x41e1);
151 regresp[1].val = Afe_read(state, 0x43e1); 155 regresp[1].val = Afe_read(state, 0x43e1);
152 regresp[2].val = Afe_read(state, 0x45e1); 156 regresp[2].val = Afe_read(state, 0x45e1);
153 regresp[3].val = Afe_read(state, 0x47e1); 157 regresp[3].val = Afe_read(state, 0x47e1);
154 158
155 regresp[4].val = Afe_read(state, 0x404C); 159 regresp[4].val = Afe_read(state, 0x404C);
156 regresp[5].val = Afe_read(state, 0x424C); 160 regresp[5].val = Afe_read(state, 0x424C);
157 regresp[6].val = Afe_read(state, 0x444C); 161 regresp[6].val = Afe_read(state, 0x444C);
158 regresp[7].val = Afe_read(state, 0x464C); 162 regresp[7].val = Afe_read(state, 0x464C);
159 163
160 regresp[8].val = Afe_read(state, 0x4047); 164 regresp[8].val = Afe_read(state, 0x4047);
161 regresp[9].val = Afe_read(state, 0x4247); 165 regresp[9].val = Afe_read(state, 0x4247);
162 regresp[10].val = Afe_read(state, 0x4447); 166 regresp[10].val = Afe_read(state, 0x4447);
163 regresp[11].val = Afe_read(state, 0x4647); 167 regresp[11].val = Afe_read(state, 0x4647);
164 168
165 DRM_DEBUG("LANE0_TX_DIAG_TX_DRV 0x%x \n" 169 DRM_DEBUG("LANE0_TX_DIAG_TX_DRV 0x%x \n"
166 "LANE1_TX_DIAG_TX_DRV 0x%x \n" 170 "LANE1_TX_DIAG_TX_DRV 0x%x \n"
167 "LANE2_TX_DIAG_TX_DRV 0x%x \n" 171 "LANE2_TX_DIAG_TX_DRV 0x%x \n"
168 "LANE3_TX_DIAG_TX_DRV 0x%x \n" 172 "LANE3_TX_DIAG_TX_DRV 0x%x \n"
169 "Lane0_TX_TXCC_CPOST_MULT_00 0x%x \n" 173 "Lane0_TX_TXCC_CPOST_MULT_00 0x%x \n"
170 "Lane1_TX_TXCC_CPOST_MULT_00 0x%x \n" 174 "Lane1_TX_TXCC_CPOST_MULT_00 0x%x \n"
171 "Lane2_TX_TXCC_CPOST_MULT_00 0x%x \n" 175 "Lane2_TX_TXCC_CPOST_MULT_00 0x%x \n"
172 "Lane3_TX_TXCC_CPOST_MULT_00 0x%x \n" 176 "Lane3_TX_TXCC_CPOST_MULT_00 0x%x \n"
173 "Lane0_TX_TXCC_CAL_SCLR_MULT 0x%x \n" 177 "Lane0_TX_TXCC_CAL_SCLR_MULT 0x%x \n"
174 "Lane1_TX_TXCC_CAL_SCLR_MULT 0x%x \n" 178 "Lane1_TX_TXCC_CAL_SCLR_MULT 0x%x \n"
175 "Lane2_TX_TXCC_CAL_SCLR_MULT 0x%x \n" 179 "Lane2_TX_TXCC_CAL_SCLR_MULT 0x%x \n"
176 "Lane3_TX_TXCC_CAL_SCLR_MULT 0x%x \n", 180 "Lane3_TX_TXCC_CAL_SCLR_MULT 0x%x \n",
177 regresp[0].val, 181 regresp[0].val,
178 regresp[1].val, 182 regresp[1].val,
179 regresp[2].val, 183 regresp[2].val,
180 regresp[3].val, 184 regresp[3].val,
181 regresp[4].val, 185 regresp[4].val,
182 regresp[5].val, 186 regresp[5].val,
183 regresp[6].val, 187 regresp[6].val,
184 regresp[7].val, 188 regresp[7].val,
185 regresp[8].val, 189 regresp[8].val,
186 regresp[9].val, 190 regresp[9].val,
187 regresp[10].val, 191 regresp[10].val,
188 regresp[11].val 192 regresp[11].val
189 ); 193 );
190 } 194 }
191 195
192 static int hdmi_scdc_tmds_config(struct imx_hdp *hdp) 196 static int hdmi_scdc_tmds_config(struct imx_hdp *hdp)
193 { 197 {
194 struct drm_scdc *scdc = &hdp->connector.display_info.hdmi.scdc; 198 struct drm_scdc *scdc = &hdp->connector.display_info.hdmi.scdc;
195 HDMITX_TRANS_DATA data_in; 199 HDMITX_TRANS_DATA data_in;
196 HDMITX_TRANS_DATA data_out; 200 HDMITX_TRANS_DATA data_out;
197 u8 buff; 201 u8 buff;
198 int ret = 0; 202 int ret = 0;
199 203
200 if (hdp->character_freq_khz > 340000) { 204 if (hdp->character_freq_khz > 340000) {
201 /* 205 /*
202 * TMDS Character Rate above 340MHz should working in HDMI2.0 206 * TMDS Character Rate above 340MHz should working in HDMI2.0
203 * Enable scrambling and TMDS_Bit_Clock_Ratio 207 * Enable scrambling and TMDS_Bit_Clock_Ratio
204 */ 208 */
205 buff = 3; 209 buff = 3;
206 hdp->hdmi_type = HDMI_TX_MODE_HDMI_2_0; 210 hdp->hdmi_type = HDMI_TX_MODE_HDMI_2_0;
207 } else if (scdc->scrambling.low_rates) { 211 } else if (scdc->scrambling.low_rates) {
208 /* 212 /*
209 * Enable scrambling and work in HDMI2.0 when scrambling capability of sink 213 * Enable scrambling and work in HDMI2.0 when scrambling capability of sink
210 * be indicated in the HF-VSDB LTE_340Mcsc_scramble bit 214 * be indicated in the HF-VSDB LTE_340Mcsc_scramble bit
211 */ 215 */
212 buff = 1; 216 buff = 1;
213 hdp->hdmi_type = HDMI_TX_MODE_HDMI_2_0; 217 hdp->hdmi_type = HDMI_TX_MODE_HDMI_2_0;
214 } else { 218 } else {
215 /* Default work in HDMI1.4 */ 219 /* Default work in HDMI1.4 */
216 buff = 0; 220 buff = 0;
217 hdp->hdmi_type = HDMI_TX_MODE_HDMI_1_4; 221 hdp->hdmi_type = HDMI_TX_MODE_HDMI_1_4;
218 } 222 }
219 223
220 data_in.buff = &buff; 224 data_in.buff = &buff;
221 data_in.len = 1; 225 data_in.len = 1;
222 data_in.slave = 0x54; 226 data_in.slave = 0x54;
223 /* TMDS config */ 227 /* TMDS config */
224 data_in.offset = 0x20; 228 data_in.offset = 0x20;
225 229
226 /* Workaround for imx8qm A0 SOC DDC R/W failed issue */ 230 /* Workaround for imx8qm A0 SOC DDC R/W failed issue */
227 if (cpu_is_imx8qm() && (imx8_get_soc_revision() < B0_SILICON_ID)) 231 if (cpu_is_imx8qm() && (imx8_get_soc_revision() < B0_SILICON_ID))
228 pr_info("Skip DDC Write for iMX8QM A0 SOC\n"); 232 pr_info("Skip DDC Write for iMX8QM A0 SOC\n");
229 else { 233 else {
230 ret = CDN_API_HDMITX_DDC_WRITE_blocking(&hdp->state, &data_in, &data_out); 234 ret = CDN_API_HDMITX_DDC_WRITE_blocking(&hdp->state, &data_in, &data_out);
231 if (ret != CDN_OK) 235 if (ret != CDN_OK)
232 pr_warn("CDN_API_HDMITX_DDC_WRITE_blocking ret = %d\n", ret); 236 pr_warn("CDN_API_HDMITX_DDC_WRITE_blocking ret = %d\n", ret);
233 } 237 }
234 return ret; 238 return ret;
235 } 239 }
236 240
237 int hdmi_phy_init_ss28fdsoi(state_struct *state, struct drm_display_mode *mode, int format, int color_depth) 241 int hdmi_phy_init_ss28fdsoi(state_struct *state, struct drm_display_mode *mode, int format, int color_depth)
238 { 242 {
239 struct imx_hdp *hdp = state_to_imx_hdp(state); 243 struct imx_hdp *hdp = state_to_imx_hdp(state);
240 int ret; 244 int ret;
241 245
242 /* reset phy */ 246 /* reset phy */
243 imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, NULL, 0); 247 imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, NULL, 0);
244 248
245 /* Configure PHY */ 249 /* Configure PHY */
246 hdp->character_freq_khz = phy_cfg_hdp_ss28fdsoi(state, 4, mode, color_depth, format); 250 hdp->character_freq_khz = phy_cfg_hdp_ss28fdsoi(state, 4, mode, color_depth, format);
247 if (hdp->character_freq_khz == 0) { 251 if (hdp->character_freq_khz == 0) {
248 DRM_ERROR("failed to set phy pclock\n"); 252 DRM_ERROR("failed to set phy pclock\n");
249 return -EINVAL; 253 return -EINVAL;
250 } 254 }
251 255
252 imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, NULL, 1); 256 imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, NULL, 1);
253 257
254 hdmi_tx_kiran_power_configuration_seq(state, 4); 258 hdmi_tx_kiran_power_configuration_seq(state, 4);
255 259
256 /* Set the lane swapping */ 260 /* Set the lane swapping */
257 ret = CDN_API_General_Write_Register_blocking(state, ADDR_SOURCD_PHY + (LANES_CONFIG << 2), 261 ret = CDN_API_General_Write_Register_blocking(state, ADDR_SOURCD_PHY + (LANES_CONFIG << 2),
258 F_SOURCE_PHY_LANE0_SWAP(3) | F_SOURCE_PHY_LANE1_SWAP(0) | 262 F_SOURCE_PHY_LANE0_SWAP(3) | F_SOURCE_PHY_LANE1_SWAP(0) |
259 F_SOURCE_PHY_LANE2_SWAP(1) | F_SOURCE_PHY_LANE3_SWAP(2) | 263 F_SOURCE_PHY_LANE2_SWAP(1) | F_SOURCE_PHY_LANE3_SWAP(2) |
260 F_SOURCE_PHY_COMB_BYPASS(0) | F_SOURCE_PHY_20_10(1)); 264 F_SOURCE_PHY_COMB_BYPASS(0) | F_SOURCE_PHY_20_10(1));
261 DRM_INFO("CDN_API_General_Write_Register_blocking LANES_CONFIG ret = %d\n", ret); 265 DRM_INFO("CDN_API_General_Write_Register_blocking LANES_CONFIG ret = %d\n", ret);
262 266
263 return true; 267 return true;
264 } 268 }
265 269
266 void hdmi_mode_set_ss28fdsoi(state_struct *state, struct drm_display_mode *mode, int format, int color_depth, int temp) 270 void hdmi_mode_set_ss28fdsoi(state_struct *state, struct drm_display_mode *mode, int format, int color_depth, int temp)
267 { 271 {
268 struct imx_hdp *hdp = container_of(state, struct imx_hdp, state); 272 struct imx_hdp *hdp = container_of(state, struct imx_hdp, state);
269 int ret; 273 int ret;
270 274
271 /* config SCDC TMDS & HDMI type */ 275 /* config SCDC TMDS & HDMI type */
272 hdmi_scdc_tmds_config(hdp); 276 hdmi_scdc_tmds_config(hdp);
273 277
274 ret = CDN_API_HDMITX_Init_blocking(state); 278 ret = CDN_API_HDMITX_Init_blocking(state);
275 if (ret != CDN_OK) { 279 if (ret != CDN_OK) {
276 DRM_INFO("CDN_API_STATUS CDN_API_HDMITX_Init_blocking ret = %d\n", ret); 280 DRM_INFO("CDN_API_STATUS CDN_API_HDMITX_Init_blocking ret = %d\n", ret);
277 return; 281 return;
278 } 282 }
279 283
280 /* force GCP CD to 0 when bpp=24 for pass CTS 7-19 */ 284 /* force GCP CD to 0 when bpp=24 for pass CTS 7-19 */
281 if (color_depth == 8) 285 if (color_depth == 8)
282 CDN_API_HDMITX_Disable_GCP(state); 286 CDN_API_HDMITX_Disable_GCP(state);
283 287
284 /* Set HDMI TX Mode */ 288 /* Set HDMI TX Mode */
285 ret = CDN_API_HDMITX_Set_Mode_blocking(state, hdp->hdmi_type, hdp->character_freq_khz); 289 ret = CDN_API_HDMITX_Set_Mode_blocking(state, hdp->hdmi_type, hdp->character_freq_khz);
286 if (ret != CDN_OK) { 290 if (ret != CDN_OK) {
287 DRM_INFO("CDN_API_HDMITX_Set_Mode_blocking ret = %d\n", ret); 291 DRM_INFO("CDN_API_HDMITX_Set_Mode_blocking ret = %d\n", ret);
288 return; 292 return;
289 } 293 }
290 294
291 ret = hdmi_avi_info_set(hdp, mode, format); 295 ret = hdmi_avi_info_set(hdp, mode, format);
292 if (ret < 0) { 296 if (ret < 0) {
293 DRM_ERROR("hdmi avi info set ret = %d\n", ret); 297 DRM_ERROR("hdmi avi info set ret = %d\n", ret);
294 return; 298 return;
295 } 299 }
296 300
297 /* vendor info frame is enable only when HDMI1.4 4K mode */ 301 /* vendor info frame is enable only when HDMI1.4 4K mode */
298 hdmi_vendor_info_set(hdp, mode, format); 302 hdmi_vendor_info_set(hdp, mode, format);
299 303
300 ret = CDN_API_HDMITX_SetVic_blocking(state, mode, color_depth, format); 304 ret = CDN_API_HDMITX_SetVic_blocking(state, mode, color_depth, format);
301 if (ret != CDN_OK) { 305 if (ret != CDN_OK) {
302 DRM_INFO("CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret); 306 DRM_INFO("CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret);
303 return; 307 return;
304 } 308 }
305 309
306 hdmi_mode_set_vswing(state); 310 hdmi_mode_set_vswing(state);
307 } 311 }
308 312
309 int hdmi_phy_init_t28hpc(state_struct *state, struct drm_display_mode *mode, int format, int color_depth) 313 int hdmi_phy_init_t28hpc(state_struct *state, struct drm_display_mode *mode, int format, int color_depth)
310 { 314 {
311 struct imx_hdp *hdp = state_to_imx_hdp(state); 315 struct imx_hdp *hdp = state_to_imx_hdp(state);
312 int ret; 316 int ret;
313 /* 0- pixel clock from phy */ 317 /* 0- pixel clock from phy */
314 u32 pixel_clk_from_phy = 1; 318 u32 pixel_clk_from_phy = 1;
315 char echo_msg[] = "echo test"; 319 char echo_msg[] = "echo test";
316 char echo_resp[sizeof(echo_msg) + 1]; 320 char echo_resp[sizeof(echo_msg) + 1];
317 321
318 /* Parameterization done */ 322 /* Parameterization done */
319 323
320 ret = CDN_API_CheckAlive_blocking(state); 324 ret = CDN_API_CheckAlive_blocking(state);
321 if (ret != 0) { 325 if (ret != 0) {
322 DRM_ERROR("NO HDMI FW running\n"); 326 DRM_ERROR("NO HDMI FW running\n");
323 return -ENXIO; 327 return -ENXIO;
324 } 328 }
325 329
326 ret = CDN_API_General_Test_Echo_Ext_blocking(state, echo_msg, echo_resp, 330 ret = CDN_API_General_Test_Echo_Ext_blocking(state, echo_msg, echo_resp,
327 sizeof(echo_msg), 331 sizeof(echo_msg),
328 CDN_BUS_TYPE_APB); 332 CDN_BUS_TYPE_APB);
329 if (ret != 0) { 333 if (ret != 0) {
330 DRM_ERROR("HDMI mailbox access failed\n"); 334 DRM_ERROR("HDMI mailbox access failed\n");
331 return -ENXIO; 335 return -ENXIO;
332 } 336 }
333 337
334 /* Configure PHY */ 338 /* Configure PHY */
335 hdp->character_freq_khz = 339 hdp->character_freq_khz =
336 phy_cfg_hdp_t28hpc(state, 4, mode, color_depth, format, pixel_clk_from_phy); 340 phy_cfg_hdp_t28hpc(state, 4, mode, color_depth, format, pixel_clk_from_phy);
337 if (hdp->character_freq_khz == 0) { 341 if (hdp->character_freq_khz == 0) {
338 DRM_ERROR("failed to set phy pclock\n"); 342 DRM_ERROR("failed to set phy pclock\n");
339 return -EINVAL; 343 return -EINVAL;
340 } 344 }
341 345
342 hdmi_tx_t28hpc_power_config_seq(state, 4); 346 hdmi_tx_t28hpc_power_config_seq(state, 4);
343 347
344 /* Set the lane swapping */ 348 /* Set the lane swapping */
345 ret = 349 ret =
346 CDN_API_General_Write_Register_blocking(state, ADDR_SOURCD_PHY + 350 CDN_API_General_Write_Register_blocking(state, ADDR_SOURCD_PHY +
347 (LANES_CONFIG << 2), 351 (LANES_CONFIG << 2),
348 F_SOURCE_PHY_LANE0_SWAP(0) | 352 F_SOURCE_PHY_LANE0_SWAP(0) |
349 F_SOURCE_PHY_LANE1_SWAP(1) | 353 F_SOURCE_PHY_LANE1_SWAP(1) |
350 F_SOURCE_PHY_LANE2_SWAP(2) | 354 F_SOURCE_PHY_LANE2_SWAP(2) |
351 F_SOURCE_PHY_LANE3_SWAP(3) | 355 F_SOURCE_PHY_LANE3_SWAP(3) |
352 F_SOURCE_PHY_COMB_BYPASS(0) 356 F_SOURCE_PHY_COMB_BYPASS(0)
353 | F_SOURCE_PHY_20_10(1)); 357 | F_SOURCE_PHY_20_10(1));
354 DRM_INFO 358 DRM_INFO
355 ("CDN_API_General_Write_Register_blocking LANES_CONFIG ret = %d\n", 359 ("CDN_API_General_Write_Register_blocking LANES_CONFIG ret = %d\n",
356 ret); 360 ret);
357 361
358 return true; 362 return true;
359 } 363 }
360 364
361 void hdmi_phy_pix_engine_reset_t28hpc(state_struct *state) 365 void hdmi_phy_pix_engine_reset_t28hpc(state_struct *state)
362 { 366 {
363 GENERAL_Read_Register_response regresp; 367 GENERAL_Read_Register_response regresp;
364 368
365 CDN_API_General_Read_Register_blocking(state, ADDR_SOURCE_CAR + 369 CDN_API_General_Read_Register_blocking(state, ADDR_SOURCE_CAR +
366 (SOURCE_HDTX_CAR << 2), 370 (SOURCE_HDTX_CAR << 2),
367 &regresp); 371 &regresp);
368 CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR + 372 CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
369 (SOURCE_HDTX_CAR << 2), 373 (SOURCE_HDTX_CAR << 2),
370 regresp.val & 0xFD); 374 regresp.val & 0xFD);
371 CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR + 375 CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
372 (SOURCE_HDTX_CAR << 2), 376 (SOURCE_HDTX_CAR << 2),
373 regresp.val); 377 regresp.val);
374 } 378 }
375 379
376 void hdmi_mode_set_t28hpc(state_struct *state, struct drm_display_mode *mode, int format, int color_depth, int temp) 380 void hdmi_mode_set_t28hpc(state_struct *state, struct drm_display_mode *mode, int format, int color_depth, int temp)
377 { 381 {
378 struct imx_hdp *hdp = container_of(state, struct imx_hdp, state); 382 struct imx_hdp *hdp = container_of(state, struct imx_hdp, state);
379 int ret; 383 int ret;
380 384
381 /* config SCDC TMDS & HDMI type */ 385 /* config SCDC TMDS & HDMI type */
382 hdmi_scdc_tmds_config(hdp); 386 hdmi_scdc_tmds_config(hdp);
383 387
384 ret = CDN_API_HDMITX_Init_blocking(state); 388 ret = CDN_API_HDMITX_Init_blocking(state);
385 if (ret != CDN_OK) { 389 if (ret != CDN_OK) {
386 DRM_ERROR("CDN_API_STATUS CDN_API_HDMITX_Init_blocking ret = %d\n", ret); 390 DRM_ERROR("CDN_API_STATUS CDN_API_HDMITX_Init_blocking ret = %d\n", ret);
387 return; 391 return;
388 } 392 }
389 393
390 /* force GCP CD to 0 when bpp=24 for pass CTS 7-19 */ 394 /* force GCP CD to 0 when bpp=24 for pass CTS 7-19 */
391 if (color_depth == 8) 395 if (color_depth == 8)
392 CDN_API_HDMITX_Disable_GCP(state); 396 CDN_API_HDMITX_Disable_GCP(state);
393 397
394 /* Set HDMI TX Mode */ 398 /* Set HDMI TX Mode */
395 ret = CDN_API_HDMITX_Set_Mode_blocking(state, hdp->hdmi_type, hdp->character_freq_khz); 399 ret = CDN_API_HDMITX_Set_Mode_blocking(state, hdp->hdmi_type, hdp->character_freq_khz);
396 if (ret != CDN_OK) { 400 if (ret != CDN_OK) {
397 DRM_ERROR("CDN_API_HDMITX_Set_Mode_blocking ret = %d\n", ret); 401 DRM_ERROR("CDN_API_HDMITX_Set_Mode_blocking ret = %d\n", ret);
398 return; 402 return;
399 } 403 }
400 404
401 ret = hdmi_avi_info_set(hdp, mode, format); 405 ret = hdmi_avi_info_set(hdp, mode, format);
402 if (ret < 0) { 406 if (ret < 0) {
403 DRM_ERROR("hdmi avi info set ret = %d\n", ret); 407 DRM_ERROR("hdmi avi info set ret = %d\n", ret);
404 return; 408 return;
405 } 409 }
406 410
407 /* vendor info frame is enable only when HDMI1.4 4K mode */ 411 /* vendor info frame is enable only when HDMI1.4 4K mode */
408 hdmi_vendor_info_set(hdp, mode, format); 412 hdmi_vendor_info_set(hdp, mode, format);
409 413
410 ret = CDN_API_HDMITX_SetVic_blocking(state, mode, color_depth, format); 414 ret = CDN_API_HDMITX_SetVic_blocking(state, mode, color_depth, format);
411 if (ret != CDN_OK) { 415 if (ret != CDN_OK) {
412 DRM_ERROR("CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret); 416 DRM_ERROR("CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret);
413 return; 417 return;
414 } 418 }
415 419
416 hdmi_mode_set_vswing(state); 420 hdmi_mode_set_vswing(state);
417 421
418 msleep(50); 422 msleep(50);
419 } 423 }
420 424
421 #define YUV_MODE BIT(0) 425 #define YUV_MODE BIT(0)
422 426
423 bool hdmi_mode_fixup_t28hpc(state_struct *state, 427 bool hdmi_mode_fixup_t28hpc(state_struct *state,
424 const struct drm_display_mode *mode, 428 const struct drm_display_mode *mode,
425 struct drm_display_mode *adjusted_mode) 429 struct drm_display_mode *adjusted_mode)
426 { 430 {
427 struct imx_hdp *hdp = container_of(state, struct imx_hdp, state); 431 struct imx_hdp *hdp = container_of(state, struct imx_hdp, state);
428 int vic = drm_match_cea_mode(mode); 432 int vic = drm_match_cea_mode(mode);
429 struct drm_display_info *di = &hdp->connector.display_info; 433 struct drm_display_info *di = &hdp->connector.display_info;
430 u32 max_clock = di->max_tmds_clock; 434 u32 max_clock = di->max_tmds_clock;
431 435
432 hdp->bpc = 8; 436 hdp->bpc = 8;
433 hdp->format = PXL_RGB; 437 hdp->format = PXL_RGB;
434 438
435 if ((vic == VIC_MODE_97_60Hz || vic == VIC_MODE_96_50Hz)) { 439 if ((vic == VIC_MODE_97_60Hz || vic == VIC_MODE_96_50Hz)) {
436 if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36) 440 if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
437 hdp->bpc = 12; 441 hdp->bpc = 12;
438 else if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30) 442 else if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
439 hdp->bpc = 10; 443 hdp->bpc = 10;
440 444
441 if (drm_mode_is_420_only(di, mode) || 445 if (drm_mode_is_420_only(di, mode) ||
442 (drm_mode_is_420_also(di, mode) && hdp->bpc > 8)) { 446 (drm_mode_is_420_also(di, mode) && hdp->bpc > 8)) {
443 hdp->format = YCBCR_4_2_0; 447 hdp->format = YCBCR_4_2_0;
444 448
445 adjusted_mode->private_flags = YUV_MODE; 449 adjusted_mode->private_flags = YUV_MODE;
446 } else { 450 } else {
447 hdp->bpc = 8; 451 hdp->bpc = 8;
448 } 452 }
449 453
450 return true; 454 return true;
451 } 455 }
452 456
453 /* Any defined maximum tmds clock limit we must not exceed*/ 457 /* Any defined maximum tmds clock limit we must not exceed*/
454 if ((di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36) && 458 if ((di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36) &&
455 (mode->clock * 3/2 <= max_clock)) 459 (mode->clock * 3/2 <= max_clock))
456 hdp->bpc = 12; 460 hdp->bpc = 12;
457 else if ((di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30) && 461 else if ((di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30) &&
458 (mode->clock * 5/4 <= max_clock)) 462 (mode->clock * 5/4 <= max_clock))
459 hdp->bpc = 10; 463 hdp->bpc = 10;
460 464
461 /* 10-bit color depth for the following modes is not supported */ 465 /* 10-bit color depth for the following modes is not supported */
462 if ((vic == VIC_MODE_95_30Hz || vic == VIC_MODE_94_25Hz || 466 if ((vic == VIC_MODE_95_30Hz || vic == VIC_MODE_94_25Hz ||
463 vic == VIC_MODE_93_24Hz) && hdp->bpc == 10) 467 vic == VIC_MODE_93_24Hz) && hdp->bpc == 10)
464 hdp->bpc = 8; 468 hdp->bpc = 8;
465 469
466 return true; 470 return true;
467 } 471 }
468 472
469 int hdmi_get_edid_block(void *data, u8 *buf, u32 block, size_t len) 473 int hdmi_get_edid_block(void *data, u8 *buf, u32 block, size_t len)
470 { 474 {
471 HDMITX_TRANS_DATA edidResp; 475 HDMITX_TRANS_DATA edidResp;
472 state_struct *state = data; 476 state_struct *state = data;
473 CDN_API_STATUS ret = 0; 477 CDN_API_STATUS ret = 0;
474 478
475 memset(&edidResp, 0, sizeof(edidResp)); 479 memset(&edidResp, 0, sizeof(edidResp));
476 switch (block) { 480 switch (block) {
477 case 0: 481 case 0:
478 ret = CDN_API_HDMITX_READ_EDID_blocking(state, 0, 0, &edidResp); 482 ret = CDN_API_HDMITX_READ_EDID_blocking(state, 0, 0, &edidResp);
479 break; 483 break;
480 case 1: 484 case 1:
481 ret = CDN_API_HDMITX_READ_EDID_blocking(state, 0, 1, &edidResp); 485 ret = CDN_API_HDMITX_READ_EDID_blocking(state, 0, 1, &edidResp);
482 break; 486 break;
483 case 2: 487 case 2:
484 ret = CDN_API_HDMITX_READ_EDID_blocking(state, 1, 0, &edidResp); 488 ret = CDN_API_HDMITX_READ_EDID_blocking(state, 1, 0, &edidResp);
485 break; 489 break;
486 case 3: 490 case 3:
487 ret = CDN_API_HDMITX_READ_EDID_blocking(state, 1, 1, &edidResp); 491 ret = CDN_API_HDMITX_READ_EDID_blocking(state, 1, 1, &edidResp);
488 break; 492 break;
489 default: 493 default:
490 pr_warn("EDID block %x read not support\n", block); 494 pr_warn("EDID block %x read not support\n", block);
491 } 495 }
492 496
493 if (ret == CDN_OK) 497 if (ret == CDN_OK)
494 memcpy(buf, edidResp.buff, 128); 498 memcpy(buf, edidResp.buff, 128);
495 499
496 return ret; 500 return ret;
497 } 501 }
498 502
499 int hdmi_get_hpd_state(state_struct *state, u8 *hpd) 503 int hdmi_get_hpd_state(state_struct *state, u8 *hpd)
500 { 504 {
501 int ret; 505 int ret;
502 506
503 ret = CDN_API_HDMITX_GetHpdStatus_blocking(state, hpd); 507 ret = CDN_API_HDMITX_GetHpdStatus_blocking(state, hpd);
504 return ret; 508 return ret;
505 } 509 }
506 510
507 int hdmi_write_hdr_metadata(state_struct *state, 511 int hdmi_write_hdr_metadata(state_struct *state,
508 union hdmi_infoframe *hdr_infoframe) 512 union hdmi_infoframe *hdr_infoframe)
509 { 513 {
510 struct imx_hdp *hdp = container_of(state, struct imx_hdp, state); 514 struct imx_hdp *hdp = container_of(state, struct imx_hdp, state);
511 u8 buffer[40]; 515 u8 buffer[40];
512 int infoframe_size; 516 int infoframe_size;
513 517
514 infoframe_size = hdmi_infoframe_pack(hdr_infoframe, 518 infoframe_size = hdmi_infoframe_pack(hdr_infoframe,
515 buffer + 1, sizeof(buffer) - 1); 519 buffer + 1, sizeof(buffer) - 1);
516 if (infoframe_size < 0) { 520 if (infoframe_size < 0) {
517 dev_err(hdp->dev, "Wrong metadata infoframe: %d\n", 521 dev_err(hdp->dev, "Wrong metadata infoframe: %d\n",
518 infoframe_size); 522 infoframe_size);
519 return infoframe_size; 523 return infoframe_size;
520 } 524 }
521 525
522 buffer[0] = 0; 526 buffer[0] = 0;
523 infoframe_size++; 527 infoframe_size++;
524 528
525 return CDN_API_InfoframeSet(state, 2, infoframe_size, 529 return CDN_API_InfoframeSet(state, 2, infoframe_size,
526 buffer, HDMI_INFOFRAME_TYPE_DRM); 530 buffer, HDMI_INFOFRAME_TYPE_DRM);
527 } 531 }
528 532