From: Zheng Yang Date: Thu, 21 May 2015 05:45:22 +0000 (+0800) Subject: HDMI: support show edid status. X-Git-Tag: firefly_0821_release~4141 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=71e8a27d623263591ae0c885804682d664cede79;p=firefly-linux-kernel-4.4.55.git HDMI: support show edid status. Use /sys/class/display/HDMI/debug node to show sink EDID status and raw status. Signed-off-by: Zheng Yang --- diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c index 98fdeaee7b61..4c65868f8397 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c @@ -123,7 +123,7 @@ static void hdmi_wq_set_video(struct hdmi *hdmi) static void hdmi_wq_parse_edid(struct hdmi *hdmi) { struct hdmi_edid *pedid; - unsigned char *buff = NULL; + int rc = HDMI_ERROR_SUCESS, extendblock = 0, i, trytimes; if (hdmi == NULL) @@ -136,8 +136,8 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi) memset(pedid, 0, sizeof(struct hdmi_edid)); INIT_LIST_HEAD(&pedid->modelist); - buff = kmalloc(HDMI_EDID_BLOCK_SIZE, GFP_KERNEL); - if (buff == NULL) { + pedid->raw[0] = kmalloc(HDMI_EDID_BLOCK_SIZE, GFP_KERNEL); + if (pedid->raw[0] == NULL) { dev_err(hdmi->dev, "[%s] can not allocate memory for edid buff.\n", __func__); @@ -154,15 +154,15 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi) for (trytimes = 0; trytimes < 3; trytimes++) { if (trytimes) msleep(50); - memset(buff, 0 , HDMI_EDID_BLOCK_SIZE); - rc = hdmi->ops->getedid(hdmi, 0, buff); + memset(pedid->raw[0], 0 , HDMI_EDID_BLOCK_SIZE); + rc = hdmi->ops->getedid(hdmi, 0, pedid->raw[0]); if (rc) { dev_err(hdmi->dev, "[HDMI] read edid base block error\n"); continue; } - rc = hdmi_edid_parse_base(buff, &extendblock, pedid); + rc = hdmi_edid_parse_base(pedid->raw[0], &extendblock, pedid); if (rc) { dev_err(hdmi->dev, "[HDMI] parse edid base block error\n"); @@ -174,12 +174,20 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi) if (rc) goto out; - for (i = 1; i < extendblock + 1; i++) { + for (i = 1; (i < extendblock + 1) && (i < HDMI_MAX_EDID_BLOCK); i++) { + pedid->raw[i] = kmalloc(HDMI_EDID_BLOCK_SIZE, GFP_KERNEL); + if (pedid->raw[i] == NULL) { + dev_err(hdmi->dev, + "[%s] can not allocate memory for edid buff.\n", + __func__); + rc = HDMI_ERROR_FALSE; + goto out; + } for (trytimes = 0; trytimes < 3; trytimes++) { if (trytimes) msleep(20); - memset(buff, 0 , HDMI_EDID_BLOCK_SIZE); - rc = hdmi->ops->getedid(hdmi, i, buff); + memset(pedid->raw[i], 0 , HDMI_EDID_BLOCK_SIZE); + rc = hdmi->ops->getedid(hdmi, i, pedid->raw[i]); if (rc) { dev_err(hdmi->dev, "[HDMI] read edid block %d error\n", @@ -187,7 +195,7 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi) continue; } - rc = hdmi_edid_parse_extensions(buff, pedid); + rc = hdmi_edid_parse_extensions(pedid->raw[i], pedid); if (rc) { dev_err(hdmi->dev, "[HDMI] parse edid block %d error\n", @@ -200,7 +208,6 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi) } } out: - kfree(buff); rc = hdmi_ouputmode_select(hdmi, rc); } @@ -234,6 +241,7 @@ static void hdmi_wq_remove(struct hdmi *hdmi) { struct list_head *pos, *n; struct rk_screen screen; + int i; DBG("%s", __func__); if (hdmi->ops->remove) @@ -249,6 +257,8 @@ static void hdmi_wq_remove(struct hdmi *hdmi) list_del(pos); kfree(pos); } + for (i = 0; i < HDMI_MAX_EDID_BLOCK; i++) + kfree(hdmi->edid.raw[i]); kfree(hdmi->edid.audio); if (hdmi->edid.specs) { kfree(hdmi->edid.specs->modedb); diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c index 25f938f0c4b0..af86044b315f 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c @@ -532,6 +532,7 @@ int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok) if (edid_ok != HDMI_ERROR_SUCESS) { dev_err(hdmi->dev, "warning: EDID error, assume sink as HDMI !!!!"); + hdmi->edid.status = -1; hdmi->edid.sink_hdmi = 1; hdmi->edid.baseaudio_support = 1; hdmi->edid.ycbcr444 = 0; diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-sysfs.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-sysfs.c index 95d60eb18ded..3d9d5c0cc2c3 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi-sysfs.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-sysfs.c @@ -304,6 +304,33 @@ static int hdmi_get_monspecs(struct rk_display_device *device, return 0; } +static int hdmi_get_debug(struct rk_display_device *device, char *buf) +{ + struct hdmi *hdmi = device->priv_data; + char *buff; + int i, j, len = 0; + + if (!hdmi) + return 0; + len += snprintf(buf+len, PAGE_SIZE, "EDID status:%s\n", + hdmi->edid.status ? "False" : "Okay"); + len += snprintf(buf+len, PAGE_SIZE, "Raw Data:"); + mutex_lock(&hdmi->lock); + for (i = 0; i < HDMI_MAX_EDID_BLOCK; i++) { + if (!hdmi->edid.raw[i]) + break; + buff = hdmi->edid.raw[i]; + for (j = 0; j < HDMI_EDID_BLOCK_SIZE; j++) { + if (j % 16 == 0) + len += snprintf(buf+len, PAGE_SIZE, "\n"); + len += snprintf(buf+len, PAGE_SIZE, "0x%02x, ", + buff[j]); + } + } + mutex_unlock(&hdmi->lock); + return len; +} + static struct rk_display_ops hdmi_display_ops = { .setenable = hdmi_set_enable, .getenable = hdmi_get_enable, @@ -319,6 +346,7 @@ static struct rk_display_ops hdmi_display_ops = { .getmonspecs = hdmi_get_monspecs, .setscale = hdmi_set_scale, .getscale = hdmi_get_scale, + .getdebug = hdmi_get_debug, }; static int hdmi_display_probe(struct rk_display_device *device, void *devdata) diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi.h b/drivers/video/rockchip/hdmi/rockchip-hdmi.h index 33b8598554ee..a47c38a9676b 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi.h +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi.h @@ -263,6 +263,7 @@ struct hdmi_audio { u32 word_length; /*Audio data word length*/ }; +#define HDMI_MAX_EDID_BLOCK 8 /* HDMI EDID Information */ struct hdmi_edid { unsigned char sink_hdmi; /*HDMI display device flag*/ @@ -294,6 +295,9 @@ struct hdmi_edid { unsigned char baseaudio_support; struct hdmi_audio *audio; /*Device supported audio info*/ unsigned int audio_num; /*Device supported audio type number*/ + + unsigned int status; /*EDID read status, success or failed*/ + char *raw[HDMI_MAX_EDID_BLOCK]; /*Raw EDID Data*/ }; struct hdmi;