.. | .. |
---|
4120 | 4120 | hdmi->y420_cmdb_map = map; |
---|
4121 | 4121 | } |
---|
4122 | 4122 | |
---|
| 4123 | +#ifdef CONFIG_NO_GKI |
---|
| 4124 | +static int drm_find_all_edid_extension(const struct edid *edid, |
---|
| 4125 | + int ext_id, int *ext_list) |
---|
| 4126 | +{ |
---|
| 4127 | + u8 *edid_ext = NULL; |
---|
| 4128 | + int i, count = 0; |
---|
| 4129 | + |
---|
| 4130 | + /* No EDID or EDID extensions */ |
---|
| 4131 | + if (edid == NULL || edid->extensions == 0) |
---|
| 4132 | + return -EINVAL; |
---|
| 4133 | + |
---|
| 4134 | + /* too many EDID extensions */ |
---|
| 4135 | + if (edid->extensions > 32) |
---|
| 4136 | + return -EINVAL; |
---|
| 4137 | + |
---|
| 4138 | + /* Find CEA extension */ |
---|
| 4139 | + for (i = 0; i < edid->extensions; i++) { |
---|
| 4140 | + edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1); |
---|
| 4141 | + if (edid_ext[0] == ext_id) { |
---|
| 4142 | + *ext_list = i; |
---|
| 4143 | + ext_list++; |
---|
| 4144 | + count++; |
---|
| 4145 | + } |
---|
| 4146 | + } |
---|
| 4147 | + |
---|
| 4148 | + return count; |
---|
| 4149 | +} |
---|
| 4150 | + |
---|
| 4151 | +/* |
---|
| 4152 | + * Search EDID for CEA extension block. |
---|
| 4153 | + */ |
---|
| 4154 | +static u8 *drm_find_edid_extension_from_index(const struct edid *edid, |
---|
| 4155 | + int ext_id, int *ext_index) |
---|
| 4156 | +{ |
---|
| 4157 | + u8 *edid_ext = NULL; |
---|
| 4158 | + int i; |
---|
| 4159 | + /* No EDID or EDID extensions */ |
---|
| 4160 | + if (edid == NULL || edid->extensions == 0) |
---|
| 4161 | + return NULL; |
---|
| 4162 | + /* Find CEA extension */ |
---|
| 4163 | + for (i = *ext_index; i < edid->extensions; i++) { |
---|
| 4164 | + edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1); |
---|
| 4165 | + if (edid_ext[0] == ext_id) |
---|
| 4166 | + break; |
---|
| 4167 | + } |
---|
| 4168 | + if (i >= edid->extensions) |
---|
| 4169 | + return NULL; |
---|
| 4170 | + *ext_index = i + 1; |
---|
| 4171 | + return edid_ext; |
---|
| 4172 | +} |
---|
| 4173 | + |
---|
| 4174 | +static int |
---|
| 4175 | +add_cea_modes(struct drm_connector *connector, struct edid *edid) |
---|
| 4176 | +{ |
---|
| 4177 | + const u8 *cea; |
---|
| 4178 | + const u8 *db, *hdmi = NULL, *video = NULL; |
---|
| 4179 | + u8 dbl, hdmi_len, video_len = 0; |
---|
| 4180 | + int i, count = 0, modes = 0; |
---|
| 4181 | + int ext_index = 0; |
---|
| 4182 | + int ext_list[32]; |
---|
| 4183 | + |
---|
| 4184 | + count = drm_find_all_edid_extension(edid, CEA_EXT, ext_list); |
---|
| 4185 | + for (i = 0; i < count; i++) { |
---|
| 4186 | + ext_index = ext_list[i]; |
---|
| 4187 | + cea = drm_find_edid_extension_from_index(edid, CEA_EXT, &ext_index); |
---|
| 4188 | + if (cea && cea_revision(cea) >= 3) { |
---|
| 4189 | + int i, start, end; |
---|
| 4190 | + |
---|
| 4191 | + if (cea_db_offsets(cea, &start, &end)) |
---|
| 4192 | + return 0; |
---|
| 4193 | + |
---|
| 4194 | + for_each_cea_db(cea, i, start, end) { |
---|
| 4195 | + db = &cea[i]; |
---|
| 4196 | + dbl = cea_db_payload_len(db); |
---|
| 4197 | + |
---|
| 4198 | + if (cea_db_tag(db) == VIDEO_BLOCK) { |
---|
| 4199 | + video = db + 1; |
---|
| 4200 | + video_len = dbl; |
---|
| 4201 | + modes += do_cea_modes(connector, video, dbl); |
---|
| 4202 | + } else if (cea_db_is_hdmi_vsdb(db)) { |
---|
| 4203 | + hdmi = db; |
---|
| 4204 | + hdmi_len = dbl; |
---|
| 4205 | + } else if (cea_db_is_y420vdb(db)) { |
---|
| 4206 | + const u8 *vdb420 = &db[2]; |
---|
| 4207 | + |
---|
| 4208 | + /* Add 4:2:0(only) modes present in EDID */ |
---|
| 4209 | + modes += do_y420vdb_modes(connector, |
---|
| 4210 | + vdb420, |
---|
| 4211 | + dbl - 1); |
---|
| 4212 | + } |
---|
| 4213 | + } |
---|
| 4214 | + } |
---|
| 4215 | + |
---|
| 4216 | + /* |
---|
| 4217 | + * We parse the HDMI VSDB after having added the cea modes as we will |
---|
| 4218 | + * be patching their flags when the sink supports stereo 3D. |
---|
| 4219 | + */ |
---|
| 4220 | + if (hdmi) |
---|
| 4221 | + modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video, |
---|
| 4222 | + video_len); |
---|
| 4223 | + } |
---|
| 4224 | + |
---|
| 4225 | + return modes; |
---|
| 4226 | +} |
---|
| 4227 | + |
---|
| 4228 | +#else |
---|
| 4229 | + |
---|
4123 | 4230 | static int |
---|
4124 | 4231 | add_cea_modes(struct drm_connector *connector, struct edid *edid) |
---|
4125 | 4232 | { |
---|
.. | .. |
---|
4166 | 4273 | |
---|
4167 | 4274 | return modes; |
---|
4168 | 4275 | } |
---|
| 4276 | +#endif |
---|
4169 | 4277 | |
---|
4170 | 4278 | static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode) |
---|
4171 | 4279 | { |
---|