devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/6] drm/msm: Support a750 "software fuse" for raytracing
@ 2024-04-30 10:43 Connor Abbott
  2024-04-30 10:43 ` [PATCH v3 1/6] arm64: dts: qcom: sm8650: Fix GPU cx_mem size Connor Abbott
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Connor Abbott @ 2024-04-30 10:43 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Jun Nie, Rob Clark, Abhinav Kumar,
	Dmitry Baryshkov, Sean Paul, Marijn Suijten
  Cc: linux-arm-msm, devicetree, freedreno, Connor Abbott

On a750, Qualcomm decided to gate support for certain features behind a
"software fuse." This consists of a register in the cx_mem zone, which
is normally only writeable by the TrustZone firmware.  On bootup it is
0, and we must call an SCM method to initialize it. Then we communicate
its value to userspace. This implements all of this, copying the SCM
call from the downstream kernel and kgsl.

So far the only optional feature we use is ray tracing (i.e. the
"ray_intersection" instruction) in a pending Mesa MR [1], so that's what
we expose to userspace. There's one extra patch to write some missing
registers, which depends on the register XML bump but is otherwise
unrelated, I just included it to make things easier on myself.

Note, 'drm/msm/a7xx: Initialize a750 "software fuse"' has a compile-time
dependency on 'firmware: qcom_scm: Add gpu_init_regs call' and it
depends on 'arm64: dts: qcom: sm8650: Fix GPU cx_mem size' to avoid a
boot-time hang. The commit the latter fixes, db33633b05c0 ("arm64: dts:
qcom: sm8650: add GPU nodes"), hasn't landed upstream yet, so we can
avoid regressions by merging it first. I think the rest of the series
can go through drm/msm for 6.10 after we land the first commit in the
same tree as db33633b05c0 to make sure linux-next is never broken,
although we'll need Bjorn's ack to land 'firmware: qcom_scm: Add
gpu_init_regs call' through drm/msm.

[1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28447

Connor Abbott (6):
  arm64: dts: qcom: sm8650: Fix GPU cx_mem size
  firmware: qcom_scm: Add gpu_init_regs call
  drm/msm: Update a6xx registers
  drm/msm/a7xx: Initialize a750 "software fuse"
  drm/msm: Add MSM_PARAM_RAYTRACING uapi
  drm/msm/a7xx: Add missing register writes from downstream

 arch/arm64/boot/dts/qcom/sm8650.dtsi          |  2 +-
 drivers/firmware/qcom/qcom_scm.c              | 14 +++
 drivers/firmware/qcom/qcom_scm.h              |  3 +
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c         | 97 ++++++++++++++++++-
 drivers/gpu/drm/msm/adreno/adreno_gpu.c       |  3 +
 drivers/gpu/drm/msm/adreno/adreno_gpu.h       |  2 +
 drivers/gpu/drm/msm/registers/adreno/a6xx.xml | 28 +++++-
 include/linux/firmware/qcom/qcom_scm.h        | 23 +++++
 include/uapi/drm/msm_drm.h                    |  1 +
 9 files changed, 168 insertions(+), 5 deletions(-)

--
2.31.1

---
Changes in v3:
- Formatting/style fixes.
- Fix RB_CMP_DBG_ECO_CNTL write on a730/a740 and add comments from kgsl.
- Link to v2: https://lore.kernel.org/r/20240426-a750-raytracing-v2-0-562ac9866d63@gmail.com

---
Connor Abbott (6):
      arm64: dts: qcom: sm8650: Fix GPU cx_mem size
      firmware: qcom_scm: Add gpu_init_regs call
      drm/msm: Update a6xx registers
      drm/msm/a7xx: Initialize a750 "software fuse"
      drm/msm: Add MSM_PARAM_RAYTRACING uapi
      drm/msm/a7xx: Add missing register writes from downstream

 arch/arm64/boot/dts/qcom/sm8650.dtsi          |   2 +-
 drivers/firmware/qcom/qcom_scm.c              |  14 ++++
 drivers/firmware/qcom/qcom_scm.h              |   3 +
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c         | 102 +++++++++++++++++++++++++-
 drivers/gpu/drm/msm/adreno/adreno_gpu.c       |   3 +
 drivers/gpu/drm/msm/adreno/adreno_gpu.h       |   2 +
 drivers/gpu/drm/msm/registers/adreno/a6xx.xml |  28 ++++++-
 include/linux/firmware/qcom/qcom_scm.h        |  23 ++++++
 include/uapi/drm/msm_drm.h                    |   1 +
 9 files changed, 173 insertions(+), 5 deletions(-)
---
base-commit: 7e6b8924568d1aa476b77323df8d2bdd31bd7257
change-id: 20240426-a750-raytracing-dee7a526513b

Best regards,
-- 
Connor Abbott <cwabbott0@gmail.com>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 1/6] arm64: dts: qcom: sm8650: Fix GPU cx_mem size
  2024-04-30 10:43 [PATCH v3 0/6] drm/msm: Support a750 "software fuse" for raytracing Connor Abbott
@ 2024-04-30 10:43 ` Connor Abbott
  2024-05-02  8:03   ` Neil Armstrong
  2024-04-30 10:43 ` [PATCH v3 2/6] firmware: qcom_scm: Add gpu_init_regs call Connor Abbott
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Connor Abbott @ 2024-04-30 10:43 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Jun Nie, Rob Clark, Abhinav Kumar,
	Dmitry Baryshkov, Sean Paul, Marijn Suijten
  Cc: linux-arm-msm, devicetree, freedreno, Connor Abbott

This is doubled compared to previous GPUs. We can't access the new
SW_FUSE_VALUE register without this.

Fixes: db33633b05c0 ("arm64: dts: qcom: sm8650: add GPU nodes")
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
---
 arch/arm64/boot/dts/qcom/sm8650.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
