[PATCH 6/9] arm64: dts/media: qcom: keep PLL8 out of Purwa camss hot path
From: Ramshouriesh
Date: Wed Jun 10 2026 - 07:21:01 EST
cam_cc_pll8 (defined in camcc-x1e80100.c) doesn't latch on Purwa
silicon. "Lucid PLL latch failed. Output may be unstable!" fires from
wait_for_pll() whenever something asks for a PLL8-sourced rate, and
the camera pipeline ends up dead with "Failed to start media
pipeline: -32" even after the qcom,x1p42100-camss compatible is in
place.
PLL8 sneaks into the streaming path via two RCG freq tables: the
slow_ahb RCG defaults to its 64 MHz entry (PLL8-sourced) when CSID
pulls it during csid_set_power, and vfe_lite picks its highest entry
(480 MHz, also PLL8) at streamon.
Fix this from the DT side:
* pin slow_ahb at 80 MHz via assigned-clock-rates in purwa.dtsi so
the RCG is reprogrammed to PLL0_OUT_EVEN at clk-init time and
never reaches PLL8;
* drop the 480 MHz entry from the Purwa vfe_lite clock_rate array
so the driver caps at 400 MHz (PLL0_OUT_ODD).
I went poking at the Qualcomm Windows BSP shipped for the UX3407QA to
see what rates the vendor side actually uses. The AeoB resource blob
at qccamplatform_ext8380/CAMP_{PERF,RES}_MTP.bin lists the camera
clocks Windows enables, and PLL8 isn't referenced once. For CCI in
particular Windows runs at 37.5 MHz off PLL0_OUT_EVEN, not the
30 MHz/PLL8 alternative the Linux driver happens to pick first.
Whether PLL8 is fused off, trust-zone-only, or just unwired on this
SoC I don't know, but treating it as unavailable matches what the
vendor does.
Signed-off-by: Ramshouriesh <rshouriesh@xxxxxxxxx>
---
arch/arm64/boot/dts/qcom/purwa.dtsi | 12 ++++++++++++
drivers/media/platform/qcom/camss/camss.c | 16 ++++++++--------
2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/purwa.dtsi b/arch/arm64/boot/dts/qcom/purwa.dtsi
index cee72349da49..5e39355c38d4 100644
--- a/arch/arm64/boot/dts/qcom/purwa.dtsi
+++ b/arch/arm64/boot/dts/qcom/purwa.dtsi
@@ -409,3 +409,15 @@ &tsens3 {
&videocc {
compatible = "qcom,x1p42100-videocc";
};
+
+/*
+ * PLL8 in the camcc-x1e80100 driver fails to lock on Purwa silicon
+ * ("Lucid PLL latch failed"). Several RCGs default to PLL8 as parent
+ * (slow_ahb at 64 MHz, cci_0 at 30 MHz). Pin slow_ahb to the next-best
+ * PLL0-sourced rate (80 MHz) at clock-init time so enabling it does not
+ * try to bring PLL8 up. cci_0 already defaults to 19.2 MHz via TCXO.
+ */
+&camcc {
+ assigned-clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>;
+ assigned-clock-rates = <80000000>;
+};
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 5c9530d52bbd..ca43ff309b26 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -4437,8 +4437,8 @@ static const struct camss_subdev_resources vfe_res_x1e80100[] = {
{ 0 },
{ 0 },
{ 0 },
- { 266666667, 400000000, 480000000 },
- { 266666667, 400000000, 480000000 }, },
+ { 266666667, 400000000 },
+ { 266666667, 400000000 }, },
.reg = { "vfe_lite0" },
.interrupt = { "vfe_lite0" },
.vfe = {
@@ -4460,8 +4460,8 @@ static const struct camss_subdev_resources vfe_res_x1e80100[] = {
{ 0 },
{ 0 },
{ 0 },
- { 266666667, 400000000, 480000000 },
- { 266666667, 400000000, 480000000 }, },
+ { 266666667, 400000000 },
+ { 266666667, 400000000 }, },
.reg = { "vfe_lite1" },
.interrupt = { "vfe_lite1" },
.vfe = {
@@ -4574,8 +4574,8 @@ static const struct camss_subdev_resources vfe_res_x1p42100[] = {
{ 0 },
{ 0 },
{ 0 },
- { 266666667, 400000000, 480000000 },
- { 266666667, 400000000, 480000000 }, },
+ { 266666667, 400000000 },
+ { 266666667, 400000000 }, },
.reg = { "vfe_lite0" },
.interrupt = { "vfe_lite0" },
.vfe = {
@@ -4597,8 +4597,8 @@ static const struct camss_subdev_resources vfe_res_x1p42100[] = {
{ 0 },
{ 0 },
{ 0 },
- { 266666667, 400000000, 480000000 },
- { 266666667, 400000000, 480000000 }, },
+ { 266666667, 400000000 },
+ { 266666667, 400000000 }, },
.reg = { "vfe_lite1" },
.interrupt = { "vfe_lite1" },
.vfe = {
--
2.53.0