All of lore.kernel.org
 help / color / mirror / Atom feed
From: Inki Dae <inki.dae@samsung.com>
To: Andrzej Hajda <a.hajda@samsung.com>, dri-devel@lists.freedesktop.org
Cc: Marek Szyprowski <m.szyprowski@samsung.com>,
	Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Subject: Re: [PATCH] drm/exynos/hdmi: refactor infoframe code
Date: Mon, 07 Nov 2016 10:45:10 +0900	[thread overview]
Message-ID: <581FDCA6.3050405@samsung.com> (raw)
In-Reply-To: <1477485391-8911-1-git-send-email-a.hajda@samsung.com>



2016년 10월 26일 21:36에 Andrzej Hajda 이(가) 쓴 글:
> Use core helpers to generate infoframes and generate vendor frame if necessary.
> 
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_hdmi.c | 141 ++++++++++-------------------------
>  drivers/gpu/drm/exynos/regs-hdmi.h   |   2 +
>  2 files changed, 42 insertions(+), 101 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
> index e8fb6ef..1bb2df7 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
> @@ -47,19 +47,6 @@
>  
>  #define HOTPLUG_DEBOUNCE_MS		1100
>  
> -/* AVI header and aspect ratio */
> -#define HDMI_AVI_VERSION		0x02
> -#define HDMI_AVI_LENGTH			0x0d
> -
> -/* AUI header info */
> -#define HDMI_AUI_VERSION		0x01
> -#define HDMI_AUI_LENGTH			0x0a
> -
> -/* AVI active format aspect ratio */
> -#define AVI_SAME_AS_PIC_ASPECT_RATIO	0x08
> -#define AVI_4_3_CENTER_RATIO		0x09
> -#define AVI_16_9_CENTER_RATIO		0x0a
> -
>  enum hdmi_type {
>  	HDMI_TYPE13,
>  	HDMI_TYPE14,
> @@ -131,7 +118,6 @@ struct hdmi_context {
>  	bool				dvi_mode;
>  	struct delayed_work		hotplug_work;
>  	struct drm_display_mode		current_mode;
> -	u8				cea_video_id;
>  	const struct hdmi_driver_data	*drv_data;
>  
>  	void __iomem			*regs;
> @@ -681,6 +667,13 @@ static inline void hdmi_reg_writev(struct hdmi_context *hdata, u32 reg_id,
>  	}
>  }
>  
> +static inline void hdmi_reg_write_buf(struct hdmi_context *hdata, u32 reg_id,
> +				      u8 *buf, int size)
> +{
> +	for (reg_id = hdmi_map_reg(hdata, reg_id); size; --size, reg_id += 4)
> +		writel(*buf++, hdata->regs + reg_id);
> +}
> +
>  static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
>  				 u32 reg_id, u32 value, u32 mask)
>  {
> @@ -762,93 +755,50 @@ static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
>  	return ret;
>  }
>  
> -static u8 hdmi_chksum(struct hdmi_context *hdata,
> -			u32 start, u8 len, u32 hdr_sum)
> -{
> -	int i;
> -
> -	/* hdr_sum : header0 + header1 + header2
> -	* start : start address of packet byte1
> -	* len : packet bytes - 1 */
> -	for (i = 0; i < len; ++i)
> -		hdr_sum += 0xff & hdmi_reg_read(hdata, start + i * 4);
> -
> -	/* return 2's complement of 8 bit hdr_sum */
> -	return (u8)(~(hdr_sum & 0xff) + 1);
> -}
> -
> -static void hdmi_reg_infoframe(struct hdmi_context *hdata,
> -			union hdmi_infoframe *infoframe)
> +static void hdmi_reg_infoframes(struct hdmi_context *hdata)
>  {
> -	u32 hdr_sum;
> -	u8 chksum;
> -	u8 ar;
> +	union hdmi_infoframe frm;
> +	u8 buf[25];
> +	int ret;
>  
>  	if (hdata->dvi_mode) {
> -		hdmi_reg_writeb(hdata, HDMI_VSI_CON,
> -				HDMI_VSI_CON_DO_NOT_TRANSMIT);
>  		hdmi_reg_writeb(hdata, HDMI_AVI_CON,
>  				HDMI_AVI_CON_DO_NOT_TRANSMIT);
> +		hdmi_reg_writeb(hdata, HDMI_VSI_CON,
> +				HDMI_VSI_CON_DO_NOT_TRANSMIT);
>  		hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_NO_TRAN);
>  		return;
>  	}
>  
> -	switch (infoframe->any.type) {
> -	case HDMI_INFOFRAME_TYPE_AVI:
> +	ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi,
> +			&hdata->current_mode);
> +	if (ret >= 0)