index 658ad2b41c5a..78b8944eaab2 100644
--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
@@ -2607,7 +2607,7 @@ tcsr: clock-controller@1fc0000 {
 		gpu: gpu@3d00000 {
 			compatible = "qcom,adreno-43051401", "qcom,adreno";
 			reg = <0x0 0x03d00000 0x0 0x40000>,
-			      <0x0 0x03d9e000 0x0 0x1000>,
+			      <0x0 0x03d9e000 0x0 0x2000>,
 			      <0x0 0x03d61000 0x0 0x800>;
 			reg-names = "kgsl_3d0_reg_memory",
 				    "cx_mem",

-- 
2.31.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 2/6] firmware: qcom_scm: Add gpu_init_regs call
  2024-04-30 10:43 [PATCH v3 0/6] drm/msm: Support a750 "software fuse" for raytracing Connor Abbott
  2024-04-30 10:43 ` [PATCH v3 1/6] arm64: dts: qcom: sm8650: Fix GPU cx_mem size Connor Abbott
@ 2024-04-30 10:43 ` Connor Abbott
  2024-04-30 10:48   ` Konrad Dybcio
                     ` (2 more replies)
  2024-04-30 10:43 ` [PATCH v3 3/6] drm/msm: Update a6xx registers Connor Abbott
                   ` (3 subsequent siblings)
  5 siblings, 3 replies; 15+ messages in thread
From: Connor Abbott @ 2024-04-30 10:43 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Jun Nie, Rob Clark, Abhinav Kumar,
	Dmitry Baryshkov, Sean Paul, Marijn Suijten
  Cc: linux-arm-msm, devicetree, freedreno, Connor Abbott

This will used by drm/msm to initialize GPU registers that Qualcomm's
firmware doesn't make writeable to the kernel.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
---
 drivers/firmware/qcom/qcom_scm.c       | 14 ++++++++++++++
 drivers/firmware/qcom/qcom_scm.h       |  3 +++
 include/linux/firmware/qcom/qcom_scm.h | 23 +++++++++++++++++++++++
 3 files changed, 40 insertions(+)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 06e46267161b..f8623ad0987c 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1394,6 +1394,20 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 }
 EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh);
 
+int qcom_scm_gpu_init_regs(u32 gpu_req)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_GPU,
+		.cmd = QCOM_SCM_SVC_GPU_INIT_REGS,
+		.arginfo = QCOM_SCM_ARGS(1),
+		.args[0] = gpu_req,
+		.owner = ARM_SMCCC_OWNER_SIP,
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_gpu_init_regs);
+
 static int qcom_scm_find_dload_address(struct device *dev, u64 *addr)
 {
 	struct device_node *tcsr;
diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h
index 4532907e8489..484e030bcac9 100644
--- a/drivers/firmware/qcom/qcom_scm.h
+++ b/drivers/firmware/qcom/qcom_scm.h
@@ -138,6 +138,9 @@ int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
 #define QCOM_SCM_WAITQ_RESUME			0x02
 #define QCOM_SCM_WAITQ_GET_WQ_CTX		0x03
 
+#define QCOM_SCM_SVC_GPU			0x28
+#define QCOM_SCM_SVC_GPU_INIT_REGS		0x01
+
 /* common error codes */
 #define QCOM_SCM_V2_EBUSY	-12
 #define QCOM_SCM_ENOMEM		-5
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index aaa19f93ac43..a221a643dc12 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -115,6 +115,29 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 int qcom_scm_lmh_profile_change(u32 profile_id);
 bool qcom_scm_lmh_dcvsh_available(void);
 
+/*
+ * Request TZ to program set of access controlled registers necessary
+ * irrespective of any features
+ */
+#define QCOM_SCM_GPU_ALWAYS_EN_REQ BIT(0)
+/*
+ * Request TZ to program BCL id to access controlled register when BCL is
+ * enabled
+ */
+#define QCOM_SCM_GPU_BCL_EN_REQ BIT(1)
+/*
+ * Request TZ to program set of access controlled register for CLX feature
+ * when enabled
+ */
+#define QCOM_SCM_GPU_CLX_EN_REQ BIT(2)
+/*
+ * Request TZ to program tsense ids to access controlled registers for reading
+ * gpu temperature sensors
+ */
+#define QCOM_SCM_GPU_TSENSE_EN_REQ BIT(3)
+
+int qcom_scm_gpu_init_regs(u32 gpu_req);
+
 #ifdef CONFIG_QCOM_QSEECOM
 
 int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id);

-- 
2.31.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 3/6] drm/msm: Update a6xx registers
  2024-04-30 10:43 [PATCH v3 0/6] drm/msm: Support a750 "software fuse" for raytracing Connor Abbott
  2024-04-30 10:43 ` [PATCH v3 1/6] arm64: dts: qcom: sm8650: Fix GPU cx_mem size Connor Abbott
  2024-04-30 10:43 ` [PATCH v3 2/6] firmware: qcom_scm: Add gpu_init_regs call Connor Abbott
@ 2024-04-30 10:43 ` Connor Abbott
  2024-04-30 10:43 ` [PATCH v3 4/6] drm/msm/a7xx: Initialize a750 "software fuse" Connor Abbott
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Connor Abbott @ 2024-04-30 10:43 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Jun Nie, Rob Clark, Abhinav Kumar,
	Dmitry Baryshkov, Sean Paul, Marijn Suijten
  Cc: linux-arm-msm, devicetree, freedreno, Connor Abbott

