From ee5079ad5b5d6ceb3c8f74422cfc470f3a24f220 Mon Sep 17 00:00:00 2001 From: Praveen K Date: Mon, 5 Jul 2021 12:38:30 +0000 Subject: [PATCH] video: tegra: host: nvdla: Add Fuse check for t234 - Check for fuse register to identify cases where a DLA t234 instance is floorswept Jira DLA-4785 Bug 200748079 Change-Id: I78c30440806578fea86b1c5fe6f247c8117e534f Signed-off-by: Praveen K Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2554212 Reviewed-by: Amit Sharma (SW-TEGRA) Reviewed-by: Anup Mahindre Reviewed-by: svc_kernel_abi Reviewed-by: Ken Adams Reviewed-by: Bharat Nihalani Reviewed-by: mobile promotions Tested-by: mobile promotions GVS: Gerrit_Virtual_Submit --- drivers/video/tegra/host/nvdla/nvdla.c | 94 ++++++++++++++++++++++++++ drivers/video/tegra/host/nvdla/nvdla.h | 17 +++++ 2 files changed, 111 insertions(+) diff --git a/drivers/video/tegra/host/nvdla/nvdla.c b/drivers/video/tegra/host/nvdla/nvdla.c index 749f0f4c..f29af1d2 100644 --- a/drivers/video/tegra/host/nvdla/nvdla.c +++ b/drivers/video/tegra/host/nvdla/nvdla.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "dev.h" @@ -691,6 +692,76 @@ out: return ret; } +static int nvhost_nvdla_read_chip_option_register(struct platform_device *pdev) +{ + /* Read floor sweeping info using nvmem api + * See Bug 200748079 + */ + struct nvmem_cell *cell = NULL; + struct device *dev = &pdev->dev; + size_t len = 0ULL; + char *pbuf = NULL; + int ret = 0; + + cell = nvmem_cell_get(dev, "dla-disable"); + + if (IS_ERR(cell)) { + + dev_err(dev, + "nvmem_cell_get error %ld. Assuming DLA instances are available\n" + , PTR_ERR(cell)); + + ret = 0; + /* Throwing a fuse read error + * and reverting to default + * behaviour assuming that the + * DLA instance exists + */ + goto out; + } + + pbuf = nvmem_cell_read(cell, &len); + + nvmem_cell_put(cell); + + if (IS_ERR(pbuf)) { + + dev_err(dev, + "nvmem_cell_read buffer error %ld. Assuming DLA instances are available\n" + , PTR_ERR(pbuf)); + + ret = 0; + /* Throwing a fuse read error + * and reverting to default + * behaviour assuming that the + * DLA instance exists + */ + goto out; + } + + if (len != FUSE_OPT_DLA_DISABLE_SIZE) { + + dev_err(dev, + "nvmem_cell_read len mismatch error. Assuming DLA instances are available\n" + ); + + ret = 0; + /* Throwing a fuse read error + * and reverting to default + * behaviour assuming that the + * DLA instance exists + */ + goto out; + } + + ret = (int)(*pbuf); + +out: + kfree(pbuf); + + return ret; +} + /* driver probe and init */ static struct of_device_id tegra_nvdla_of_match[] = { { @@ -720,6 +791,7 @@ static int nvdla_probe(struct platform_device *pdev) struct nvhost_device_data *pdata = NULL; struct nvdla_device *nvdla_dev = NULL; struct device *dev = &pdev->dev; + int fuse_ret = 0; if (pdev->dev.of_node) { const struct of_device_id *match; @@ -761,6 +833,28 @@ static int nvdla_probe(struct platform_device *pdev) goto err_no_ip; } +#if KERNEL_VERSION(4, 15, 0) > LINUX_VERSION_CODE + if (tegra_get_chipid() == TEGRA_CHIPID_TEGRA23) { +#else + if (tegra_get_chip_id() == TEGRA234) { +#endif + fuse_ret = nvhost_nvdla_read_chip_option_register(pdev); + + if ((fuse_ret & FUSE_OPT_DLA_0_DISABLED) && + (pdata->class == NV_DLA0_CLASS_ID)) { + dev_err(dev, "NVDLA0 IP is disabled in Fuse\n"); + err = -ENODEV; + goto err_no_ip; + } + + if ((fuse_ret & FUSE_OPT_DLA_1_DISABLED) && + (pdata->class == NV_DLA1_CLASS_ID)) { + dev_err(dev, "NVDLA1 IP is disabled in Fuse\n"); + err = -ENODEV; + goto err_no_ip; + } + } + dma_set_mask(dev, DMA_BIT_MASK(39)); nvdla_dev = devm_kzalloc(dev, sizeof(*nvdla_dev), GFP_KERNEL); diff --git a/drivers/video/tegra/host/nvdla/nvdla.h b/drivers/video/tegra/host/nvdla/nvdla.h index 443578ac..c53a7dc5 100644 --- a/drivers/video/tegra/host/nvdla/nvdla.h +++ b/drivers/video/tegra/host/nvdla/nvdla.h @@ -61,6 +61,23 @@ #define MAX_NUM_ACTION_LIST 1 +/** + * Return size of FUSE_OPT_DLA_DISABLE register read + */ +#define FUSE_OPT_DLA_DISABLE_SIZE 1 + +/** + * Value of FUSE_OPT_DLA_DISABLE register + * when DLA0 is disabled + */ +#define FUSE_OPT_DLA_0_DISABLED 1 + +/** + * Value of FUSE_OPT_DLA_DISABLE register + * when DLA1 is disabled + */ +#define FUSE_OPT_DLA_1_DISABLED 2 + /** * Maximum number of queue's per engine */