Seems above condition is not clear becuase drm_hdmi_avi_infoframe_from_display_mode function returns 0 or negative value.

> +		ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf));
> +	if (ret > 0) {
>  		hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC);

I think above code should be called when drm_hdmi_avi_infoframe_from_display_mode function returned 0 and the value from hdmi_avi_infoframe_pack function is more than 1.

> -		hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->any.type);
> -		hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1,
> -				infoframe->any.version);
> -		hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->any.length);
> -		hdr_sum = infoframe->any.type + infoframe->any.version +
> -			  infoframe->any.length;
> -
> -		/* Output format zero hardcoded ,RGB YBCR selection */
> -		hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 |
> -			AVI_ACTIVE_FORMAT_VALID |
> -			AVI_UNDERSCANNED_DISPLAY_VALID);
> -
> -		/*
> -		 * Set the aspect ratio as per the mode, mentioned in
> -		 * Table 9 AVI InfoFrame Data Byte 2 of CEA-861-D Standard
> -		 */
> -		ar = hdata->current_mode.picture_aspect_ratio;
> -		switch (ar) {
> -		case HDMI_PICTURE_ASPECT_4_3:
> -			ar |= AVI_4_3_CENTER_RATIO;
> -			break;
> -		case HDMI_PICTURE_ASPECT_16_9:
> -			ar |= AVI_16_9_CENTER_RATIO;
> -			break;
> -		case HDMI_PICTURE_ASPECT_NONE:
> -		default:
> -			ar |= AVI_SAME_AS_PIC_ASPECT_RATIO;
> -			break;
> -		}
> -		hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(2), ar);
> +		hdmi_reg_write_buf(hdata, HDMI_AVI_HEADER0, buf, ret);
> +	} else {
> +		DRM_INFO("%s: invalid AVI infoframe (%d)\n", __func__, ret);

If drm_hdmi_avi_infoframe_from_display_mode function returns 0 on success, then above message will be printed out. Seems not reasonable.

> +	}
>  
> -		hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), hdata->cea_video_id);
> +	ret = drm_hdmi_vendor_infoframe_from_display_mode(&frm.vendor.hdmi,
> +			&hdata->current_mode);
> +	if (ret >= 0)

Ditto.

> +		ret = hdmi_vendor_infoframe_pack(&frm.vendor.hdmi, buf,
> +				sizeof(buf));
> +	if (ret > 0) {
> +		hdmi_reg_writeb(hdata, HDMI_VSI_CON, HDMI_VSI_CON_EVERY_VSYNC);
> +		hdmi_reg_write_buf(hdata, HDMI_VSI_HEADER0, buf, ret);

Also above codes should be called when drm_hdmi_vendor_infoframe_from_display_mode function returned 0 and the value from hdmi_vendor_infoframe_pack function is more than 1.

> +	}
>  
> -		chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1),
> -					infoframe->any.length, hdr_sum);
> -		DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum);
> -		hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum);
> -		break;
> -	case HDMI_INFOFRAME_TYPE_AUDIO:
> -		hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02);
> -		hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->any.type);
> -		hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1,
> -				infoframe->any.version);
> -		hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->any.length);
> -		hdr_sum = infoframe->any.type + infoframe->any.version +
> -			  infoframe->any.length;
> -		chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1),
> -					infoframe->any.length, hdr_sum);
> -		DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum);
> -		hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum);
> -		break;
> -	default:
> -		break;
> +	ret = hdmi_audio_infoframe_init(&frm.audio);
> +	if (ret >= 0) {

Ditto.

> +		frm.audio.channels = 2;
> +		ret = hdmi_audio_infoframe_pack(&frm.audio, buf, sizeof(buf));
> +	}
> +	if (ret > 0) {
> +		hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_EVERY_VSYNC);
> +		hdmi_reg_write_buf(hdata, HDMI_AUI_HEADER0, buf, ret);