Update to mesa commit ff155f46a33 ("freedreno/a7xx: Register updates
from kgsl").

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
---
 drivers/gpu/drm/msm/registers/adreno/a6xx.xml | 28 ++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/registers/adreno/a6xx.xml b/drivers/gpu/drm/msm/registers/adreno/a6xx.xml
index 78524aaab9d4..43fe90c12679 100644
--- a/drivers/gpu/drm/msm/registers/adreno/a6xx.xml
+++ b/drivers/gpu/drm/msm/registers/adreno/a6xx.xml
@@ -1227,6 +1227,7 @@ to upconvert to 32b float internally?
 		<bitfield name="DEBBUS_INTR_0" pos="26" type="boolean"/>
 		<bitfield name="DEBBUS_INTR_1" pos="27" type="boolean"/>
 		<bitfield name="TSBWRITEERROR" pos="28" type="boolean" variants="A7XX-"/>
+		<bitfield name="SWFUSEVIOLATION" pos="29" type="boolean" variants="A7XX-"/>
 		<bitfield name="ISDB_CPU_IRQ" pos="30" type="boolean"/>
 		<bitfield name="ISDB_UNDER_DEBUG" pos="31" type="boolean"/>
 	</bitset>
@@ -1503,6 +1504,9 @@ to upconvert to 32b float internally?
 	<reg32 offset="0x0287" name="RBBM_CLOCK_MODE_BV_VFD" variants="A7XX-"/>
 	<reg32 offset="0x0288" name="RBBM_CLOCK_MODE_BV_GPC" variants="A7XX-"/>
 
+	<reg32 offset="0x02c0" name="RBBM_SW_FUSE_INT_STATUS" variants="A7XX-"/>
+	<reg32 offset="0x02c1" name="RBBM_SW_FUSE_INT_MASK" variants="A7XX-"/>
+
 	<array offset="0x0400" name="RBBM_PERFCTR_CP" stride="2" length="14" variants="A6XX"/>
 	<array offset="0x041c" name="RBBM_PERFCTR_RBBM" stride="2" length="4" variants="A6XX"/>
 	<array offset="0x0424" name="RBBM_PERFCTR_PC" stride="2" length="8" variants="A6XX"/>
@@ -2842,7 +2846,11 @@ to upconvert to 32b float internally?
 		</reg32>
 	</array>
 	<!-- 0x891b-0x8926 invalid -->
-	<reg64 offset="0x8927" name="RB_SAMPLE_COUNT_ADDR" type="waddress" align="16" usage="cmd" variants="A6XX"/>
+	<doc>
+		RB_SAMPLE_COUNT_ADDR register is used up to (and including) a730. After that
+		the address is specified through CP_EVENT_WRITE7::WRITE_SAMPLE_COUNT.
+	</doc>
+	<reg64 offset="0x8927" name="RB_SAMPLE_COUNT_ADDR" type="waddress" align="16" usage="cmd"/>
 	<!-- 0x8929-0x89ff invalid -->
 
 	<!-- TODO: there are some registers in the 0x8a00-0x8bff range -->
@@ -2950,7 +2958,7 @@ to upconvert to 32b float internally?
 	<!-- 0x8e1d-0x8e1f invalid -->
 	<!-- 0x8e20-0x8e25 more perfcntr sel? -->
 	<!-- 0x8e26-0x8e27 invalid -->
-	<reg32 offset="0x8e28" name="RB_UNKNOWN_8E28" low="0" high="10"/>
+	<reg32 offset="0x8e28" name="RB_CMP_DBG_ECO_CNTL"/>
 	<!-- 0x8e29-0x8e2b invalid -->
 	<array offset="0x8e2c" name="RB_PERFCTR_CMP_SEL" stride="1" length="4"/>
 	<array offset="0x8e30" name="RB_PERFCTR_UFC_SEL" stride="1" length="6" variants="A7XX-"/>
@@ -3306,6 +3314,15 @@ to upconvert to 32b float internally?
 		<bitfield name="DISCARD" pos="2" type="boolean"/>
 	</reg32>
 
+	<!-- Both are a750+.
+	     Probably needed to correctly overlap execution of several draws.
+	-->
+	<reg32 offset="0x9885" name="PC_TESS_PARAM_SIZE" variants="A7XX-" usage="cmd"/>
+	<!-- Blob adds a bit more space {0x10, 0x20, 0x30, 0x40} bytes, but the meaning of
+	     this additional space is not known.
+	-->
+	<reg32 offset="0x9886" name="PC_TESS_FACTOR_SIZE" variants="A7XX-" usage="cmd"/>
+
 	<!-- 0x9982-0x9aff invalid -->
 
 	<reg32 offset="0x9b00" name="PC_PRIMITIVE_CNTL_0" type="a6xx_primitive_cntl_0" usage="rp_blit"/>
@@ -4293,7 +4310,7 @@ to upconvert to 32b float internally?
 	<!-- always 0x100000 or 0x1000000? -->
 	<reg32 offset="0xb600" name="TPL1_DBG_ECO_CNTL" low="0" high="25" usage="cmd"/>
 	<reg32 offset="0xb601" name="TPL1_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
-	<reg32 offset="0xb602" name="TPL1_UNKNOWN_B602" low="0" high="7" type="uint" usage="cmd"/>
+	<reg32 offset="0xb602" name="TPL1_DBG_ECO_CNTL1" usage="cmd"/>
 	<reg32 offset="0xb604" name="TPL1_NC_MODE_CNTL">
 		<bitfield name="MODE" pos="0" type="boolean"/>
 		<bitfield name="LOWER_BIT" low="1" high="2" type="uint"/>
@@ -4965,6 +4982,11 @@ to upconvert to 32b float internally?
 	<reg32 offset="0x0001" name="SYSTEM_CACHE_CNTL_0"/>
 	<reg32 offset="0x0002" name="SYSTEM_CACHE_CNTL_1"/>
 	<reg32 offset="0x0039" name="CX_MISC_TCM_RET_CNTL" variants="A7XX-"/>
+	<reg32 offset="0x0400" name="CX_MISC_SW_FUSE_VALUE" variants="A7XX-">
+		<bitfield pos="0" name="FASTBLEND" type="boolean"/>
+		<bitfield pos="1" name="LPAC" type="boolean"/>
+		<bitfield pos="2" name="RAYTRACING" type="boolean"/>
+	</reg32>
 </domain>
 
 </database>

-- 
2.31.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 4/6] drm/msm/a7xx: Initialize a750 "software fuse"
  2024-04-30 10:43 [PATCH v3 0/6] drm/msm: Support a750 "software fuse" for raytracing Connor Abbott
                   ` (2 preceding siblings ...)
  2024-04-30 10:43 ` [PATCH v3 3/6] drm/msm: Update a6xx registers Connor Abbott
