Loading drivers/iommu/arm-smmu-debug.c +64 −29 Original line number Diff line number Diff line Loading @@ -19,21 +19,37 @@ #include "arm-smmu-debug.h" u32 arm_smmu_debug_tbu_testbus_select(void __iomem *tbu_base, void __iomem *tcu_base, u32 testbus_version, bool write, u32 val) { void __iomem *base; int offset; if (testbus_version == 1) { base = tcu_base; offset = ARM_SMMU_TESTBUS_SEL_HLOS1_NS; } else { base = tbu_base; offset = DEBUG_TESTBUS_SEL_TBU; } if (write) { writel_relaxed(val, tbu_base + DEBUG_TESTBUS_SEL_TBU); writel_relaxed(val, base + offset); /* Make sure tbu select register is written to */ wmb(); } else { return readl_relaxed(tbu_base + DEBUG_TESTBUS_SEL_TBU); return readl_relaxed(base + offset); } return 0; } u32 arm_smmu_debug_tbu_testbus_output(void __iomem *tbu_base) u32 arm_smmu_debug_tbu_testbus_output(void __iomem *tbu_base, u32 testbus_version) { return readl_relaxed(tbu_base + DEBUG_TESTBUS_TBU); int offset = (testbus_version == 1) ? CLIENT_DEBUG_SR_HALT_ACK : DEBUG_TESTBUS_TBU; return readl_relaxed(tbu_base + offset); } u32 arm_smmu_debug_tcu_testbus_select(void __iomem *base, Loading Loading @@ -66,67 +82,86 @@ u32 arm_smmu_debug_tcu_testbus_output(void __iomem *base) } static void arm_smmu_debug_dump_tbu_qns4_testbus(struct device *dev, void __iomem *tbu_base) void __iomem *tbu_base, void __iomem *tcu_base, u32 testbus_version) { int i; u32 reg; for (i = 0 ; i < TBU_QNS4_BRIDGE_SIZE; ++i) { reg = arm_smmu_debug_tbu_testbus_select(tbu_base, READ, 0); reg = arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, READ, 0); reg = (reg & ~GENMASK(4, 0)) | i << 0; arm_smmu_debug_tbu_testbus_select(tbu_base, WRITE, reg); arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, WRITE, reg); dev_info(dev, "testbus_sel: 0x%lx Index: %d val: 0x%llx\n", arm_smmu_debug_tbu_testbus_select(tbu_base, READ, 0), i, arm_smmu_debug_tbu_testbus_output(tbu_base)); arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, READ, 0), i, arm_smmu_debug_tbu_testbus_output(tbu_base, testbus_version)); } } static void arm_smmu_debug_program_tbu_testbus(void __iomem *tbu_base, void __iomem *tcu_base, u32 testbus_version, int tbu_testbus) { u32 reg; reg = arm_smmu_debug_tbu_testbus_select(tbu_base, READ, 0); reg = (reg & ~GENMASK(7, 0)) | tbu_testbus; arm_smmu_debug_tbu_testbus_select(tbu_base, WRITE, reg); reg = arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, READ, 0); if (testbus_version == 1) reg = (reg & ~GENMASK(9, 0)); else reg = (reg & ~GENMASK(7, 0)); reg |= tbu_testbus; arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, WRITE, reg); } void arm_smmu_debug_dump_tbu_testbus(struct device *dev, void __iomem *tbu_base, int tbu_testbus_sel) void __iomem *tcu_base, int tbu_testbus_sel, u32 testbus_version) { if (tbu_testbus_sel & TBU_CLK_GATE_CONTROLLER_TESTBUS_SEL) { dev_info(dev, "Dumping TBU clk gate controller:\n"); arm_smmu_debug_program_tbu_testbus(tbu_base, arm_smmu_debug_program_tbu_testbus(tbu_base, tcu_base, testbus_version, TBU_CLK_GATE_CONTROLLER_TESTBUS); dev_info(dev, "testbus_sel: 0x%lx val: 0x%llx\n", arm_smmu_debug_tbu_testbus_select(tbu_base, READ, 0), arm_smmu_debug_tbu_testbus_output(tbu_base)); arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, READ, 0), arm_smmu_debug_tbu_testbus_output(tbu_base, testbus_version)); } if (tbu_testbus_sel & TBU_QNS4_A2Q_TESTBUS_SEL) { dev_info(dev, "Dumping TBU qns4 a2q test bus:\n"); arm_smmu_debug_program_tbu_testbus(tbu_base, TBU_QNS4_A2Q_TESTBUS); arm_smmu_debug_dump_tbu_qns4_testbus(dev, tbu_base); arm_smmu_debug_program_tbu_testbus(tbu_base, tcu_base, testbus_version, TBU_QNS4_A2Q_TESTBUS); arm_smmu_debug_dump_tbu_qns4_testbus(dev, tbu_base, tcu_base, testbus_version); } if (tbu_testbus_sel & TBU_QNS4_Q2A_TESTBUS_SEL) { dev_info(dev, "Dumping qns4 q2a test bus:\n"); arm_smmu_debug_program_tbu_testbus(tbu_base, TBU_QNS4_Q2A_TESTBUS); arm_smmu_debug_dump_tbu_qns4_testbus(dev, tbu_base); arm_smmu_debug_program_tbu_testbus(tbu_base, tcu_base, testbus_version, TBU_QNS4_Q2A_TESTBUS); arm_smmu_debug_dump_tbu_qns4_testbus(dev, tbu_base, tcu_base, testbus_version); } if (tbu_testbus_sel & TBU_MULTIMASTER_QCHANNEL_TESTBUS_SEL) { dev_info(dev, "Dumping multi master qchannel:\n"); arm_smmu_debug_program_tbu_testbus(tbu_base, arm_smmu_debug_program_tbu_testbus(tbu_base, tcu_base, testbus_version, TBU_MULTIMASTER_QCHANNEL_TESTBUS); dev_info(dev, "testbus_sel: 0x%lx val: 0x%llx\n", arm_smmu_debug_tbu_testbus_select(tbu_base, READ, 0), arm_smmu_debug_tbu_testbus_output(tbu_base)); tcu_base, testbus_version, READ, 0), arm_smmu_debug_tbu_testbus_output(tbu_base, testbus_version)); } } Loading drivers/iommu/arm-smmu-debug.h +13 −7 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define ARM_SMMU_TESTBUS_SEL_HLOS1_NS 0x8 #define DEBUG_TESTBUS_SEL_TBU 0x50 #define DEBUG_TESTBUS_TBU 0x58 #define CLIENT_DEBUG_SR_HALT_ACK 0x24 #define TCU_PTW_TESTBUS (0x1 << 8) #define TCU_CACHE_TESTBUS ~TCU_PTW_TESTBUS Loading Loading @@ -58,23 +59,28 @@ enum testbus_ops { #ifdef CONFIG_ARM_SMMU u32 arm_smmu_debug_tbu_testbus_select(void __iomem *tbu_base, bool write, u32 val); u32 arm_smmu_debug_tbu_testbus_output(void __iomem *tbu_base); void __iomem *tcu_base, u32 testbus_version, bool write, u32 reg); u32 arm_smmu_debug_tbu_testbus_output(void __iomem *tbu_base, u32 testbus_version); u32 arm_smmu_debug_tcu_testbus_select(void __iomem *base, void __iomem *tcu_base, enum tcu_testbus testbus, bool write, u32 val); u32 arm_smmu_debug_tcu_testbus_output(void __iomem *base); void arm_smmu_debug_dump_tbu_testbus(struct device *dev, void __iomem *tbu_base, int tbu_testbus_sel); void __iomem *tcu_base, int tbu_testbus_sel, u32 testbus_version); void arm_smmu_debug_dump_tcu_testbus(struct device *dev, void __iomem *base, void __iomem *tcu_base, int tcu_testbus_sel); #else static inline u32 arm_smmu_debug_tbu_testbus_select(void __iomem *tbu_base, bool write, u32 val) void __iomem *tcu_base, u32 testbus_version, bool write, u32 val) { } static inline u32 arm_smmu_debug_tbu_testbus_output(void __iomem *tbu_base) static inline u32 arm_smmu_debug_tbu_testbus_output(void __iomem *tbu_base, u32 testbus_version) { } u32 arm_smmu_debug_tcu_testbus_select(void __iomem *base, Loading @@ -86,7 +92,8 @@ static inline u32 arm_smmu_debug_tcu_testbus_output(void __iomem *base) { } static inline void arm_smmu_debug_dump_tbu_testbus(struct device *dev, void __iomem *tbu_base, int tbu_testbus_sel) void __iomem *tbu_base, void __iomem *tcu_base, int tbu_testbus_sel, u32 testbus_version) { } static inline void arm_smmu_debug_dump_tcu_testbus(struct device *dev, Loading @@ -95,4 +102,3 @@ static inline void arm_smmu_debug_dump_tcu_testbus(struct device *dev, { } #endif drivers/iommu/arm-smmu.c +54 −10 Original line number Diff line number Diff line Loading @@ -5080,6 +5080,7 @@ struct qsmmuv500_archdata { u32 version; struct actlr_setting *actlrs; u32 actlr_tbl_size; u32 testbus_version; }; #define get_qsmmuv500_archdata(smmu) \ ((struct qsmmuv500_archdata *)(smmu->archdata)) Loading Loading @@ -5570,6 +5571,22 @@ static int qsmmuv500_read_actlr_tbl(struct arm_smmu_device *smmu) return 0; } static int qsmmuv500_get_testbus_version(struct arm_smmu_device *smmu) { struct device *dev = smmu->dev; struct qsmmuv500_archdata *data = get_qsmmuv500_archdata(smmu); u32 testbus_version; const __be32 *cell; cell = of_get_property(dev->of_node, "qcom,testbus-version", NULL); if (!cell) return 0; testbus_version = of_read_number(cell, 1); data->testbus_version = testbus_version; return 0; } static ssize_t arm_smmu_debug_testbus_read(struct file *file, char __user *ubuf, size_t count, loff_t *offset, enum testbus_sel tbu, enum testbus_ops ops) Loading @@ -5587,16 +5604,28 @@ static ssize_t arm_smmu_debug_testbus_read(struct file *file, if (tbu == SEL_TBU) { struct qsmmuv500_tbu_device *tbu = file->private_data; struct arm_smmu_device *smmu = tbu->smmu; void __iomem *tbu_base = tbu->base; struct qsmmuv500_archdata *data = smmu->archdata; void __iomem *tcu_base = data->tcu_base; u32 testbus_version = data->testbus_version; struct arm_smmu_power_resources *pwr; long val; arm_smmu_power_on(tbu->pwr); if (testbus_version == 1) pwr = smmu->pwr; else pwr = tbu->pwr; arm_smmu_power_on(pwr); if (ops == TESTBUS_SELECT) val = arm_smmu_debug_tbu_testbus_select(tbu_base, READ, 0); tcu_base, testbus_version, READ, 0); else val = arm_smmu_debug_tbu_testbus_output(tbu_base); arm_smmu_power_off(tbu->pwr); val = arm_smmu_debug_tbu_testbus_output(tbu_base, testbus_version); arm_smmu_power_off(pwr); snprintf(buf, buf_len, "0x%0x\n", val); } else { Loading Loading @@ -5767,6 +5796,11 @@ static ssize_t arm_smmu_debug_tbu_testbus_sel_write(struct file *file, { struct qsmmuv500_tbu_device *tbu = file->private_data; void __iomem *tbu_base = tbu->base; struct arm_smmu_device *smmu = tbu->smmu; struct arm_smmu_power_resources *pwr; struct qsmmuv500_archdata *data = smmu->archdata; void __iomem *tcu_base = data->tcu_base; u32 testbus_version = data->testbus_version; u64 val; if (kstrtoull_from_user(ubuf, count, 0, &val)) { Loading @@ -5774,9 +5808,15 @@ static ssize_t arm_smmu_debug_tbu_testbus_sel_write(struct file *file, return -EINVAL; } arm_smmu_power_on(tbu->pwr); arm_smmu_debug_tbu_testbus_select(tbu_base, WRITE, val); arm_smmu_power_off(tbu->pwr); if (testbus_version == 1) pwr = smmu->pwr; else pwr = tbu->pwr; arm_smmu_power_on(pwr); arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, WRITE, val); arm_smmu_power_off(pwr); return count; } Loading Loading @@ -5881,6 +5921,10 @@ static int qsmmuv500_arch_init(struct arm_smmu_device *smmu) data->version = readl_relaxed(data->tcu_base + TCU_HW_VERSION_HLOS1); smmu->archdata = data; ret = qsmmuv500_get_testbus_version(smmu); if (ret) return ret; qsmmuv500_tcu_testbus_init(smmu); if (arm_smmu_is_static_cb(smmu)) Loading Loading
drivers/iommu/arm-smmu-debug.c +64 −29 Original line number Diff line number Diff line Loading @@ -19,21 +19,37 @@ #include "arm-smmu-debug.h" u32 arm_smmu_debug_tbu_testbus_select(void __iomem *tbu_base, void __iomem *tcu_base, u32 testbus_version, bool write, u32 val) { void __iomem *base; int offset; if (testbus_version == 1) { base = tcu_base; offset = ARM_SMMU_TESTBUS_SEL_HLOS1_NS; } else { base = tbu_base; offset = DEBUG_TESTBUS_SEL_TBU; } if (write) { writel_relaxed(val, tbu_base + DEBUG_TESTBUS_SEL_TBU); writel_relaxed(val, base + offset); /* Make sure tbu select register is written to */ wmb(); } else { return readl_relaxed(tbu_base + DEBUG_TESTBUS_SEL_TBU); return readl_relaxed(base + offset); } return 0; } u32 arm_smmu_debug_tbu_testbus_output(void __iomem *tbu_base) u32 arm_smmu_debug_tbu_testbus_output(void __iomem *tbu_base, u32 testbus_version) { return readl_relaxed(tbu_base + DEBUG_TESTBUS_TBU); int offset = (testbus_version == 1) ? CLIENT_DEBUG_SR_HALT_ACK : DEBUG_TESTBUS_TBU; return readl_relaxed(tbu_base + offset); } u32 arm_smmu_debug_tcu_testbus_select(void __iomem *base, Loading Loading @@ -66,67 +82,86 @@ u32 arm_smmu_debug_tcu_testbus_output(void __iomem *base) } static void arm_smmu_debug_dump_tbu_qns4_testbus(struct device *dev, void __iomem *tbu_base) void __iomem *tbu_base, void __iomem *tcu_base, u32 testbus_version) { int i; u32 reg; for (i = 0 ; i < TBU_QNS4_BRIDGE_SIZE; ++i) { reg = arm_smmu_debug_tbu_testbus_select(tbu_base, READ, 0); reg = arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, READ, 0); reg = (reg & ~GENMASK(4, 0)) | i << 0; arm_smmu_debug_tbu_testbus_select(tbu_base, WRITE, reg); arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, WRITE, reg); dev_info(dev, "testbus_sel: 0x%lx Index: %d val: 0x%llx\n", arm_smmu_debug_tbu_testbus_select(tbu_base, READ, 0), i, arm_smmu_debug_tbu_testbus_output(tbu_base)); arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, READ, 0), i, arm_smmu_debug_tbu_testbus_output(tbu_base, testbus_version)); } } static void arm_smmu_debug_program_tbu_testbus(void __iomem *tbu_base, void __iomem *tcu_base, u32 testbus_version, int tbu_testbus) { u32 reg; reg = arm_smmu_debug_tbu_testbus_select(tbu_base, READ, 0); reg = (reg & ~GENMASK(7, 0)) | tbu_testbus; arm_smmu_debug_tbu_testbus_select(tbu_base, WRITE, reg); reg = arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, READ, 0); if (testbus_version == 1) reg = (reg & ~GENMASK(9, 0)); else reg = (reg & ~GENMASK(7, 0)); reg |= tbu_testbus; arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, WRITE, reg); } void arm_smmu_debug_dump_tbu_testbus(struct device *dev, void __iomem *tbu_base, int tbu_testbus_sel) void __iomem *tcu_base, int tbu_testbus_sel, u32 testbus_version) { if (tbu_testbus_sel & TBU_CLK_GATE_CONTROLLER_TESTBUS_SEL) { dev_info(dev, "Dumping TBU clk gate controller:\n"); arm_smmu_debug_program_tbu_testbus(tbu_base, arm_smmu_debug_program_tbu_testbus(tbu_base, tcu_base, testbus_version, TBU_CLK_GATE_CONTROLLER_TESTBUS); dev_info(dev, "testbus_sel: 0x%lx val: 0x%llx\n", arm_smmu_debug_tbu_testbus_select(tbu_base, READ, 0), arm_smmu_debug_tbu_testbus_output(tbu_base)); arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, READ, 0), arm_smmu_debug_tbu_testbus_output(tbu_base, testbus_version)); } if (tbu_testbus_sel & TBU_QNS4_A2Q_TESTBUS_SEL) { dev_info(dev, "Dumping TBU qns4 a2q test bus:\n"); arm_smmu_debug_program_tbu_testbus(tbu_base, TBU_QNS4_A2Q_TESTBUS); arm_smmu_debug_dump_tbu_qns4_testbus(dev, tbu_base); arm_smmu_debug_program_tbu_testbus(tbu_base, tcu_base, testbus_version, TBU_QNS4_A2Q_TESTBUS); arm_smmu_debug_dump_tbu_qns4_testbus(dev, tbu_base, tcu_base, testbus_version); } if (tbu_testbus_sel & TBU_QNS4_Q2A_TESTBUS_SEL) { dev_info(dev, "Dumping qns4 q2a test bus:\n"); arm_smmu_debug_program_tbu_testbus(tbu_base, TBU_QNS4_Q2A_TESTBUS); arm_smmu_debug_dump_tbu_qns4_testbus(dev, tbu_base); arm_smmu_debug_program_tbu_testbus(tbu_base, tcu_base, testbus_version, TBU_QNS4_Q2A_TESTBUS); arm_smmu_debug_dump_tbu_qns4_testbus(dev, tbu_base, tcu_base, testbus_version); } if (tbu_testbus_sel & TBU_MULTIMASTER_QCHANNEL_TESTBUS_SEL) { dev_info(dev, "Dumping multi master qchannel:\n"); arm_smmu_debug_program_tbu_testbus(tbu_base, arm_smmu_debug_program_tbu_testbus(tbu_base, tcu_base, testbus_version, TBU_MULTIMASTER_QCHANNEL_TESTBUS); dev_info(dev, "testbus_sel: 0x%lx val: 0x%llx\n", arm_smmu_debug_tbu_testbus_select(tbu_base, READ, 0), arm_smmu_debug_tbu_testbus_output(tbu_base)); tcu_base, testbus_version, READ, 0), arm_smmu_debug_tbu_testbus_output(tbu_base, testbus_version)); } } Loading
drivers/iommu/arm-smmu-debug.h +13 −7 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define ARM_SMMU_TESTBUS_SEL_HLOS1_NS 0x8 #define DEBUG_TESTBUS_SEL_TBU 0x50 #define DEBUG_TESTBUS_TBU 0x58 #define CLIENT_DEBUG_SR_HALT_ACK 0x24 #define TCU_PTW_TESTBUS (0x1 << 8) #define TCU_CACHE_TESTBUS ~TCU_PTW_TESTBUS Loading Loading @@ -58,23 +59,28 @@ enum testbus_ops { #ifdef CONFIG_ARM_SMMU u32 arm_smmu_debug_tbu_testbus_select(void __iomem *tbu_base, bool write, u32 val); u32 arm_smmu_debug_tbu_testbus_output(void __iomem *tbu_base); void __iomem *tcu_base, u32 testbus_version, bool write, u32 reg); u32 arm_smmu_debug_tbu_testbus_output(void __iomem *tbu_base, u32 testbus_version); u32 arm_smmu_debug_tcu_testbus_select(void __iomem *base, void __iomem *tcu_base, enum tcu_testbus testbus, bool write, u32 val); u32 arm_smmu_debug_tcu_testbus_output(void __iomem *base); void arm_smmu_debug_dump_tbu_testbus(struct device *dev, void __iomem *tbu_base, int tbu_testbus_sel); void __iomem *tcu_base, int tbu_testbus_sel, u32 testbus_version); void arm_smmu_debug_dump_tcu_testbus(struct device *dev, void __iomem *base, void __iomem *tcu_base, int tcu_testbus_sel); #else static inline u32 arm_smmu_debug_tbu_testbus_select(void __iomem *tbu_base, bool write, u32 val) void __iomem *tcu_base, u32 testbus_version, bool write, u32 val) { } static inline u32 arm_smmu_debug_tbu_testbus_output(void __iomem *tbu_base) static inline u32 arm_smmu_debug_tbu_testbus_output(void __iomem *tbu_base, u32 testbus_version) { } u32 arm_smmu_debug_tcu_testbus_select(void __iomem *base, Loading @@ -86,7 +92,8 @@ static inline u32 arm_smmu_debug_tcu_testbus_output(void __iomem *base) { } static inline void arm_smmu_debug_dump_tbu_testbus(struct device *dev, void __iomem *tbu_base, int tbu_testbus_sel) void __iomem *tbu_base, void __iomem *tcu_base, int tbu_testbus_sel, u32 testbus_version) { } static inline void arm_smmu_debug_dump_tcu_testbus(struct device *dev, Loading @@ -95,4 +102,3 @@ static inline void arm_smmu_debug_dump_tcu_testbus(struct device *dev, { } #endif
drivers/iommu/arm-smmu.c +54 −10 Original line number Diff line number Diff line Loading @@ -5080,6 +5080,7 @@ struct qsmmuv500_archdata { u32 version; struct actlr_setting *actlrs; u32 actlr_tbl_size; u32 testbus_version; }; #define get_qsmmuv500_archdata(smmu) \ ((struct qsmmuv500_archdata *)(smmu->archdata)) Loading Loading @@ -5570,6 +5571,22 @@ static int qsmmuv500_read_actlr_tbl(struct arm_smmu_device *smmu) return 0; } static int qsmmuv500_get_testbus_version(struct arm_smmu_device *smmu) { struct device *dev = smmu->dev; struct qsmmuv500_archdata *data = get_qsmmuv500_archdata(smmu); u32 testbus_version; const __be32 *cell; cell = of_get_property(dev->of_node, "qcom,testbus-version", NULL); if (!cell) return 0; testbus_version = of_read_number(cell, 1); data->testbus_version = testbus_version; return 0; } static ssize_t arm_smmu_debug_testbus_read(struct file *file, char __user *ubuf, size_t count, loff_t *offset, enum testbus_sel tbu, enum testbus_ops ops) Loading @@ -5587,16 +5604,28 @@ static ssize_t arm_smmu_debug_testbus_read(struct file *file, if (tbu == SEL_TBU) { struct qsmmuv500_tbu_device *tbu = file->private_data; struct arm_smmu_device *smmu = tbu->smmu; void __iomem *tbu_base = tbu->base; struct qsmmuv500_archdata *data = smmu->archdata; void __iomem *tcu_base = data->tcu_base; u32 testbus_version = data->testbus_version; struct arm_smmu_power_resources *pwr; long val; arm_smmu_power_on(tbu->pwr); if (testbus_version == 1) pwr = smmu->pwr; else pwr = tbu->pwr; arm_smmu_power_on(pwr); if (ops == TESTBUS_SELECT) val = arm_smmu_debug_tbu_testbus_select(tbu_base, READ, 0); tcu_base, testbus_version, READ, 0); else val = arm_smmu_debug_tbu_testbus_output(tbu_base); arm_smmu_power_off(tbu->pwr); val = arm_smmu_debug_tbu_testbus_output(tbu_base, testbus_version); arm_smmu_power_off(pwr); snprintf(buf, buf_len, "0x%0x\n", val); } else { Loading Loading @@ -5767,6 +5796,11 @@ static ssize_t arm_smmu_debug_tbu_testbus_sel_write(struct file *file, { struct qsmmuv500_tbu_device *tbu = file->private_data; void __iomem *tbu_base = tbu->base; struct arm_smmu_device *smmu = tbu->smmu; struct arm_smmu_power_resources *pwr; struct qsmmuv500_archdata *data = smmu->archdata; void __iomem *tcu_base = data->tcu_base; u32 testbus_version = data->testbus_version; u64 val; if (kstrtoull_from_user(ubuf, count, 0, &val)) { Loading @@ -5774,9 +5808,15 @@ static ssize_t arm_smmu_debug_tbu_testbus_sel_write(struct file *file, return -EINVAL; } arm_smmu_power_on(tbu->pwr); arm_smmu_debug_tbu_testbus_select(tbu_base, WRITE, val); arm_smmu_power_off(tbu->pwr); if (testbus_version == 1) pwr = smmu->pwr; else pwr = tbu->pwr; arm_smmu_power_on(pwr); arm_smmu_debug_tbu_testbus_select(tbu_base, tcu_base, testbus_version, WRITE, val); arm_smmu_power_off(pwr); return count; } Loading Loading @@ -5881,6 +5921,10 @@ static int qsmmuv500_arch_init(struct arm_smmu_device *smmu) data->version = readl_relaxed(data->tcu_base + TCU_HW_VERSION_HLOS1); smmu->archdata = data; ret = qsmmuv500_get_testbus_version(smmu); if (ret) return ret; qsmmuv500_tcu_testbus_init(smmu); if (arm_smmu_is_static_cb(smmu)) Loading