@@ -69,6 +69,8 @@ static void power_off(struct drm_bridge *bridge)
69
69
}
70
70
71
71
#define AVI_IFRAME_LINE_NUMBER 1
72
+ #define SPD_IFRAME_LINE_NUMBER 1
73
+ #define VENSPEC_IFRAME_LINE_NUMBER 3
72
74
73
75
static int msm_hdmi_config_avi_infoframe (struct hdmi * hdmi ,
74
76
const u8 * buffer , size_t len )
@@ -142,6 +144,74 @@ static int msm_hdmi_config_audio_infoframe(struct hdmi *hdmi,
142
144
return 0 ;
143
145
}
144
146
147
+ static int msm_hdmi_config_spd_infoframe (struct hdmi * hdmi ,
148
+ const u8 * buffer , size_t len )
149
+ {
150
+ u32 buf [7 ] = {};
151
+ u32 val ;
152
+ int i ;
153
+
154
+ if (len != HDMI_INFOFRAME_SIZE (SPD ) || len - 3 > sizeof (buf )) {
155
+ DRM_DEV_ERROR (& hdmi -> pdev -> dev ,
156
+ "failed to configure SPD infoframe\n" );
157
+ return - EINVAL ;
158
+ }
159
+
160
+ /* checksum gets written together with the body of the frame */
161
+ hdmi_write (hdmi , REG_HDMI_GENERIC1_HDR ,
162
+ buffer [0 ] |
163
+ buffer [1 ] << 8 |
164
+ buffer [2 ] << 16 );
165
+
166
+ memcpy (buf , & buffer [3 ], len - 3 );
167
+
168
+ for (i = 0 ; i < ARRAY_SIZE (buf ); i ++ )
169
+ hdmi_write (hdmi , REG_HDMI_GENERIC1 (i ), buf [i ]);
170
+
171
+ val = hdmi_read (hdmi , REG_HDMI_GEN_PKT_CTRL );
172
+ val |= HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
173
+ HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
174
+ HDMI_GEN_PKT_CTRL_GENERIC1_LINE (SPD_IFRAME_LINE_NUMBER );
175
+ hdmi_write (hdmi , REG_HDMI_GEN_PKT_CTRL , val );
176
+
177
+ return 0 ;
178
+ }
179
+
180
+ static int msm_hdmi_config_hdmi_infoframe (struct hdmi * hdmi ,
181
+ const u8 * buffer , size_t len )
182
+ {
183
+ u32 buf [7 ] = {};
184
+ u32 val ;
185
+ int i ;
186
+
187
+ if (len < HDMI_INFOFRAME_HEADER_SIZE + HDMI_VENDOR_INFOFRAME_SIZE ||
188
+ len - 3 > sizeof (buf )) {
189
+ DRM_DEV_ERROR (& hdmi -> pdev -> dev ,
190
+ "failed to configure HDMI infoframe\n" );
191
+ return - EINVAL ;
192
+ }
193
+
194
+ /* checksum gets written together with the body of the frame */
195
+ hdmi_write (hdmi , REG_HDMI_GENERIC0_HDR ,
196
+ buffer [0 ] |
197
+ buffer [1 ] << 8 |
198
+ buffer [2 ] << 16 );
199
+
200
+ memcpy (buf , & buffer [3 ], len - 3 );
201
+
202
+ for (i = 0 ; i < ARRAY_SIZE (buf ); i ++ )
203
+ hdmi_write (hdmi , REG_HDMI_GENERIC0 (i ), buf [i ]);
204
+
205
+ val = hdmi_read (hdmi , REG_HDMI_GEN_PKT_CTRL );
206
+ val |= HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
207
+ HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
208
+ HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
209
+ HDMI_GEN_PKT_CTRL_GENERIC0_LINE (VENSPEC_IFRAME_LINE_NUMBER );
210
+ hdmi_write (hdmi , REG_HDMI_GEN_PKT_CTRL , val );
211
+
212
+ return 0 ;
213
+ }
214
+
145
215
static int msm_hdmi_bridge_clear_infoframe (struct drm_bridge * bridge ,
146
216
enum hdmi_infoframe_type type )
147
217
{
@@ -176,6 +246,25 @@ static int msm_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge,
176
246
177
247
break ;
178
248
249
+ case HDMI_INFOFRAME_TYPE_SPD :
250
+ val = hdmi_read (hdmi , REG_HDMI_GEN_PKT_CTRL );
251
+ val &= ~(HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
252
+ HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
253
+ HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK );
254
+ hdmi_write (hdmi , REG_HDMI_GEN_PKT_CTRL , val );
255
+
256
+ break ;
257
+
258
+ case HDMI_INFOFRAME_TYPE_VENDOR :
259
+ val = hdmi_read (hdmi , REG_HDMI_GEN_PKT_CTRL );
260
+ val &= ~(HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
261
+ HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
262
+ HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
263
+ HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK );
264
+ hdmi_write (hdmi , REG_HDMI_GEN_PKT_CTRL , val );
265
+
266
+ break ;
267
+
179
268
default :
180
269
drm_dbg_driver (hdmi_bridge -> base .dev , "Unsupported infoframe type %x\n" , type );
181
270
}
@@ -197,6 +286,10 @@ static int msm_hdmi_bridge_write_infoframe(struct drm_bridge *bridge,
197
286
return msm_hdmi_config_avi_infoframe (hdmi , buffer , len );
198
287
case HDMI_INFOFRAME_TYPE_AUDIO :
199
288
return msm_hdmi_config_audio_infoframe (hdmi , buffer , len );
289
+ case HDMI_INFOFRAME_TYPE_SPD :
290
+ return msm_hdmi_config_spd_infoframe (hdmi , buffer , len );
291
+ case HDMI_INFOFRAME_TYPE_VENDOR :
292
+ return msm_hdmi_config_hdmi_infoframe (hdmi , buffer , len );
200
293
default :
201
294
drm_dbg_driver (hdmi_bridge -> base .dev , "Unsupported infoframe type %x\n" , type );
202
295
return 0 ;
0 commit comments