@ 2024-04-30 10:43 ` Connor Abbott
  2024-04-30 10:50   ` Konrad Dybcio
  2024-06-26  9:33   ` Neil Armstrong
  2024-04-30 10:43 ` [PATCH v3 5/6] drm/msm: Add MSM_PARAM_RAYTRACING uapi Connor Abbott
  2024-04-30 10:43 ` [PATCH v3 6/6] drm/msm/a7xx: Add missing register writes from downstream Connor Abbott
  5 siblings, 2 replies; 15+ messages in thread
From: Connor Abbott @ 2024-04-30 10:43 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Jun Nie, Rob Clark, Abhinav Kumar,
	Dmitry Baryshkov, Sean Paul, Marijn Suijten
  Cc: linux-arm-msm, devicetree, freedreno, Connor Abbott

On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method to
initialize cx_mem. Copy this from downstream (minus BCL which we
currently don't support). On a750, this includes a new "fuse" register
which can be used by qcom_scm to fuse off certain features like
raytracing in software. The fuse is default off, and is initialized by
calling the method. Afterwards we have to read it to find out which
features were enabled.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 91 ++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
 2 files changed, 92 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index cf0b1de1c071..52b080206090 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -10,6 +10,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/devfreq.h>
+#include <linux/firmware/qcom/qcom_scm.h>
 #include <linux/pm_domain.h>
 #include <linux/soc/qcom/llcc-qcom.h>
 
@@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
 		       A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
 		       A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
 		       A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
-		       A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
+		       A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
+		       A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
 
 #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
 			 A6XX_CP_APRIV_CNTL_RBFETCH | \
@@ -2356,6 +2358,27 @@ static void a6xx_fault_detect_irq(struct msm_gpu *gpu)
 	kthread_queue_work(gpu->worker, &gpu->recover_work);
 }
 
+static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
+{
+	u32 status;
+
+	status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
+	gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
+
+	dev_err_ratelimited(&gpu->pdev->dev, "SW fuse violation status=%8.8x\n", status);
+
+	/*
+	 * Ignore FASTBLEND violations, because the HW will silently fall back
+	 * to legacy blending.
+	 */
+	if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
+		      A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
+		del_timer(&gpu->hangcheck_timer);
+
+		kthread_queue_work(gpu->worker, &gpu->recover_work);
+	}
+}
+
 static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
 {
 	struct msm_drm_private *priv = gpu->dev->dev_private;
@@ -2384,6 +2407,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
 	if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
 		dev_err_ratelimited(&gpu->pdev->dev, "UCHE | Out of bounds access\n");
 
+	if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
+		a7xx_sw_fuse_violation_irq(gpu);
+
 	if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
 		msm_gpu_retire(gpu);
 
@@ -2525,6 +2551,61 @@ static void a6xx_llc_slices_init(struct platform_device *pdev,
 		a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
 }
 
+static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
+{
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	struct msm_gpu *gpu = &adreno_gpu->base;
+	u32 fuse_val;
+	int ret;
+
+	if (adreno_is_a750(adreno_gpu)) {
+		/*
+		 * Assume that if qcom scm isn't available, that whatever
+		 * replacement allows writing the fuse register ourselves.
+		 * Users of alternative firmware need to make sure this
+		 * register is writeable or indicate that it's not somehow.
+		 * Print a warning because if you mess this up you're about to
+		 * crash horribly.
+		 */
+		if (!qcom_scm_is_available()) {
+			dev_warn_once(gpu->dev->dev,
+				"SCM is not available, poking fuse register\n");
+			a6xx_llc_write(a6xx_gpu, REG_A7XX_CX_MISC_SW_FUSE_VALUE,
+				A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
+				A7XX_CX_MISC_SW_FUSE_VALUE_FASTBLEND |
+				A7XX_CX_MISC_SW_FUSE_VALUE_LPAC);
+			adreno_gpu->has_ray_tracing = true;
+			return 0;
+		}
+
+		ret = qcom_scm_gpu_init_regs(QCOM_SCM_GPU_ALWAYS_EN_REQ |
+					     QCOM_SCM_GPU_TSENSE_EN_REQ);
+		if (ret)
+			return ret;
+
+		/*
+		 * On a750 raytracing may be disabled by the firmware, find out
+		 * whether that's the case. The scm call above sets the fuse
+		 * register.
+		 */
+		fuse_val = a6xx_llc_read(a6xx_gpu,
+					 REG_A7XX_CX_MISC_SW_FUSE_VALUE);
+		adreno_gpu->has_ray_tracing =
+			!!(fuse_val & A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING);
+	} else {
+		if (adreno_is_a740(adreno_gpu)) {
+			/* Raytracing is always enabled on a740 */
+			adreno_gpu->has_ray_tracing = true;
+		}
+
+		if (qcom_scm_is_available())
+			return qcom_scm_gpu_init_regs(QCOM_SCM_GPU_ALWAYS_EN_REQ);
+	}
+
+	return 0;
+}
+
+
 #define GBIF_CLIENT_HALT_MASK		BIT(0)
 #define GBIF_ARB_HALT_MASK		BIT(1)
 #define VBIF_XIN_HALT_CTRL0_MASK	GENMASK(3, 0)
@@ -3094,6 +3175,14 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
 		return ERR_PTR(ret);
 	}
 
+	if (adreno_is_a7xx(adreno_gpu)) {
+		ret = a7xx_cx_mem_init(a6xx_gpu);
+		if (ret) {
+			a6xx_destroy(&(a6xx_gpu->base.base));
+			return ERR_PTR(ret);
+		}
+	}
+
 	if (gpu->aspace)
 		msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu,
 				a6xx_fault_handler);
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index 77526892eb8c..4180f3149dd8 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -182,6 +182,8 @@ struct adreno_gpu {
 	 */
 	const unsigned int *reg_offsets;
 	bool gmu_is_wrapper;
+
+	bool has_ray_tracing;
 };
 #define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base)
 

-- 
2.31.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 5/6] drm/msm: Add MSM_PARAM_RAYTRACING uapi
  2024-04-30 10:43 [PATCH v3 0/6] drm/msm: Support a750 "software fuse" for raytracing Connor Abbott
                   ` (3 preceding siblings ...)
  2024-04-30 10:43 ` [PATCH v3 4/6] drm/msm/a7xx: Initialize a750 "software fuse" Connor Abbott
@ 2024-04-30 10:43 ` Connor Abbott
  2024-04-30 10:43 ` [PATCH v3 6/6] drm/msm/a7xx: Add missing register writes from downstream Connor Abbott
  5 siblings, 0 replies; 15+ messages in thread
From: Connor Abbott @ 2024-04-30 10:43 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Jun Nie, Rob Clark, Abhinav Kumar,
	Dmitry Baryshkov, Sean Paul, Marijn Suijten
  Cc: linux-arm-msm, devicetree, freedreno, Connor Abbott

Expose the value of the software fuse to userspace.

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 +++
 include/uapi/drm/msm_drm.h              | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 074fb498706f..99ad651857b2 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -376,6 +376,9 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
 	case MSM_PARAM_HIGHEST_BANK_BIT:
 		*value = adreno_gpu->ubwc_config.highest_bank_bit;
 		return 0;
+	case MSM_PARAM_RAYTRACING:
+		*value = adreno_gpu->has_ray_tracing;
+		return 0;
 	default:
 		DBG("%s: invalid param: %u", gpu->name, param);
 		return -EINVAL;
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index d8a6b3472760..3fca72f73861 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -87,6 +87,7 @@ struct drm_msm_timespec {
 #define MSM_PARAM_VA_START   0x0e  /* RO: start of valid GPU iova range */
 #define MSM_PARAM_VA_SIZE    0x0f  /* RO: size of valid GPU iova range (bytes) */
 #define MSM_PARAM_HIGHEST_BANK_BIT 0x10 /* RO */
+#define MSM_PARAM_RAYTRACING 0x11 /* RO */
 
 /* For backwards compat.  The original support for preemption was based on
  * a single ring per priority level so # of priority levels equals the #

-- 
2.31.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 6/6] drm/msm/a7xx: Add missing register writes from downstream
  2024-04-30 10:43 [PATCH v3 0/6] drm/msm: Support a750 "software fuse" for raytracing Connor Abbott
                   ` (4 preceding siblings ...)
  2024-04-30 10:43 ` [PATCH v3 5/6] drm/msm: Add MSM_PARAM_RAYTRACING uapi Connor Abbott
@ 2024-04-30 10:43 ` Connor Abbott
  2024-04-30 10:51   ` Konrad Dybcio
  5 siblings, 1 reply; 15+ messages in thread
From: Connor Abbott @ 2024-04-30 10:43 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Jun Nie, Rob Clark, Abhinav Kumar,
	Dmitry Baryshkov, Sean Paul, Marijn Suijten
  Cc: linux-arm-msm, devicetree, freedreno, Connor Abbott

This isn't known to fix anything yet, but it's a good idea to add it.

Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 52b080206090..24a4ed9bfea9 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1953,6 +1953,17 @@ static int hw_init(struct msm_gpu *gpu)
 				  BIT(6) | BIT(5) | BIT(3) | BIT(2) | BIT(1));
 	}
 
+	if (adreno_is_a750(adreno_gpu)) {
+		/* Disable ubwc merged UFC request feature */
+		gpu_rmw(gpu, REG_A6XX_RB_CMP_DBG_ECO_CNTL, BIT(19), BIT(19));
+
+		/* Enable TP flaghint and other performance settings */
+		gpu_write(gpu, REG_A6XX_TPL1_DBG_ECO_CNTL1, 0xc0700);
+	} else if (adreno_is_a7xx(adreno_gpu)) {
+		/* Disable non-ubwc read reqs from passing write reqs */
+		gpu_rmw(gpu, REG_A6XX_RB_CMP_DBG_ECO_CNTL, BIT(11), BIT(11));
+	}
+
 	/* Enable interrupts */
 	gpu_write(gpu, REG_A6XX_RBBM_INT_0_MASK,
 		  adreno_is_a7xx(adreno_gpu) ? A7XX_INT_MASK : A6XX_INT_MASK);

-- 
2.31.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 2/6] firmware: qcom_scm: Add gpu_init_regs call
  2024-04-30 10:43 ` [PATCH v3 2/6] firmware: qcom_scm: Add gpu_init_regs call Connor Abbott
