Message ID | 7a0e5e99a83f203b6a8981d263b89b2bb7d2fe15.1672826282.git.jani.nikula@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/edid: info & modes parsing and drm_edid refactors | expand |
On Wed, Jan 04, 2023 at 12:05:22PM +0200, Jani Nikula wrote: > Now that we have pre-parsed CTA VDB VICs stored in info->vics, leverage > that to simplify CTA Y420CMDB parsing. Move updating the y420_cmdb_modes > bitmap to the display info parsing stage, instead of updating it during > add modes. This allows us to drop the intermediate y420_cmdb_map from > display info, and replace it with a local variable. > > This is prerequisite work for overall better separation of the two > parsing steps (updating display info and adding modes). > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> > Signed-off-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > --- > drivers/gpu/drm/drm_edid.c | 86 ++++++++++++++++++------------------- > include/drm/drm_connector.h | 3 -- > 2 files changed, 43 insertions(+), 46 deletions(-) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index 4e9108e9fc96..ead7a4ce0422 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -4522,24 +4522,6 @@ static int do_y420vdb_modes(struct drm_connector *connector, > return modes; > } > > -/* > - * drm_add_cmdb_modes - Add a YCBCR 420 mode into bitmap > - * @connector: connector corresponding to the HDMI sink > - * @vic: CEA vic for the video mode to be added in the map > - * > - * Makes an entry for a videomode in the YCBCR 420 bitmap > - */ > -static void > -drm_add_cmdb_modes(struct drm_connector *connector, u8 vic) > -{ > - struct drm_hdmi_info *hdmi = &connector->display_info.hdmi; > - > - if (!drm_valid_cea_vic(vic)) > - return; > - > - bitmap_set(hdmi->y420_cmdb_modes, vic, 1); > -} > - > /** > * drm_display_mode_from_cea_vic() - return a mode for CEA VIC > * @dev: DRM device > @@ -4572,7 +4554,6 @@ EXPORT_SYMBOL(drm_display_mode_from_cea_vic); > static int add_cta_vdb_modes(struct drm_connector *connector) > { > const struct drm_display_info *info = &connector->display_info; > - const struct drm_hdmi_info *hdmi = &info->hdmi; > int i, modes = 0; > > if (!info->vics) > @@ -4583,18 +4564,6 @@ static int add_cta_vdb_modes(struct drm_connector *connector) > > mode = drm_display_mode_from_vic_index(connector, i); > if (mode) { > - /* > - * YCBCR420 capability block contains a bitmap which > - * gives the index of CEA modes from CEA VDB, which > - * can support YCBCR 420 sampling output also (apart > - * from RGB/YCBCR444 etc). > - * For example, if the bit 0 in bitmap is set, > - * first mode in VDB can support YCBCR420 output too. > - * Add YCBCR420 modes only if sink is HDMI 2.0 capable. > - */ > - if (i < 64 && hdmi->y420_cmdb_map & (1ULL << i)) > - drm_add_cmdb_modes(connector, info->vics[i]); > - > drm_mode_probed_add(connector, mode); > modes++; > } > @@ -5188,20 +5157,26 @@ static int edid_hfeeodb_extension_block_count(const struct edid *edid) > return cta[4 + 2]; > } > > -static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector, > - const u8 *db) > +/* > + * CTA-861 YCbCr 4:2:0 Capability Map Data Block (CTA Y420CMDB) > + * > + * Y420CMDB contains a bitmap which gives the index of CTA modes from CTA VDB, > + * which can support YCBCR 420 sampling output also (apart from RGB/YCBCR444 > + * etc). For example, if the bit 0 in bitmap is set, first mode in VDB can > + * support YCBCR420 output too. > + */ > +static void parse_cta_y420cmdb(struct drm_connector *connector, > + const struct cea_db *db, u64 *y420cmdb_map) > { > struct drm_display_info *info = &connector->display_info; > - struct drm_hdmi_info *hdmi = &info->hdmi; > - u8 map_len = cea_db_payload_len(db) - 1; > - u8 count; > + int i, map_len = cea_db_payload_len(db) - 1; > + const u8 *data = cea_db_data(db) + 1; > u64 map = 0; > > if (map_len == 0) { > /* All CEA modes support ycbcr420 sampling also.*/ > - hdmi->y420_cmdb_map = U64_MAX; > - info->color_formats |= DRM_COLOR_FORMAT_YCBCR420; > - return; > + map = U64_MAX; > + goto out; > } > > /* > @@ -5219,13 +5194,14 @@ static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector, > if (WARN_ON_ONCE(map_len > 8)) > map_len = 8; > > - for (count = 0; count < map_len; count++) > - map |= (u64)db[2 + count] << (8 * count); > + for (i = 0; i < map_len; i++) > + map |= (u64)data[i] << (8 * i); > > +out: > if (map) > info->color_formats |= DRM_COLOR_FORMAT_YCBCR420; > > - hdmi->y420_cmdb_map = map; > + *y420cmdb_map = map; > } > > static int add_cea_modes(struct drm_connector *connector, > @@ -5864,6 +5840,26 @@ static void parse_cta_vdb(struct drm_connector *connector, const struct cea_db * > } > } > > +/* > + * Update y420_cmdb_modes based on previously parsed CTA VDB and Y420CMDB. > + * > + * Translate the y420cmdb_map based on VIC indexes to y420_cmdb_modes indexed > + * using the VICs themselves. > + */ > +static void update_cta_y420cmdb(struct drm_connector *connector, u64 y420cmdb_map) > +{ > + struct drm_display_info *info = &connector->display_info; > + struct drm_hdmi_info *hdmi = &info->hdmi; > + int i, len = min_t(int, info->vics_len, BITS_PER_TYPE(y420cmdb_map)); > + > + for (i = 0; i < len; i++) { > + u8 vic = info->vics[i]; > + > + if (vic && y420cmdb_map & BIT_ULL(i)) > + bitmap_set(hdmi->y420_cmdb_modes, vic, 1); > + } > +} > + > static bool cta_vdb_has_vic(const struct drm_connector *connector, u8 vic) > { > const struct drm_display_info *info = &connector->display_info; > @@ -6181,6 +6177,7 @@ static void drm_parse_cea_ext(struct drm_connector *connector, > const struct cea_db *db; > struct cea_db_iter iter; > const u8 *edid_ext; > + u64 y420cmdb_map = 0; > > drm_edid_iter_begin(drm_edid, &edid_iter); > drm_edid_iter_for_each(edid_ext, &edid_iter) { > @@ -6218,7 +6215,7 @@ static void drm_parse_cea_ext(struct drm_connector *connector, > else if (cea_db_is_microsoft_vsdb(db)) > drm_parse_microsoft_vsdb(connector, data); > else if (cea_db_is_y420cmdb(db)) > - drm_parse_y420cmdb_bitmap(connector, data); > + parse_cta_y420cmdb(connector, db, &y420cmdb_map); > else if (cea_db_is_vcdb(db)) > drm_parse_vcdb(connector, data); > else if (cea_db_is_hdmi_hdr_metadata_block(db)) > @@ -6227,6 +6224,9 @@ static void drm_parse_cea_ext(struct drm_connector *connector, > parse_cta_vdb(connector, db); > } > cea_db_iter_end(&iter); > + > + if (y420cmdb_map) > + update_cta_y420cmdb(connector, y420cmdb_map); > } > > static > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h > index d97ed06d5837..1c26c4e72c62 100644 > --- a/include/drm/drm_connector.h > +++ b/include/drm/drm_connector.h > @@ -304,9 +304,6 @@ struct drm_hdmi_info { > */ > unsigned long y420_cmdb_modes[BITS_TO_LONGS(256)]; > > - /** @y420_cmdb_map: bitmap of SVD index, to extraxt vcb modes */ > - u64 y420_cmdb_map; > - > /** @y420_dc_modes: bitmap of deep color support index */ > u8 y420_dc_modes; > > -- > 2.34.1
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 4e9108e9fc96..ead7a4ce0422 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -4522,24 +4522,6 @@ static int do_y420vdb_modes(struct drm_connector *connector, return modes; } -/* - * drm_add_cmdb_modes - Add a YCBCR 420 mode into bitmap - * @connector: connector corresponding to the HDMI sink - * @vic: CEA vic for the video mode to be added in the map - * - * Makes an entry for a videomode in the YCBCR 420 bitmap - */ -static void -drm_add_cmdb_modes(struct drm_connector *connector, u8 vic) -{ - struct drm_hdmi_info *hdmi = &connector->display_info.hdmi; - - if (!drm_valid_cea_vic(vic)) - return; - - bitmap_set(hdmi->y420_cmdb_modes, vic, 1); -} - /** * drm_display_mode_from_cea_vic() - return a mode for CEA VIC * @dev: DRM device @@ -4572,7 +4554,6 @@ EXPORT_SYMBOL(drm_display_mode_from_cea_vic); static int add_cta_vdb_modes(struct drm_connector *connector) { const struct drm_display_info *info = &connector->display_info; - const struct drm_hdmi_info *hdmi = &info->hdmi; int i, modes = 0; if (!info->vics) @@ -4583,18 +4564,6 @@ static int add_cta_vdb_modes(struct drm_connector *connector) mode = drm_display_mode_from_vic_index(connector, i); if (mode) { - /* - * YCBCR420 capability block contains a bitmap which - * gives the index of CEA modes from CEA VDB, which - * can support YCBCR 420 sampling output also (apart - * from RGB/YCBCR444 etc). - * For example, if the bit 0 in bitmap is set, - * first mode in VDB can support YCBCR420 output too. - * Add YCBCR420 modes only if sink is HDMI 2.0 capable. - */ - if (i < 64 && hdmi->y420_cmdb_map & (1ULL << i)) - drm_add_cmdb_modes(connector, info->vics[i]); - drm_mode_probed_add(connector, mode); modes++; } @@ -5188,20 +5157,26 @@ static int edid_hfeeodb_extension_block_count(const struct edid *edid) return cta[4 + 2]; } -static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector, - const u8 *db) +/* + * CTA-861 YCbCr 4:2:0 Capability Map Data Block (CTA Y420CMDB) + * + * Y420CMDB contains a bitmap which gives the index of CTA modes from CTA VDB, + * which can support YCBCR 420 sampling output also (apart from RGB/YCBCR444 + * etc). For example, if the bit 0 in bitmap is set, first mode in VDB can + * support YCBCR420 output too. + */ +static void parse_cta_y420cmdb(struct drm_connector *connector, + const struct cea_db *db, u64 *y420cmdb_map) { struct drm_display_info *info = &connector->display_info; - struct drm_hdmi_info *hdmi = &info->hdmi; - u8 map_len = cea_db_payload_len(db) - 1; - u8 count; + int i, map_len = cea_db_payload_len(db) - 1; + const u8 *data = cea_db_data(db) + 1; u64 map = 0; if (map_len == 0) { /* All CEA modes support ycbcr420 sampling also.*/ - hdmi->y420_cmdb_map = U64_MAX; - info->color_formats |= DRM_COLOR_FORMAT_YCBCR420; - return; + map = U64_MAX; + goto out; } /* @@ -5219,13 +5194,14 @@ static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector, if (WARN_ON_ONCE(map_len > 8)) map_len = 8; - for (count = 0; count < map_len; count++) - map |= (u64)db[2 + count] << (8 * count); + for (i = 0; i < map_len; i++) + map |= (u64)data[i] << (8 * i); +out: if (map) info->color_formats |= DRM_COLOR_FORMAT_YCBCR420; - hdmi->y420_cmdb_map = map; + *y420cmdb_map = map; } static int add_cea_modes(struct drm_connector *connector, @@ -5864,6 +5840,26 @@ static void parse_cta_vdb(struct drm_connector *connector, const struct cea_db * } } +/* + * Update y420_cmdb_modes based on previously parsed CTA VDB and Y420CMDB. + * + * Translate the y420cmdb_map based on VIC indexes to y420_cmdb_modes indexed + * using the VICs themselves. + */ +static void update_cta_y420cmdb(struct drm_connector *connector, u64 y420cmdb_map) +{ + struct drm_display_info *info = &connector->display_info; + struct drm_hdmi_info *hdmi = &info->hdmi; + int i, len = min_t(int, info->vics_len, BITS_PER_TYPE(y420cmdb_map)); + + for (i = 0; i < len; i++) { + u8 vic = info->vics[i]; + + if (vic && y420cmdb_map & BIT_ULL(i)) + bitmap_set(hdmi->y420_cmdb_modes, vic, 1); + } +} + static bool cta_vdb_has_vic(const struct drm_connector *connector, u8 vic) { const struct drm_display_info *info = &connector->display_info; @@ -6181,6 +6177,7 @@ static void drm_parse_cea_ext(struct drm_connector *connector, const struct cea_db *db; struct cea_db_iter iter; const u8 *edid_ext; + u64 y420cmdb_map = 0; drm_edid_iter_begin(drm_edid, &edid_iter); drm_edid_iter_for_each(edid_ext, &edid_iter) { @@ -6218,7 +6215,7 @@ static void drm_parse_cea_ext(struct drm_connector *connector, else if (cea_db_is_microsoft_vsdb(db)) drm_parse_microsoft_vsdb(connector, data); else if (cea_db_is_y420cmdb(db)) - drm_parse_y420cmdb_bitmap(connector, data); + parse_cta_y420cmdb(connector, db, &y420cmdb_map); else if (cea_db_is_vcdb(db)) drm_parse_vcdb(connector, data); else if (cea_db_is_hdmi_hdr_metadata_block(db)) @@ -6227,6 +6224,9 @@ static void drm_parse_cea_ext(struct drm_connector *connector, parse_cta_vdb(connector, db); } cea_db_iter_end(&iter); + + if (y420cmdb_map) + update_cta_y420cmdb(connector, y420cmdb_map); } static diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index d97ed06d5837..1c26c4e72c62 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -304,9 +304,6 @@ struct drm_hdmi_info { */ unsigned long y420_cmdb_modes[BITS_TO_LONGS(256)]; - /** @y420_cmdb_map: bitmap of SVD index, to extraxt vcb modes */ - u64 y420_cmdb_map; - /** @y420_dc_modes: bitmap of deep color support index */ u8 y420_dc_modes;
Now that we have pre-parsed CTA VDB VICs stored in info->vics, leverage that to simplify CTA Y420CMDB parsing. Move updating the y420_cmdb_modes bitmap to the display info parsing stage, instead of updating it during add modes. This allows us to drop the intermediate y420_cmdb_map from display info, and replace it with a local variable. This is prerequisite work for overall better separation of the two parsing steps (updating display info and adding modes). Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/drm_edid.c | 86 ++++++++++++++++++------------------- include/drm/drm_connector.h | 3 -- 2 files changed, 43 insertions(+), 46 deletions(-)