diff --git a/drivers/gpu/drm/tegra/nvenc.c b/drivers/gpu/drm/tegra/nvenc.c index a5605a72..5f6cead8 100644 --- a/drivers/gpu/drm/tegra/nvenc.c +++ b/drivers/gpu/drm/tegra/nvenc.c @@ -21,7 +21,11 @@ #include #include +#include + +#include #include +#include #include "drm.h" #include "falcon.h" @@ -33,6 +37,7 @@ #define NVENC_TFBIF_ACTMON_ACTIVE_BORPS 0x1850 #define NVENC_TFBIF_ACTMON_ACTIVE_WEIGHT 0x1854 #define NVENC_AXI_RW_BANDWIDTH 512 +#define NVENC_SEC_INTF_CRC_CTRL 0xe000 #define NVENC_TFBIF_ACTMON_ACTIVE_MASK_STARVED BIT(0) #define NVENC_TFBIF_ACTMON_ACTIVE_MASK_STALLED BIT(1) @@ -44,6 +49,7 @@ struct nvenc_config { unsigned int version; bool supports_sid; bool supports_timestamping; + bool has_crc_enable; unsigned int num_instances; }; @@ -60,10 +66,31 @@ struct nvenc { struct devfreq_dev_profile *devfreq_profile; struct icc_path *icc_write; + bool can_enable_crc; + /* Platform configuration */ const struct nvenc_config *config; }; +static bool blf_write_allowed(u32 offset) +{ + void __iomem *regs = ioremap(0x13a10000 + offset, 12); + u32 val; + + val = readl(regs + 0x8); + if (!(val & 0x20000)) { + iounmap(regs); + return true; + } + + val = readl(regs + 0x4); + iounmap(regs); + if (val & BIT(1)) + return true; + + return false; +} + static inline struct nvenc *to_nvenc(struct tegra_drm_client *client) { return container_of(client, struct nvenc, client); @@ -484,6 +511,9 @@ static __maybe_unused int nvenc_runtime_resume(struct device *dev) host1x_actmon_enable(&nvenc->client.base); + if (nvenc->can_enable_crc) + nvenc_writel(nvenc, 0x1, NVENC_SEC_INTF_CRC_CTRL); + return 0; disable: @@ -611,6 +641,7 @@ static const struct nvenc_config nvenc_t234_config = { .supports_sid = true, .supports_timestamping = true, .num_instances = 1, + .has_crc_enable = true, }; static const struct of_device_id tegra_nvenc_of_match[] = { @@ -711,6 +742,12 @@ static int nvenc_probe(struct platform_device *pdev) goto exit_actmon; } + if (nvenc->config->has_crc_enable) { + nvenc->can_enable_crc = + !tegra_platform_is_silicon() || + blf_write_allowed(0x67a0); + } + nvenc->hwpm.dev = dev; nvenc->hwpm.regs = nvenc->regs; tegra_drm_hwpm_register(&nvenc->hwpm, pdev->resource[0].start, diff --git a/drivers/gpu/drm/tegra/ofa.c b/drivers/gpu/drm/tegra/ofa.c index 575ef462..23758f97 100644 --- a/drivers/gpu/drm/tegra/ofa.c +++ b/drivers/gpu/drm/tegra/ofa.c @@ -18,7 +18,11 @@ #include #include +#include + +#include #include +#include #include "drm.h" #include "falcon.h" @@ -32,6 +36,7 @@ #define OFA_TFBIF_ACTMON_ACTIVE_WEIGHT 0x1454 #define OFA_SAFETY_RAM_INIT_REQ 0x3320 #define OFA_SAFETY_RAM_INIT_DONE 0x3324 +#define OFA_SEC_INTF_CRC_CTRL 0xe000 #define OFA_TFBIF_ACTMON_ACTIVE_MASK_STARVED BIT(0) #define OFA_TFBIF_ACTMON_ACTIVE_MASK_STALLED BIT(1) @@ -56,10 +61,31 @@ struct ofa { struct devfreq *devfreq; struct devfreq_dev_profile *devfreq_profile; + bool can_enable_crc; + /* Platform configuration */ const struct ofa_config *config; }; +static bool blf_write_allowed(u32 offset) +{ + void __iomem *regs = ioremap(0x13a10000 + offset, 12); + u32 val; + + val = readl(regs + 0x8); + if (!(val & 0x20000)) { + iounmap(regs); + return true; + } + + val = readl(regs + 0x4); + iounmap(regs); + if (val & BIT(1)) + return true; + + return false; +} + static inline struct ofa *to_ofa(struct tegra_drm_client *client) { return container_of(client, struct ofa, client); @@ -421,6 +447,9 @@ static __maybe_unused int ofa_runtime_resume(struct device *dev) host1x_actmon_enable(&ofa->client.base); + if (ofa->can_enable_crc) + ofa_writel(ofa, 0x1, OFA_SEC_INTF_CRC_CTRL); + return 0; disable: @@ -589,6 +618,10 @@ static int ofa_probe(struct platform_device *pdev) goto exit_actmon; } + ofa->can_enable_crc = + !tegra_platform_is_silicon() || + (ofa->config == &ofa_t234_config && blf_write_allowed(0x6960)); + ofa->hwpm.dev = dev; ofa->hwpm.regs = ofa->regs; tegra_drm_hwpm_register(&ofa->hwpm, pdev->resource[0].start, diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c index ada3dcd8..b6684373 100644 --- a/drivers/gpu/drm/tegra/vic.c +++ b/drivers/gpu/drm/tegra/vic.c @@ -22,7 +22,11 @@ #include #include +#include + +#include #include +#include #include "drm.h" #include "falcon.h" @@ -30,11 +34,14 @@ #include "vic.h" #include "hwpm.h" +#define VIC_SEC_INTF_CRC_CTRL 0xe000 + struct vic_config { const char *firmware; unsigned int version; bool supports_sid; bool supports_timestamping; + bool has_crc_enable; }; struct vic { @@ -52,11 +59,31 @@ struct vic { struct icc_path *icc_write; bool can_use_context; + bool can_enable_crc; /* Platform configuration */ const struct vic_config *config; }; +static bool blf_write_allowed(u32 offset) +{ + void __iomem *regs = ioremap(0x13a10000 + offset, 12); + u32 val; + + val = readl(regs + 0x8); + if (!(val & 0x20000)) { + iounmap(regs); + return true; + } + + val = readl(regs + 0x4); + iounmap(regs); + if (val & BIT(1)) + return true; + + return false; +} + static inline struct vic *to_vic(struct tegra_drm_client *client) { return container_of(client, struct vic, client); @@ -541,6 +568,9 @@ static int __maybe_unused vic_runtime_resume(struct device *dev) host1x_actmon_enable(&vic->client.base); + if (vic->can_enable_crc) + vic_writel(vic, 0x1, VIC_SEC_INTF_CRC_CTRL); + return 0; assert: @@ -676,6 +706,7 @@ static const struct vic_config vic_t234_config = { .version = 0x23, .supports_sid = true, .supports_timestamping = true, + .has_crc_enable = true, }; static const struct of_device_id tegra_vic_of_match[] = { @@ -779,6 +810,12 @@ static int vic_probe(struct platform_device *pdev) goto exit_actmon; } + if (vic->config->has_crc_enable) { + vic->can_enable_crc = + !tegra_platform_is_silicon() || + blf_write_allowed(0x9500); + } + vic->hwpm.dev = dev; vic->hwpm.regs = vic->regs; tegra_drm_hwpm_register(&vic->hwpm, pdev->resource[0].start,