@ 2024-04-30 10:48   ` Konrad Dybcio
  2024-05-27  0:03   ` Bjorn Andersson
  2024-06-21  5:29   ` (subset) " Bjorn Andersson
  2 siblings, 0 replies; 15+ messages in thread
From: Konrad Dybcio @ 2024-04-30 10:48 UTC (permalink / raw)
  To: Connor Abbott, Bjorn Andersson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Jun Nie, Rob Clark, Abhinav Kumar,
	Dmitry Baryshkov, Sean Paul, Marijn Suijten
  Cc: linux-arm-msm, devicetree, freedreno

On 30.04.2024 12:43 PM, Connor Abbott wrote:
> This will used by drm/msm to initialize GPU registers that Qualcomm's
> firmware doesn't make writeable to the kernel.
> 
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 4/6] drm/msm/a7xx: Initialize a750 "software fuse"
  2024-04-30 10:43 ` [PATCH v3 4/6] drm/msm/a7xx: Initialize a750 "software fuse" Connor Abbott
@ 2024-04-30 10:50   ` Konrad Dybcio
  2024-06-26  9:33   ` Neil Armstrong
  1 sibling, 0 replies; 15+ messages in thread
From: Konrad Dybcio @ 2024-04-30 10:50 UTC (permalink / raw)
  To: Connor Abbott, Bjorn Andersson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Jun Nie, Rob Clark, Abhinav Kumar,
	Dmitry Baryshkov, Sean Paul, Marijn Suijten
  Cc: linux-arm-msm, devicetree, freedreno

On 30.04.2024 12:43 PM, Connor Abbott wrote:
> On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method to
> initialize cx_mem. Copy this from downstream (minus BCL which we
> currently don't support). On a750, this includes a new "fuse" register
> which can be used by qcom_scm to fuse off certain features like
> raytracing in software. The fuse is default off, and is initialized by
> calling the method. Afterwards we have to read it to find out which
> features were enabled.
> 
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 6/6] drm/msm/a7xx: Add missing register writes from downstream
  2024-04-30 10:43 ` [PATCH v3 6/6] drm/msm/a7xx: Add missing register writes from downstream Connor Abbott
@ 2024-04-30 10:51   ` Konrad Dybcio
  0 siblings, 0 replies; 15+ messages in thread
From: Konrad Dybcio @ 2024-04-30 10:51 UTC (permalink / raw)
  To: Connor Abbott, Bjorn Andersson, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Jun Nie, Rob Clark, Abhinav Kumar,
	Dmitry Baryshkov, Sean Paul, Marijn Suijten
  Cc: linux-arm-msm, devicetree, freedreno

On 30.04.2024 12:43 PM, Connor Abbott wrote:
> This isn't known to fix anything yet, but it's a good idea to add it.
> 
> Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 1/6] arm64: dts: qcom: sm8650: Fix GPU cx_mem size
  2024-04-30 10:43 ` [PATCH v3 1/6] arm64: dts: qcom: sm8650: Fix GPU cx_mem size Connor Abbott
@ 2024-05-02  8:03   ` Neil Armstrong
  0 siblings, 0 replies; 15+ messages in thread
From: Neil Armstrong @ 2024-05-02  8:03 UTC (permalink / raw)
  To: Connor Abbott, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jun Nie, Rob Clark,
	Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten
  Cc: linux-arm-msm, devicetree, freedreno

