diff options
author | Oliver Brown <oliver.brown@nxp.com> | 2019-02-05 02:54:27 +0200 |
---|---|---|
committer | Oliver Brown <oliver.brown@nxp.com> | 2019-02-12 07:15:36 -0600 |
commit | 90c44287a9ae5a9976855ccc47cb5f39b69d1e12 (patch) | |
tree | 4bb7811fcd1dab9c2320545d00b3ae71c8d25b79 /drivers/soc | |
parent | ddefa9eee4d8d6a9fe500e2228c3417a01d7ae6a (diff) |
MLK-20890-1 soc: imx8: Add support to read HDCP fuse.
Added function to read HDCP disable fuse.
Signed-off-by: Oliver Brown <oliver.brown@nxp.com>
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/imx/soc-imx8.c | 93 |
1 files changed, 91 insertions, 2 deletions
diff --git a/drivers/soc/imx/soc-imx8.c b/drivers/soc/imx/soc-imx8.c index 4f4899f8663a..4f773cbedb4a 100644 --- a/drivers/soc/imx/soc-imx8.c +++ b/drivers/soc/imx/soc-imx8.c @@ -275,7 +275,7 @@ static ssize_t imx8_get_soc_uid(struct device *dev, } static struct device_attribute imx8_uid = - __ATTR(soc_uid, S_IRUGO, imx8_get_soc_uid, NULL); + __ATTR(soc_uid, 0444, imx8_get_soc_uid, NULL); static void __init imx8mq_noc_init(void) { @@ -516,7 +516,96 @@ int check_m4_enabled(void) m4_is_enabled = !!res.a0; if (m4_is_enabled) - printk("M4 is started\n"); + pr_info("M4 is started\n"); return 0; } + +#define IMX8MQ_FEATURE_BITS 0x450 +#define IMX8MQ_FEATURE_HDCP (1<<27) + +static bool imx8mq_soc_is_hdcp_available(void) +{ + struct device_node *np; + void __iomem *base; + + u32 val = 0xffffffff; /* HDCP disabled */ + + np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp"); + if (!np) { + pr_warn("failed to find ocotp node\n"); + return val; + } + + base = of_iomap(np, 0); + if (!base) { + pr_warn("failed to map ocotp\n"); + goto put_node; + } + + val = readl_relaxed(base + IMX8MQ_FEATURE_BITS); + pr_debug("%s(), val 0x%08x hdcp %u\n", __func__, val, + (val & IMX8MQ_FEATURE_HDCP)); + + iounmap(base); + +put_node: + of_node_put(np); + + if ((val & IMX8MQ_FEATURE_HDCP) == 0) { + pr_debug("HDCP is enabled\n"); + return true; + } + pr_debug("HDCP is disabled\n"); + return false; +} + +#define IMX8QM_FEATURE_BITS 0x3 +#define IMX8QM_FEATURE_HDCP (1<<3) + +static int imx8qm_soc_is_hdcp_available(void) +{ + sc_ipc_t mu_ipc; + sc_ipc_id_t mu_id; + uint32_t fuse = 0xffffffff; + int ret; + + ret = sc_ipc_getMuID(&mu_id); + if (ret) { + pr_warn("sc_ipc_getMuID() can't obtain mu id SCI! %d\n", + ret); + return false; + } + + ret = sc_ipc_open(&mu_ipc, mu_id); + if (ret) { + pr_warn("sc_ipc_getMuID() can't open MU channel to SCU! %d\n", + ret); + return false; + } + + ret = sc_misc_otp_fuse_read(mu_ipc, IMX8QM_FEATURE_BITS, &fuse); + sc_ipc_close(mu_ipc); + if (ret) { + pr_warn("sc_misc_otp_fuse_read fail! %d\n", ret); + return false; + } + + pr_debug("mu_id = %d, fuse[3] = 0x%x\n", mu_id, fuse); + + if ((fuse & IMX8QM_FEATURE_HDCP) == 0) { + pr_debug("HDCP is enabled\n"); + return true; + } + pr_debug("HDCP is disabled\n"); + return false; +} + +bool check_hdcp_enabled(void) +{ + if (cpu_is_imx8mq()) + return imx8mq_soc_is_hdcp_available(); + if (cpu_is_imx8qm()) + return imx8qm_soc_is_hdcp_available(); + return false; +} |