diff options
author | Ken Chang <kenc@nvidia.com> | 2011-08-30 05:59:23 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:01:41 -0400 |
commit | 09ebab3009c2adf9de28258db124c111c673de36 (patch) | |
tree | 88db49f33b985b5243894aa116a3fca580574cb7 /drivers/video | |
parent | d4351b51ebd12d3088702735419c7c9a51b45249 (diff) |
video:tegra:dc: fix hdcp hotplug issue
bit WRITE16 of HDMI_NV_PDISP_KEY_CTRL_0 shall be polled until it
reports DONE, which is value 0 to ensure the write is complete.
bug 858744
bug 861719
(cherry picked from commit d37336f3965cd1071afb6b03b979b0409ee480f1)
(reviewed on http://git-master/r/49821)
Change-Id: I38fe861a265db7d969f3a15f164724294d627cfd
Reviewed-on: http://git-master/r/52852
Tested-by: Ken Chang <kenc@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Rebase-Id: Rde95d37c2dfa5d1a169a3aa2a80f304f25b94c03
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/tegra/dc/nvhdcp.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/drivers/video/tegra/dc/nvhdcp.c b/drivers/video/tegra/dc/nvhdcp.c index 4fd978781..10e09c54b 100644 --- a/drivers/video/tegra/dc/nvhdcp.c +++ b/drivers/video/tegra/dc/nvhdcp.c | |||
@@ -420,7 +420,7 @@ static int wait_hdcp_ctrl(struct tegra_dc_hdmi_data *hdmi, u32 mask, u32 *v) | |||
420 | 420 | ||
421 | do { | 421 | do { |
422 | ctrl = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_RG_HDCP_CTRL); | 422 | ctrl = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_RG_HDCP_CTRL); |
423 | if ((ctrl | (mask))) { | 423 | if ((ctrl & mask)) { |
424 | if (v) | 424 | if (v) |
425 | *v = ctrl; | 425 | *v = ctrl; |
426 | break; | 426 | break; |
@@ -435,19 +435,18 @@ static int wait_hdcp_ctrl(struct tegra_dc_hdmi_data *hdmi, u32 mask, u32 *v) | |||
435 | return 0; | 435 | return 0; |
436 | } | 436 | } |
437 | 437 | ||
438 | /* wait for any bits in mask to be set in HDMI_NV_PDISP_KEY_CTRL | 438 | /* wait for bits in mask to be set to value in HDMI_NV_PDISP_KEY_CTRL |
439 | * waits up to 100mS */ | 439 | * waits up to 100mS */ |
440 | static int wait_key_ctrl(struct tegra_dc_hdmi_data *hdmi, u32 mask) | 440 | static int wait_key_ctrl(struct tegra_dc_hdmi_data *hdmi, u32 mask, u32 value) |
441 | { | 441 | { |
442 | int retries = 101; | 442 | int retries = 101; |
443 | u32 ctrl; | 443 | u32 ctrl; |
444 | 444 | ||
445 | do { | 445 | do { |
446 | msleep(1); | ||
446 | ctrl = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_KEY_CTRL); | 447 | ctrl = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_KEY_CTRL); |
447 | if ((ctrl | (mask))) | 448 | if (((ctrl ^ value) & mask) == 0) |
448 | break; | 449 | break; |
449 | if (retries > 1) | ||
450 | msleep(1); | ||
451 | } while (--retries); | 450 | } while (--retries); |
452 | if (!retries) { | 451 | if (!retries) { |
453 | nvhdcp_err("key ctrl read timeout (mask=0x%x)\n", mask); | 452 | nvhdcp_err("key ctrl read timeout (mask=0x%x)\n", mask); |
@@ -667,7 +666,7 @@ static int load_kfuse(struct tegra_dc_hdmi_data *hdmi) | |||
667 | tegra_hdmi_writel(hdmi, ctrl | PKEY_REQUEST_RELOAD_TRIGGER | 666 | tegra_hdmi_writel(hdmi, ctrl | PKEY_REQUEST_RELOAD_TRIGGER |
668 | | LOCAL_KEYS , HDMI_NV_PDISP_KEY_CTRL); | 667 | | LOCAL_KEYS , HDMI_NV_PDISP_KEY_CTRL); |
669 | 668 | ||
670 | e = wait_key_ctrl(hdmi, PKEY_LOADED); | 669 | e = wait_key_ctrl(hdmi, PKEY_LOADED, PKEY_LOADED); |
671 | if (e) { | 670 | if (e) { |
672 | nvhdcp_err("key reload timeout\n"); | 671 | nvhdcp_err("key reload timeout\n"); |
673 | return -EIO; | 672 | return -EIO; |
@@ -705,7 +704,7 @@ static int load_kfuse(struct tegra_dc_hdmi_data *hdmi) | |||
705 | tegra_hdmi_writel(hdmi, tmp, HDMI_NV_PDISP_KEY_CTRL); | 704 | tegra_hdmi_writel(hdmi, tmp, HDMI_NV_PDISP_KEY_CTRL); |
706 | 705 | ||
707 | /* wait for WRITE16 to complete */ | 706 | /* wait for WRITE16 to complete */ |
708 | e = wait_key_ctrl(hdmi, 0x10); /* WRITE16 */ | 707 | e = wait_key_ctrl(hdmi, 0x10, 0); /* WRITE16 */ |
709 | if (e) { | 708 | if (e) { |
710 | nvhdcp_err("key write timeout\n"); | 709 | nvhdcp_err("key write timeout\n"); |
711 | return -EIO; | 710 | return -EIO; |