On 30/04/2024 12:43, Connor Abbott wrote:
> This is doubled compared to previous GPUs. We can't access the new
> SW_FUSE_VALUE register without this.
> 
> Fixes: db33633b05c0 ("arm64: dts: qcom: sm8650: add GPU nodes")
> Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
> ---
>   arch/arm64/boot/dts/qcom/sm8650.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
> index 658ad2b41c5a..78b8944eaab2 100644
> --- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
> @@ -2607,7 +2607,7 @@ tcsr: clock-controller@1fc0000 {
>   		gpu: gpu@3d00000 {
>   			compatible = "qcom,adreno-43051401", "qcom,adreno";
>   			reg = <0x0 0x03d00000 0x0 0x40000>,
> -			      <0x0 0x03d9e000 0x0 0x1000>,
> +			      <0x0 0x03d9e000 0x0 0x2000>,
>   			      <0x0 0x03d61000 0x0 0x800>;
>   			reg-names = "kgsl_3d0_reg_memory",
>   				    "cx_mem",
> 

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 2/6] firmware: qcom_scm: Add gpu_init_regs call
  2024-04-30 10:43 ` [PATCH v3 2/6] firmware: qcom_scm: Add gpu_init_regs call Connor Abbott
  2024-04-30 10:48   ` Konrad Dybcio
@ 2024-05-27  0:03   ` Bjorn Andersson
  2024-06-21  5:29   ` (subset) " Bjorn Andersson
  2 siblings, 0 replies; 15+ messages in thread
From: Bjorn Andersson @ 2024-05-27  0:03 UTC (permalink / raw)
  To: Connor Abbott
  Cc: Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Neil Armstrong, Jun Nie, Rob Clark, Abhinav Kumar,
	Dmitry Baryshkov, Sean Paul, Marijn Suijten, linux-arm-msm,
	devicetree, freedreno

On Tue, Apr 30, 2024 at 11:43:16AM GMT, Connor Abbott wrote:
> This will used by drm/msm to initialize GPU registers that Qualcomm's
> firmware doesn't make writeable to the kernel.
> 
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Signed-off-by: Connor Abbott <cwabbott0@gmail.com>

Acked-by: Bjorn Andersson <andersson@kernel.org>

Regards,
Bjorn

> ---
>  drivers/firmware/qcom/qcom_scm.c       | 14 ++++++++++++++
>  drivers/firmware/qcom/qcom_scm.h       |  3 +++
>  include/linux/firmware/qcom/qcom_scm.h | 23 +++++++++++++++++++++++
>  3 files changed, 40 insertions(+)
> 
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 06e46267161b..f8623ad0987c 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -1394,6 +1394,20 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
>  }
>  EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh);
>  
> +int qcom_scm_gpu_init_regs(u32 gpu_req)
> +{
> +	struct qcom_scm_desc desc = {
> +		.svc = QCOM_SCM_SVC_GPU,
> +		.cmd = QCOM_SCM_SVC_GPU_INIT_REGS,
> +		.arginfo = QCOM_SCM_ARGS(1),
> +		.args[0] = gpu_req,
> +		.owner = ARM_SMCCC_OWNER_SIP,
> +	};
> +
> +	return qcom_scm_call(__scm->dev, &desc, NULL);
> +}
> +EXPORT_SYMBOL_GPL(qcom_scm_gpu_init_regs);
> +
>  static int qcom_scm_find_dload_address(struct device *dev, u64 *addr)
>  {
>  	struct device_node *tcsr;
> diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h
> index 4532907e8489..484e030bcac9 100644
> --- a/drivers/firmware/qcom/qcom_scm.h
> +++ b/drivers/firmware/qcom/qcom_scm.h
> @@ -138,6 +138,9 @@ int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
>  #define QCOM_SCM_WAITQ_RESUME			0x02
>  #define QCOM_SCM_WAITQ_GET_WQ_CTX		0x03
>  
> +#define QCOM_SCM_SVC_GPU			0x28
> +#define QCOM_SCM_SVC_GPU_INIT_REGS		0x01
> +
>  /* common error codes */
>  #define QCOM_SCM_V2_EBUSY	-12
>  #define QCOM_SCM_ENOMEM		-5
> diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
> index aaa19f93ac43..a221a643dc12 100644
> --- a/include/linux/firmware/qcom/qcom_scm.h
> +++ b/include/linux/firmware/qcom/qcom_scm.h
> @@ -115,6 +115,29 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
>  int qcom_scm_lmh_profile_change(u32 profile_id);
>  bool qcom_scm_lmh_dcvsh_available(void);
>  
> +/*
> + * Request TZ to program set of access controlled registers necessary
> + * irrespective of any features
> + */
> +#define QCOM_SCM_GPU_ALWAYS_EN_REQ BIT(0)
> +/*
> + * Request TZ to program BCL id to access controlled register when BCL is
> + * enabled
> + */
> +#define QCOM_SCM_GPU_BCL_EN_REQ BIT(1)
> +/*
> + * Request TZ to program set of access controlled register for CLX feature
> + * when enabled
> + */
> +#define QCOM_SCM_GPU_CLX_EN_REQ BIT(2)
> +/*
> + * Request TZ to program tsense ids to access controlled registers for reading
> + * gpu temperature sensors
> + */
> +#define QCOM_SCM_GPU_TSENSE_EN_REQ BIT(3)
> +
> +int qcom_scm_gpu_init_regs(u32 gpu_req);
> +
>  #ifdef CONFIG_QCOM_QSEECOM
>  
>  int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id);
> 
> -- 
> 2.31.1
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: (subset) [PATCH v3 2/6] firmware: qcom_scm: Add gpu_init_regs call
  2024-04-30 10:43 ` [PATCH v3 2/6] firmware: qcom_scm: Add gpu_init_regs call Connor Abbott
  2024-04-30 10:48   ` Konrad Dybcio
  2024-05-27  0:03   ` Bjorn Andersson
@ 2024-06-21  5:29   ` Bjorn Andersson
  2 siblings, 0 replies; 15+ messages in thread
From: Bjorn Andersson @ 2024-06-21  5:29 UTC (permalink / raw)
  To: Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Neil Armstrong, Jun Nie, Rob Clark, Abhinav Kumar,
	Dmitry Baryshkov, Sean Paul, Marijn Suijten, Connor Abbott
  Cc: linux-arm-msm, devicetree, freedreno


On Tue, 30 Apr 2024 11:43:16 +0100, Connor Abbott wrote:
> This will used by drm/msm to initialize GPU registers that Qualcomm's
> firmware doesn't make writeable to the kernel.
> 
> 

Applied, thanks!

[2/6] firmware: qcom_scm: Add gpu_init_regs call
      commit: 158ed777e330e9bf6bd592daaf1e860d965ec8b5

Best regards,
-- 
Bjorn Andersson <andersson@kernel.org>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 4/6] drm/msm/a7xx: Initialize a750 "software fuse"
  2024-04-30 10:43 ` [PATCH v3 4/6] drm/msm/a7xx: Initialize a750 "software fuse" Connor Abbott
  2024-04-30 10:50   ` Konrad Dybcio
@ 2024-06-26  9:33   ` Neil Armstrong
  2024-06-26 10:05     ` Connor Abbott
  1 sibling, 1 reply; 15+ messages in thread
From: Neil Armstrong @ 2024-06-26  9:33 UTC (permalink / raw)
  To: Connor Abbott, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jun Nie, Rob Clark,
	Abhinav Kumar, Dmitry Baryshkov, Sean Paul, Marijn Suijten
  Cc: linux-arm-msm, devicetree, freedreno

Hi,

