[DOWNSTREAM]: iommu/tegra241-cmdqv: WAR for 64-bit writes on NV HV
NVIDIA’s hypervisor does not support 64-bit writes to consecutive two 32-bit registers e.g., VCMDQ_BASE_LO and VCMDQ_BASE_HI. The driver currently issues a 64-bit write to such registers, which works fine on real hardware but fails under NV HV. This is not a functional bug in the driver, but rather a quirk of the hypervisor which does not fully emulate the HW behavior. Add a workaround to split the write into two 32-bit accesses. Bug 5111712 Change-Id: I6fb6a926a80326e2d7a8a2ec9e475106af843f7c Signed-off-by: Ashish Mhetre <amhetre@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/3rdparty/canonical/linux-noble/+/3439898 Reviewed-by: Pritesh Raithatha <praithatha@nvidia.com> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com> GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
@@ -83,7 +83,9 @@
|
|||||||
#define VCMDQ_LOG2SIZE GENMASK(4, 0)
|
#define VCMDQ_LOG2SIZE GENMASK(4, 0)
|
||||||
|
|
||||||
#define TEGRA241_VCMDQ_BASE 0x00000
|
#define TEGRA241_VCMDQ_BASE 0x00000
|
||||||
|
#define TEGRA241_VCMDQ_BASE_H 0x00004
|
||||||
#define TEGRA241_VCMDQ_CONS_INDX_BASE 0x00008
|
#define TEGRA241_VCMDQ_CONS_INDX_BASE 0x00008
|
||||||
|
#define TEGRA241_VCMDQ_CONS_INDX_BASE_H 0x0000C
|
||||||
|
|
||||||
/* VINTF logical-VCMDQ pages */
|
/* VINTF logical-VCMDQ pages */
|
||||||
#define TEGRA241_VINTFi_PAGE0(i) (TEGRA241_VINTF_PAGE_BASE + SZ_128K*(i))
|
#define TEGRA241_VINTFi_PAGE0(i) (TEGRA241_VINTF_PAGE_BASE + SZ_128K*(i))
|
||||||
@@ -367,8 +369,10 @@ static void tegra241_vcmdq_hw_deinit(struct tegra241_vcmdq *vcmdq)
|
|||||||
}
|
}
|
||||||
writel_relaxed(0, REG_VCMDQ_PAGE0(vcmdq, PROD));
|
writel_relaxed(0, REG_VCMDQ_PAGE0(vcmdq, PROD));
|
||||||
writel_relaxed(0, REG_VCMDQ_PAGE0(vcmdq, CONS));
|
writel_relaxed(0, REG_VCMDQ_PAGE0(vcmdq, CONS));
|
||||||
writeq_relaxed(0, REG_VCMDQ_PAGE1(vcmdq, BASE));
|
writel_relaxed(0, REG_VCMDQ_PAGE1(vcmdq, BASE_H));
|
||||||
writeq_relaxed(0, REG_VCMDQ_PAGE1(vcmdq, CONS_INDX_BASE));
|
writel_relaxed(0, REG_VCMDQ_PAGE1(vcmdq, BASE));
|
||||||
|
writel_relaxed(0, REG_VCMDQ_PAGE1(vcmdq, CONS_INDX_BASE_H));
|
||||||
|
writel_relaxed(0, REG_VCMDQ_PAGE1(vcmdq, CONS_INDX_BASE));
|
||||||
|
|
||||||
gerrorn = readl_relaxed(REG_VCMDQ_PAGE0(vcmdq, GERRORN));
|
gerrorn = readl_relaxed(REG_VCMDQ_PAGE0(vcmdq, GERRORN));
|
||||||
gerror = readl_relaxed(REG_VCMDQ_PAGE0(vcmdq, GERROR));
|
gerror = readl_relaxed(REG_VCMDQ_PAGE0(vcmdq, GERROR));
|
||||||
@@ -390,7 +394,8 @@ static int tegra241_vcmdq_hw_init(struct tegra241_vcmdq *vcmdq)
|
|||||||
tegra241_vcmdq_hw_deinit(vcmdq);
|
tegra241_vcmdq_hw_deinit(vcmdq);
|
||||||
|
|
||||||
/* Configure and enable VCMDQ */
|
/* Configure and enable VCMDQ */
|
||||||
writeq_relaxed(vcmdq->cmdq.q.q_base, REG_VCMDQ_PAGE1(vcmdq, BASE));
|
writel_relaxed(upper_32_bits(vcmdq->cmdq.q.q_base), REG_VCMDQ_PAGE1(vcmdq, BASE_H));
|
||||||
|
writel_relaxed(lower_32_bits(vcmdq->cmdq.q.q_base), REG_VCMDQ_PAGE1(vcmdq, BASE));
|
||||||
|
|
||||||
ret = vcmdq_write_config(vcmdq, VCMDQ_EN);
|
ret = vcmdq_write_config(vcmdq, VCMDQ_EN);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|||||||
Reference in New Issue
Block a user