Message ID | 1366390886-4215-1-git-send-email-zajec5@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Am 19.04.2013 19:01, schrieb Rafa? Mi?ecki: > Some devices (ATI/AMD cards) don't support passing ELD struct to the > hardware but just require filling specific registers and then the > hardware/firmware does the rest. In such cases we need to read the info > from SAD blocks and put them in the correct registers. > > Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com> Maybe add some comment that the returned pointer needs to be kfreed, but apart from that it is good enough for me and: Reviewed-by: Christian König <christian.koenig@amd.com> > --- > Changes since RFC: > 1) Fixed allocation (and kcalloc instead of kzalloc) > 2) Don't duplicate defines for audio codecs > 3) Some variables scope > --- > drivers/gpu/drm/drm_edid.c | 58 ++++++++++++++++++++++++++++++++++++++++++++ > include/drm/drm_edid.h | 9 +++++++ > 2 files changed, 67 insertions(+) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index e2acfdb..89ae211 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -2511,6 +2511,64 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) > EXPORT_SYMBOL(drm_edid_to_eld); > > /** > + * drm_edid_to_sad - extracts SADs from EDID > + * @edid: EDID to parse > + * @sads: pointer that will be set to the extracted SADs > + * > + * Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from it. > + * > + * Return number of found SADs or negative number on error. > + */ > +int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads) > +{ > + int count = 0; > + int i, start, end, dbl; > + u8 *cea; > + > + cea = drm_find_cea_extension(edid); > + if (!cea) { > + DRM_DEBUG_KMS("SAD: no CEA Extension found\n"); > + return -ENOENT; > + } > + > + if (cea_revision(cea) < 3) { > + DRM_DEBUG_KMS("SAD: wrong CEA revision\n"); > + return -ENOTSUPP; > + } > + > + if (cea_db_offsets(cea, &start, &end)) { > + DRM_DEBUG_KMS("SAD: invalid data block offsets\n"); > + return -EPROTO; > + } > + > + for_each_cea_db(cea, i, start, end) { > + u8 *db = &cea[i]; > + > + if (cea_db_tag(db) == AUDIO_BLOCK) { > + dbl = cea_db_payload_len(db); > + int j; > + > + count = dbl / 3; /* SAD is 3B */ > + *sads = kcalloc(count, sizeof(**sads), GFP_KERNEL); > + if (!*sads) > + return -ENOMEM; > + for (j = 0; j < count; j++) { > + u8 *sad = &db[1 + j * 3]; > + > + (*sads)[j].format = (sad[0] & 0x78) >> 3; > + (*sads)[j].channels = sad[0] & 0x7; > + (*sads)[j].freq = sad[1] & 0x7F; > + (*sads)[j].byte2 = sad[2]; > + } > + break; > + } > + } > + > + return count; > +} > +EXPORT_SYMBOL(drm_edid_to_sad); > + > +/** > * drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond > * @connector: connector associated with the HDMI/DP sink > * @mode: the display mode > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h > index 5da1b4a..fc481fc 100644 > --- a/include/drm/drm_edid.h > +++ b/include/drm/drm_edid.h > @@ -244,12 +244,21 @@ struct edid { > > #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8)) > > +/* Short Audio Descriptor */ > +struct cea_sad { > + u8 format; > + u8 channels; /* max number of channels - 1 */ > + u8 freq; > + u8 byte2; /* meaning depends on format */ > +}; > + > struct drm_encoder; > struct drm_connector; > struct drm_display_mode; > struct hdmi_avi_infoframe; > > void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid); > +int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads); > int drm_av_sync_delay(struct drm_connector *connector, > struct drm_display_mode *mode); > struct drm_connector *drm_select_eld(struct drm_encoder *encoder,
On Fri, Apr 19, 2013 at 1:01 PM, Rafa? Mi?ecki <zajec5@gmail.com> wrote: > Some devices (ATI/AMD cards) don't support passing ELD struct to the > hardware but just require filling specific registers and then the > hardware/firmware does the rest. In such cases we need to read the info > from SAD blocks and put them in the correct registers. > > Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com> Thanks both patches applied. I added a comment about needing to kfree the returned pointer as per Christian's comment. Alex > --- > Changes since RFC: > 1) Fixed allocation (and kcalloc instead of kzalloc) > 2) Don't duplicate defines for audio codecs > 3) Some variables scope > --- > drivers/gpu/drm/drm_edid.c | 58 ++++++++++++++++++++++++++++++++++++++++++++ > include/drm/drm_edid.h | 9 +++++++ > 2 files changed, 67 insertions(+) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index e2acfdb..89ae211 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -2511,6 +2511,64 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) > EXPORT_SYMBOL(drm_edid_to_eld); > > /** > + * drm_edid_to_sad - extracts SADs from EDID > + * @edid: EDID to parse > + * @sads: pointer that will be set to the extracted SADs > + * > + * Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from it. > + * > + * Return number of found SADs or negative number on error. > + */ > +int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads) > +{ > + int count = 0; > + int i, start, end, dbl; > + u8 *cea; > + > + cea = drm_find_cea_extension(edid); > + if (!cea) { > + DRM_DEBUG_KMS("SAD: no CEA Extension found\n"); > + return -ENOENT; > + } > + > + if (cea_revision(cea) < 3) { > + DRM_DEBUG_KMS("SAD: wrong CEA revision\n"); > + return -ENOTSUPP; > + } > + > + if (cea_db_offsets(cea, &start, &end)) { > + DRM_DEBUG_KMS("SAD: invalid data block offsets\n"); > + return -EPROTO; > + } > + > + for_each_cea_db(cea, i, start, end) { > + u8 *db = &cea[i]; > + > + if (cea_db_tag(db) == AUDIO_BLOCK) { > + dbl = cea_db_payload_len(db); > + int j; > + > + count = dbl / 3; /* SAD is 3B */ > + *sads = kcalloc(count, sizeof(**sads), GFP_KERNEL); > + if (!*sads) > + return -ENOMEM; > + for (j = 0; j < count; j++) { > + u8 *sad = &db[1 + j * 3]; > + > + (*sads)[j].format = (sad[0] & 0x78) >> 3; > + (*sads)[j].channels = sad[0] & 0x7; > + (*sads)[j].freq = sad[1] & 0x7F; > + (*sads)[j].byte2 = sad[2]; > + } > + break; > + } > + } > + > + return count; > +} > +EXPORT_SYMBOL(drm_edid_to_sad); > + > +/** > * drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond > * @connector: connector associated with the HDMI/DP sink > * @mode: the display mode > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h > index 5da1b4a..fc481fc 100644 > --- a/include/drm/drm_edid.h > +++ b/include/drm/drm_edid.h > @@ -244,12 +244,21 @@ struct edid { > > #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8)) > > +/* Short Audio Descriptor */ > +struct cea_sad { > + u8 format; > + u8 channels; /* max number of channels - 1 */ > + u8 freq; > + u8 byte2; /* meaning depends on format */ > +}; > + > struct drm_encoder; > struct drm_connector; > struct drm_display_mode; > struct hdmi_avi_infoframe; > > void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid); > +int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads); > int drm_av_sync_delay(struct drm_connector *connector, > struct drm_display_mode *mode); > struct drm_connector *drm_select_eld(struct drm_encoder *encoder, > -- > 1.7.10.4 >
Am 21.04.2013 23:53, schrieb Alex Deucher: > On Fri, Apr 19, 2013 at 1:01 PM, Rafa? Mi?ecki <zajec5@gmail.com> wrote: >> Some devices (ATI/AMD cards) don't support passing ELD struct to the >> hardware but just require filling specific registers and then the >> hardware/firmware does the rest. In such cases we need to read the info >> from SAD blocks and put them in the correct registers. >> >> Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com> > Thanks both patches applied. I added a comment about needing to kfree > the returned pointer as per Christian's comment. Found one more minor nitpick in this patch: > + if (cea_db_tag(db) == AUDIO_BLOCK) { > + dbl = cea_db_payload_len(db); > + int j; > + That's code after declaration and so complained on by the compiler. Christian.
2013/4/22 Christian König <deathsimple@vodafone.de>: > Found one more minor nitpick in this patch: > > >> + if (cea_db_tag(db) == AUDIO_BLOCK) { >> + dbl = cea_db_payload_len(db); >> + int j; >> + > > > That's code after declaration and so complained on by the compiler. I guess you've missed drm_edid_to_sad: (drm-next-3.10) compiler warnings [PATCH] drm: drm_edid_to_sad: fix declaration warning threads :)
On Mon, Apr 22, 2013 at 12:12 PM, Rafa? Mi?ecki <zajec5@gmail.com> wrote: > 2013/4/22 Christian König <deathsimple@vodafone.de>: >> Found one more minor nitpick in this patch: >> >> >>> + if (cea_db_tag(db) == AUDIO_BLOCK) { >>> + dbl = cea_db_payload_len(db); >>> + int j; >>> + >> >> >> That's code after declaration and so complained on by the compiler. > > I guess you've missed > drm_edid_to_sad: (drm-next-3.10) compiler warnings > [PATCH] drm: drm_edid_to_sad: fix declaration warning > threads :) > I've fixed it up in my tree. thanks! Alex
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index e2acfdb..89ae211 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -2511,6 +2511,64 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) EXPORT_SYMBOL(drm_edid_to_eld); /** + * drm_edid_to_sad - extracts SADs from EDID + * @edid: EDID to parse + * @sads: pointer that will be set to the extracted SADs + * + * Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from it. + * + * Return number of found SADs or negative number on error. + */ +int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads) +{ + int count = 0; + int i, start, end, dbl; + u8 *cea; + + cea = drm_find_cea_extension(edid); + if (!cea) { + DRM_DEBUG_KMS("SAD: no CEA Extension found\n"); + return -ENOENT; + } + + if (cea_revision(cea) < 3) { + DRM_DEBUG_KMS("SAD: wrong CEA revision\n"); + return -ENOTSUPP; + } + + if (cea_db_offsets(cea, &start, &end)) { + DRM_DEBUG_KMS("SAD: invalid data block offsets\n"); + return -EPROTO; + } + + for_each_cea_db(cea, i, start, end) { + u8 *db = &cea[i]; + + if (cea_db_tag(db) == AUDIO_BLOCK) { + dbl = cea_db_payload_len(db); + int j; + + count = dbl / 3; /* SAD is 3B */ + *sads = kcalloc(count, sizeof(**sads), GFP_KERNEL); + if (!*sads) + return -ENOMEM; + for (j = 0; j < count; j++) { + u8 *sad = &db[1 + j * 3]; + + (*sads)[j].format = (sad[0] & 0x78) >> 3; + (*sads)[j].channels = sad[0] & 0x7; + (*sads)[j].freq = sad[1] & 0x7F; + (*sads)[j].byte2 = sad[2]; + } + break; + } + } + + return count; +} +EXPORT_SYMBOL(drm_edid_to_sad); + +/** * drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond * @connector: connector associated with the HDMI/DP sink * @mode: the display mode diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 5da1b4a..fc481fc 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -244,12 +244,21 @@ struct edid { #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8)) +/* Short Audio Descriptor */ +struct cea_sad { + u8 format; + u8 channels; /* max number of channels - 1 */ + u8 freq; + u8 byte2; /* meaning depends on format */ +}; + struct drm_encoder; struct drm_connector; struct drm_display_mode; struct hdmi_avi_infoframe; void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid); +int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads); int drm_av_sync_delay(struct drm_connector *connector, struct drm_display_mode *mode); struct drm_connector *drm_select_eld(struct drm_encoder *encoder,
Some devices (ATI/AMD cards) don't support passing ELD struct to the hardware but just require filling specific registers and then the hardware/firmware does the rest. In such cases we need to read the info from SAD blocks and put them in the correct registers. Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com> --- Changes since RFC: 1) Fixed allocation (and kcalloc instead of kzalloc) 2) Don't duplicate defines for audio codecs 3) Some variables scope --- drivers/gpu/drm/drm_edid.c | 58 ++++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_edid.h | 9 +++++++ 2 files changed, 67 insertions(+)