On 30/04/2024 12:43, Connor Abbott wrote:
> On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method to
> initialize cx_mem. Copy this from downstream (minus BCL which we
> currently don't support). On a750, this includes a new "fuse" register
> which can be used by qcom_scm to fuse off certain features like
> raytracing in software. The fuse is default off, and is initialized by
> calling the method. Afterwards we have to read it to find out which
> features were enabled.
> 
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
> ---
>   drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 91 ++++++++++++++++++++++++++++++++-
>   drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
>   2 files changed, 92 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index cf0b1de1c071..52b080206090 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -10,6 +10,7 @@
>   
>   #include <linux/bitfield.h>
>   #include <linux/devfreq.h>
> +#include <linux/firmware/qcom/qcom_scm.h>
>   #include <linux/pm_domain.h>
>   #include <linux/soc/qcom/llcc-qcom.h>
>   
> @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
>   		       A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
>   		       A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
>   		       A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> -		       A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> +		       A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> +		       A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
>   
>   #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
>   			 A6XX_CP_APRIV_CNTL_RBFETCH | \
> @@ -2356,6 +2358,27 @@ static void a6xx_fault_detect_irq(struct msm_gpu *gpu)
>   	kthread_queue_work(gpu->worker, &gpu->recover_work);
>   }
>   
> +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> +{
> +	u32 status;
> +
> +	status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> +	gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> +
> +	dev_err_ratelimited(&gpu->pdev->dev, "SW fuse violation status=%8.8x\n", status);
> +
> +	/*
> +	 * Ignore FASTBLEND violations, because the HW will silently fall back
> +	 * to legacy blending.
> +	 */
> +	if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> +		      A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> +		del_timer(&gpu->hangcheck_timer);
> +
> +		kthread_queue_work(gpu->worker, &gpu->recover_work);
> +	}
> +}
> +
>   static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
>   {
>   	struct msm_drm_private *priv = gpu->dev->dev_private;
> @@ -2384,6 +2407,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
>   	if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
>   		dev_err_ratelimited(&gpu->pdev->dev, "UCHE | Out of bounds access\n");
>   
> +	if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> +		a7xx_sw_fuse_violation_irq(gpu);
> +
>   	if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
>   		msm_gpu_retire(gpu);
>   
> @@ -2525,6 +2551,61 @@ static void a6xx_llc_slices_init(struct platform_device *pdev,
>   		a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
>   }
>   
> +static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
> +{
> +	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
> +	struct msm_gpu *gpu = &adreno_gpu->base;
> +	u32 fuse_val;
> +	int ret;
> +
> +	if (adreno_is_a750(adreno_gpu)) {
> +		/*
> +		 * Assume that if qcom scm isn't available, that whatever
> +		 * replacement allows writing the fuse register ourselves.
> +		 * Users of alternative firmware need to make sure this
> +		 * register is writeable or indicate that it's not somehow.
> +		 * Print a warning because if you mess this up you're about to
> +		 * crash horribly.
> +		 */
> +		if (!qcom_scm_is_available()) {
> +			dev_warn_once(gpu->dev->dev,
> +				"SCM is not available, poking fuse register\n");
> +			a6xx_llc_write(a6xx_gpu, REG_A7XX_CX_MISC_SW_FUSE_VALUE,
> +				A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> +				A7XX_CX_MISC_SW_FUSE_VALUE_FASTBLEND |
> +				A7XX_CX_MISC_SW_FUSE_VALUE_LPAC);
> +			adreno_gpu->has_ray_tracing = true;
> +			return 0;
> +		}
> +
> +		ret = qcom_scm_gpu_init_regs(QCOM_SCM_GPU_ALWAYS_EN_REQ |
> +					     QCOM_SCM_GPU_TSENSE_EN_REQ);
> +		if (ret)
> +			return ret;
> +
> +		/*
> +		 * On a750 raytracing may be disabled by the firmware, find out
> +		 * whether that's the case. The scm call above sets the fuse
> +		 * register.
> +		 */
> +		fuse_val = a6xx_llc_read(a6xx_gpu,
> +					 REG_A7XX_CX_MISC_SW_FUSE_VALUE);
> +		adreno_gpu->has_ray_tracing =
> +			!!(fuse_val & A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING);
> +	} else {
> +		if (adreno_is_a740(adreno_gpu)) {
> +			/* Raytracing is always enabled on a740 */
> +			adreno_gpu->has_ray_tracing = true;
> +		}
> +
> +		if (qcom_scm_is_available())
> +			return qcom_scm_gpu_init_regs(QCOM_SCM_GPU_ALWAYS_EN_REQ);
> +	}
> +
> +	return 0;
> +}
> +
> +
>   #define GBIF_CLIENT_HALT_MASK		BIT(0)
>   #define GBIF_ARB_HALT_MASK		BIT(1)
>   #define VBIF_XIN_HALT_CTRL0_MASK	GENMASK(3, 0)
> @@ -3094,6 +3175,14 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
>   		return ERR_PTR(ret);
>   	}
>   
> +	if (adreno_is_a7xx(adreno_gpu)) {
> +		ret = a7xx_cx_mem_init(a6xx_gpu);
> +		if (ret) {
> +			a6xx_destroy(&(a6xx_gpu->base.base));
> +			return ERR_PTR(ret);
> +		}
> +	}
> +
>   	if (gpu->aspace)
>   		msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu,
>   				a6xx_fault_handler);
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> index 77526892eb8c..4180f3149dd8 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> @@ -182,6 +182,8 @@ struct adreno_gpu {
>   	 */
>   	const unsigned int *reg_offsets;
>   	bool gmu_is_wrapper;
> +
> +	bool has_ray_tracing;
>   };
>   #define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base)
>   
> 

This patch break GPU init on SM8450-HDK and SM8550-HDK, call to
qcom_scm_gpu_init_regs(QCOM_SCM_GPU_ALWAYS_EN_REQ) returns -5.

On which device did you test this ?

Neil

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 4/6] drm/msm/a7xx: Initialize a750 "software fuse"
  2024-06-26  9:33   ` Neil Armstrong
@ 2024-06-26 10:05     ` Connor Abbott
  0 siblings, 0 replies; 15+ messages in thread
From: Connor Abbott @ 2024-06-26 10:05 UTC (permalink / raw)
  To: neil.armstrong
  Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jun Nie, Rob Clark, Abhinav Kumar, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten, linux-arm-msm, devicetree, freedreno

