| From 859a288601a5dd6322c0153da7d2baf1dba64922 Mon Sep 17 00:00:00 2001 |
| From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> |
| Date: Tue, 17 Jan 2017 10:29:03 +0200 |
| Subject: [PATCH 248/255] drm: bridge: dw-hdmi: Reject invalid product IDs |
| |
| The DWC HDMI TX can be recognized by the two product identification |
| registers. If the registers don't read as expect the IP will be very |
| different than what the driver has been designed for, or will be |
| misconfigured in a way that makes it non-operational (invalid memory |
| address, incorrect clocks, ...). We should reject this situation with an |
| error. |
| |
| While this isn't critical for proper operation with supported IPs at the |
| moment, the driver will soon gain automatic device-specific handling |
| based on runtime device identification. This change makes it easier to |
| implement that without having to default to a random guess in case the |
| device can't be identified. |
| |
| While at it print a readable version number in the device identification |
| message instead of raw register values. |
| |
| Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> |
| Reviewed-by: Jose Abreu <joabreu@synopsys.com> |
| Signed-off-by: Archit Taneja <architt@codeaurora.org> |
| Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-14-laurent.pinchart+renesas@ideasonboard.com |
| (cherry picked from commit 0527e12e8264ae96b1fcc550b4a9e5940f4ffc30) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/gpu/drm/bridge/dw-hdmi.c | 25 +++++++++++++++++++------ |
| drivers/gpu/drm/bridge/dw-hdmi.h | 8 ++++++++ |
| 2 files changed, 27 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/gpu/drm/bridge/dw-hdmi.c |
| +++ b/drivers/gpu/drm/bridge/dw-hdmi.c |
| @@ -1832,6 +1832,9 @@ __dw_hdmi_probe(struct platform_device * |
| int irq; |
| int ret; |
| u32 val = 1; |
| + u16 version; |
| + u8 prod_id0; |
| + u8 prod_id1; |
| u8 config0; |
| u8 config1; |
| |
| @@ -1914,12 +1917,22 @@ __dw_hdmi_probe(struct platform_device * |
| } |
| |
| /* Product and revision IDs */ |
| - dev_info(dev, |
| - "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n", |
| - hdmi_readb(hdmi, HDMI_DESIGN_ID), |
| - hdmi_readb(hdmi, HDMI_REVISION_ID), |
| - hdmi_readb(hdmi, HDMI_PRODUCT_ID0), |
| - hdmi_readb(hdmi, HDMI_PRODUCT_ID1)); |
| + version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) |
| + | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); |
| + prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0); |
| + prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1); |
| + |
| + if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX || |
| + (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) { |
| + dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n", |
| + version, prod_id0, prod_id1); |
| + ret = -ENODEV; |
| + goto err_iahb; |
| + } |
| + |
| + dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n", |
| + version >> 12, version & 0xfff, |
| + prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without"); |
| |
| initialize_hdmi_ih_mutes(hdmi); |
| |
| --- a/drivers/gpu/drm/bridge/dw-hdmi.h |
| +++ b/drivers/gpu/drm/bridge/dw-hdmi.h |
| @@ -545,6 +545,14 @@ |
| #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12 |
| |
| enum { |
| +/* PRODUCT_ID0 field values */ |
| + HDMI_PRODUCT_ID0_HDMI_TX = 0xa0, |
| + |
| +/* PRODUCT_ID1 field values */ |
| + HDMI_PRODUCT_ID1_HDCP = 0xc0, |
| + HDMI_PRODUCT_ID1_HDMI_RX = 0x02, |
| + HDMI_PRODUCT_ID1_HDMI_TX = 0x01, |
| + |
| /* CONFIG0_ID field values */ |
| HDMI_CONFIG0_I2S = 0x10, |
| |