Also above codes should be called when hdmi_audio_infoframe_init function returned 0 and the value from hdmi_audio_infoframe_pack function is more than 1.

>  	}
>  }
>  
> @@ -1127,8 +1077,6 @@ static void hdmi_start(struct hdmi_context *hdata, bool start)
>  
>  static void hdmi_conf_init(struct hdmi_context *hdata)
>  {
> -	union hdmi_infoframe infoframe;
> -
>  	/* disable HPD interrupts from HDMI IP block, use GPIO instead */
>  	hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
>  		HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
> @@ -1164,15 +1112,7 @@ static void hdmi_conf_init(struct hdmi_context *hdata)
>  		hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
>  		hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
>  	} else {
> -		infoframe.any.type = HDMI_INFOFRAME_TYPE_AVI;
> -		infoframe.any.version = HDMI_AVI_VERSION;
> -		infoframe.any.length = HDMI_AVI_LENGTH;
> -		hdmi_reg_infoframe(hdata, &infoframe);
> -
> -		infoframe.any.type = HDMI_INFOFRAME_TYPE_AUDIO;
> -		infoframe.any.version = HDMI_AUI_VERSION;
> -		infoframe.any.length = HDMI_AUI_LENGTH;
> -		hdmi_reg_infoframe(hdata, &infoframe);
> +		hdmi_reg_infoframes(hdata);
>  
>  		/* enable AVI packet every vsync, fixes purple line problem */
>  		hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
> @@ -1458,7 +1398,6 @@ static void hdmi_mode_set(struct drm_encoder *encoder,
>  		"INTERLACED" : "PROGRESSIVE");
>  
>  	drm_mode_copy(&hdata->current_mode, m);
> -	hdata->cea_video_id = drm_match_cea_mode(mode);
>  }
>  
>  static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
> diff --git a/drivers/gpu/drm/exynos/regs-hdmi.h b/drivers/gpu/drm/exynos/regs-hdmi.h
> index 169667a..a0507dc 100644
> --- a/drivers/gpu/drm/exynos/regs-hdmi.h
> +++ b/drivers/gpu/drm/exynos/regs-hdmi.h
> @@ -361,9 +361,11 @@
>  
>  /* AUI bit definition */
>  #define HDMI_AUI_CON_NO_TRAN		(0 << 0)
> +#define HDMI_AUI_CON_EVERY_VSYNC	(1 << 1)
>  
>  /* VSI bit definition */
>  #define HDMI_VSI_CON_DO_NOT_TRANSMIT	(0 << 0)
> +#define HDMI_VSI_CON_EVERY_VSYNC	(1 << 1)
>  
>  /* HDCP related registers */
>  #define HDMI_HDCP_SHA1(n)		HDMI_CORE_BASE(0x7000 + 4 * (n))
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2016-11-07  1:45 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20161026123635eucas1p2ddd97eff849b9f633ea2d482fbd82c34@eucas1p2.samsung.com>
2016-10-26 12:36 ` [PATCH] drm/exynos/hdmi: refactor infoframe code Andrzej Hajda
2016-11-07  1:45   ` Inki Dae [this message]
2016-11-07  8:05     ` Andrzej Hajda
2016-11-07  8:14       ` Inki Dae
2016-11-07 15:04         ` Andrzej Hajda

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=581FDCA6.3050405@samsung.com \
    --to=inki.dae@samsung.com \
    --cc=a.hajda@samsung.com \
    --cc=b.zolnierkie@samsung.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=m.szyprowski@samsung.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.