On Wed, Jun 26, 2024 at 10:33 AM Neil Armstrong
<neil.armstrong@linaro.org> wrote:
>
> Hi,
>
> On 30/04/2024 12:43, Connor Abbott wrote:
> > On all Qualcomm platforms with a7xx GPUs, qcom_scm provides a method to
> > initialize cx_mem. Copy this from downstream (minus BCL which we
> > currently don't support). On a750, this includes a new "fuse" register
> > which can be used by qcom_scm to fuse off certain features like
> > raytracing in software. The fuse is default off, and is initialized by
> > calling the method. Afterwards we have to read it to find out which
> > features were enabled.
> >
> > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
> > ---
> >   drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 91 ++++++++++++++++++++++++++++++++-
> >   drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +
> >   2 files changed, 92 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > index cf0b1de1c071..52b080206090 100644
> > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > @@ -10,6 +10,7 @@
> >
> >   #include <linux/bitfield.h>
> >   #include <linux/devfreq.h>
> > +#include <linux/firmware/qcom/qcom_scm.h>
> >   #include <linux/pm_domain.h>
> >   #include <linux/soc/qcom/llcc-qcom.h>
> >
> > @@ -1686,7 +1687,8 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
> >                      A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
> >                      A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
> >                      A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
> > -                    A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
> > +                    A6XX_RBBM_INT_0_MASK_TSBWRITEERROR | \
> > +                    A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> >
> >   #define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
> >                        A6XX_CP_APRIV_CNTL_RBFETCH | \
> > @@ -2356,6 +2358,27 @@ static void a6xx_fault_detect_irq(struct msm_gpu *gpu)
> >       kthread_queue_work(gpu->worker, &gpu->recover_work);
> >   }
> >
> > +static void a7xx_sw_fuse_violation_irq(struct msm_gpu *gpu)
> > +{
> > +     u32 status;
> > +
> > +     status = gpu_read(gpu, REG_A7XX_RBBM_SW_FUSE_INT_STATUS);
> > +     gpu_write(gpu, REG_A7XX_RBBM_SW_FUSE_INT_MASK, 0);
> > +
> > +     dev_err_ratelimited(&gpu->pdev->dev, "SW fuse violation status=%8.8x\n", status);
> > +
> > +     /*
> > +      * Ignore FASTBLEND violations, because the HW will silently fall back
> > +      * to legacy blending.
> > +      */
> > +     if (status & (A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > +                   A7XX_CX_MISC_SW_FUSE_VALUE_LPAC)) {
> > +             del_timer(&gpu->hangcheck_timer);
> > +
> > +             kthread_queue_work(gpu->worker, &gpu->recover_work);
> > +     }
> > +}
> > +
> >   static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> >   {
> >       struct msm_drm_private *priv = gpu->dev->dev_private;
> > @@ -2384,6 +2407,9 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
> >       if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
> >               dev_err_ratelimited(&gpu->pdev->dev, "UCHE | Out of bounds access\n");
> >
> > +     if (status & A6XX_RBBM_INT_0_MASK_SWFUSEVIOLATION)
> > +             a7xx_sw_fuse_violation_irq(gpu);
> > +
> >       if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
> >               msm_gpu_retire(gpu);
> >
> > @@ -2525,6 +2551,61 @@ static void a6xx_llc_slices_init(struct platform_device *pdev,
> >               a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
> >   }
> >
> > +static int a7xx_cx_mem_init(struct a6xx_gpu *a6xx_gpu)
> > +{
> > +     struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
> > +     struct msm_gpu *gpu = &adreno_gpu->base;
> > +     u32 fuse_val;
> > +     int ret;
> > +
> > +     if (adreno_is_a750(adreno_gpu)) {
> > +             /*
> > +              * Assume that if qcom scm isn't available, that whatever
> > +              * replacement allows writing the fuse register ourselves.
> > +              * Users of alternative firmware need to make sure this
> > +              * register is writeable or indicate that it's not somehow.
> > +              * Print a warning because if you mess this up you're about to
> > +              * crash horribly.
> > +              */
> > +             if (!qcom_scm_is_available()) {
> > +                     dev_warn_once(gpu->dev->dev,
> > +                             "SCM is not available, poking fuse register\n");
> > +                     a6xx_llc_write(a6xx_gpu, REG_A7XX_CX_MISC_SW_FUSE_VALUE,
> > +                             A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
> > +                             A7XX_CX_MISC_SW_FUSE_VALUE_FASTBLEND |
> > +                             A7XX_CX_MISC_SW_FUSE_VALUE_LPAC);
> > +                     adreno_gpu->has_ray_tracing = true;
> > +                     return 0;
> > +             }
> > +
> > +             ret = qcom_scm_gpu_init_regs(QCOM_SCM_GPU_ALWAYS_EN_REQ |
> > +                                          QCOM_SCM_GPU_TSENSE_EN_REQ);
> > +             if (ret)
> > +                     return ret;
> > +
> > +             /*
> > +              * On a750 raytracing may be disabled by the firmware, find out
> > +              * whether that's the case. The scm call above sets the fuse
> > +              * register.
> > +              */
> > +             fuse_val = a6xx_llc_read(a6xx_gpu,
> > +                                      REG_A7XX_CX_MISC_SW_FUSE_VALUE);
> > +             adreno_gpu->has_ray_tracing =
> > +                     !!(fuse_val & A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING);
> > +     } else {
> > +             if (adreno_is_a740(adreno_gpu)) {
> > +                     /* Raytracing is always enabled on a740 */
> > +                     adreno_gpu->has_ray_tracing = true;
> > +             }
> > +
> > +             if (qcom_scm_is_available())
> > +                     return qcom_scm_gpu_init_regs(QCOM_SCM_GPU_ALWAYS_EN_REQ);
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +
> >   #define GBIF_CLIENT_HALT_MASK               BIT(0)
> >   #define GBIF_ARB_HALT_MASK          BIT(1)
> >   #define VBIF_XIN_HALT_CTRL0_MASK    GENMASK(3, 0)
> > @@ -3094,6 +3175,14 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
> >               return ERR_PTR(ret);
> >       }
> >
> > +     if (adreno_is_a7xx(adreno_gpu)) {
> > +             ret = a7xx_cx_mem_init(a6xx_gpu);
> > +             if (ret) {
> > +                     a6xx_destroy(&(a6xx_gpu->base.base));
> > +                     return ERR_PTR(ret);
> > +             }
> > +     }
> > +
> >       if (gpu->aspace)
> >               msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu,
> >                               a6xx_fault_handler);
> > diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> > index 77526892eb8c..4180f3149dd8 100644
> > --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> > +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> > @@ -182,6 +182,8 @@ struct adreno_gpu {
> >        */
> >       const unsigned int *reg_offsets;
> >       bool gmu_is_wrapper;
> > +
> > +     bool has_ray_tracing;
> >   };
> >   #define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base)
> >
> >
>
> This patch break GPU init on SM8450-HDK and SM8550-HDK, call to
> qcom_scm_gpu_init_regs(QCOM_SCM_GPU_ALWAYS_EN_REQ) returns -5.
>
> On which device did you test this ?
>
> Neil

I tested on SM8650-HDK (with your DTS patches on top). kgsl does call
this on SM8450/SM8550 [1], and doesn't swallow -EIO, which is why I
thought it was safe. But looking more into it now, the commit message
introducing it mentions the software fuse which is SM8650-only, so
maybe they broke SM8550 when adding this for SM8650?

Connor

[1] https://git.codelinaro.org/clo/le/platform/vendor/qcom/opensource/graphics-kernel/-/blob/gfx-kernel.le.0.0.r1-rel/adreno_gen7.c?ref_type=heads#L915.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2024-06-26 10:05 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-30 10:43 [PATCH v3 0/6] drm/msm: Support a750 "software fuse" for raytracing Connor Abbott
2024-04-30 10:43 ` [PATCH v3 1/6] arm64: dts: qcom: sm8650: Fix GPU cx_mem size Connor Abbott
2024-05-02  8:03   ` Neil Armstrong
2024-04-30 10:43 ` [PATCH v3 2/6] firmware: qcom_scm: Add gpu_init_regs call Connor Abbott
2024-04-30 10:48   ` Konrad Dybcio
2024-05-27  0:03   ` Bjorn Andersson
2024-06-21  5:29   ` (subset) " Bjorn Andersson
2024-04-30 10:43 ` [PATCH v3 3/6] drm/msm: Update a6xx registers Connor Abbott
2024-04-30 10:43 ` [PATCH v3 4/6] drm/msm/a7xx: Initialize a750 "software fuse" Connor Abbott
2024-04-30 10:50   ` Konrad Dybcio
2024-06-26  9:33   ` Neil Armstrong
2024-06-26 10:05     ` Connor Abbott
2024-04-30 10:43 ` [PATCH v3 5/6] drm/msm: Add MSM_PARAM_RAYTRACING uapi Connor Abbott
2024-04-30 10:43 ` [PATCH v3 6/6] drm/msm/a7xx: Add missing register writes from downstream Connor Abbott
2024-04-30 10:51   ` Konrad Dybcio

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).